// the sequential reads. (For this reason, each display has a private
// FrameReader. Thus, we can easily keep multiple open file descriptors around
// for a single .frames file.)
+//
+// Thread-compatible, but not thread-safe.
class FrameReader {
public:
FrameReader();
{
fprintf(stderr, "output_pts=%ld original input_pts=%ld\n", output_pts, frame.pts);
- // Preload the file from disk, so that the encoder thread does not get stalled.
- // TODO: Consider sending it through the queue instead.
- (void)frame_reader.read_frame(frame);
-
QueuedFrame qf;
qf.local_pts = local_pts;
qf.type = QueuedFrame::ORIGINAL;
qf.output_pts = output_pts;
- qf.frame1 = frame;
qf.display_func = move(display_func);
qf.queue_spot_holder = move(queue_spot_holder);
qf.subtitle = subtitle;
+ qf.encoded_jpeg.reset(new string(frame_reader.read_frame(frame)));
lock_guard<mutex> lock(queue_lock);
frame_queue.push_back(move(qf));
if (qf.type == QueuedFrame::ORIGINAL) {
// Send the JPEG frame on, unchanged.
- string jpeg = frame_reader.read_frame(qf.frame1);
+ string jpeg = move(*qf.encoded_jpeg);
AVPacket pkt;
av_init_packet(&pkt);
pkt.stream_index = 0;
int64_t output_pts;
enum Type { ORIGINAL, FADED, INTERPOLATED, FADED_INTERPOLATED, REFRESH } type;
- FrameOnDisk frame1; // The only frame for original frames.
+
+ // For original frames only. Made move-only so we know explicitly
+ // we don't copy these ~200 kB files around inadvertedly.
+ //
+ // TODO: Consider using vector<uint8_t> instead, so we save one copy.
+ std::unique_ptr<std::string> encoded_jpeg;
+
+ // For everything except original frames.
+ FrameOnDisk frame1;
// For fades only (including fades against interpolated frames).
FrameOnDisk secondary_frame;