auto const f = full_length.frames_round (vfr);
auto v = video->position(film()).get_value_or(ContentTime()).frames_round(vfr) + 1;
while (v < f) {
- video->emit (film(), shared_ptr<const ImageProxy> (new RawImageProxy (_black_image)), v);
+ video->emit (film(), make_shared<const RawImageProxy>(_black_image), v);
++v;
}
}
auto context = video_codec_context();
- int r = avcodec_send_packet (context, packet);
- if (r < 0) {
- LOG_WARNING("avcodec_send_packet returned %1 for a video packet", r);
- }
-
- while (true) {
- r = avcodec_receive_frame (context, _video_frame);
- if (r == AVERROR(EAGAIN) || r == AVERROR_EOF || (r < 0 && !packet)) {
- /* More input is required, no more frames are coming, or we are flushing and there was
- * some error which we just want to ignore.
- */
- return false;
- } else if (r < 0) {
- throw DecodeError (N_("avcodec_receive_frame"), N_("FFmpeg::decode_and_process_video_packet"), r);
+ bool pending = false;
+ do {
+ int r = avcodec_send_packet (context, packet);
+ if (r < 0) {
+ LOG_WARNING("avcodec_send_packet returned %1 for a video packet", r);
}
- process_video_frame ();
- }
+ /* EAGAIN means we should call avcodec_receive_frame and then re-send the same packet */
+ pending = r == AVERROR(EAGAIN);
+
+ while (true) {
+ r = avcodec_receive_frame (context, _video_frame);
+ if (r == AVERROR(EAGAIN) || r == AVERROR_EOF || (r < 0 && !packet)) {
+ /* More input is required, no more frames are coming, or we are flushing and there was
+ * some error which we just want to ignore.
+ */
+ return false;
+ } else if (r < 0) {
+ throw DecodeError (N_("avcodec_receive_frame"), N_("FFmpeg::decode_and_process_video_packet"), r);
+ }
+
+ process_video_frame ();
+ }
+ } while (pending);
return true;
}
_have_current_subtitle = true;
}
+ ContentBitmapText bitmap_text(from);
for (unsigned int i = 0; i < sub.num_rects; ++i) {
auto const rect = sub.rects[i];
case SUBTITLE_NONE:
break;
case SUBTITLE_BITMAP:
- process_bitmap_subtitle (rect, from);
+ bitmap_text.subs.push_back(process_bitmap_subtitle(rect));
break;
case SUBTITLE_TEXT:
cout << "XXX: SUBTITLE_TEXT " << rect->text << "\n";
}
}
+ if (!bitmap_text.subs.empty()) {
+ only_text()->emit_bitmap_start(bitmap_text);
+ }
+
if (_current_subtitle_to) {
only_text()->emit_stop (*_current_subtitle_to);
}
}
-void
-FFmpegDecoder::process_bitmap_subtitle (AVSubtitleRect const * rect, ContentTime from)
+BitmapText
+FFmpegDecoder::process_bitmap_subtitle (AVSubtitleRect const * rect)
{
/* Note BGRA is expressed little-endian, so the first byte in the word is B, second
G, third R, fourth A.
static_cast<double>(rect->h) / target_height
);
- only_text()->emit_bitmap_start (from, image, scaled_rect);
+ return { image, scaled_rect };
}