+ int frame_finished;
+ if (avcodec_decode_video2 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
+ _first_video = frame_time (_format_context->streams[_video_stream]);
+ }
+}
+
+void
+FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream)
+{
+ if (stream->first_audio) {
+ return;
+ }
+
+ int frame_finished;
+ if (avcodec_decode_audio4 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
+ stream->first_audio = frame_time (stream->stream (_format_context));
+ }
+}
+
+void
+FFmpegExaminer::subtitle_packet (AVCodecContext* context, shared_ptr<FFmpegSubtitleStream> stream)
+{
+ int frame_finished;
+ AVSubtitle sub;
+ if (avcodec_decode_subtitle2 (context, &sub, &frame_finished, &_packet) >= 0 && frame_finished) {
+ ContentTimePeriod const period = subtitle_period (sub);
+ if (sub.num_rects == 0 && !stream->periods.empty () && stream->periods.back().to > period.from) {
+ /* Finish the last subtitle */
+ stream->periods.back().to = period.from;
+ } else if (sub.num_rects == 1) {
+ stream->periods.push_back (period);
+ }
+ }
+}
+
+optional<ContentTime>
+FFmpegExaminer::frame_time (AVStream* s) const
+{
+ optional<ContentTime> t;
+
+ int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
+ if (bet != AV_NOPTS_VALUE) {
+ t = ContentTime::from_seconds (bet * av_q2d (s->time_base));