diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-10-30 01:25:50 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-10-30 01:25:50 +0000 |
| commit | 093ad6790e1a5d6656dbf422668739f14a52471f (patch) | |
| tree | e96c0e7d56b3fab9ab9e52205c50cd3b642d2dcb /src/lib/ffmpeg_decoder.cc | |
| parent | e8a14fc68d393a001bb966a52ad8536dd3058a76 (diff) | |
Insert / remove frames from the output as required to keep things right with the source's PTS values; do avcodec_get_frame_defaults() for all streams.
Diffstat (limited to 'src/lib/ffmpeg_decoder.cc')
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index bfb0ed568..98fd4f576 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -49,6 +49,7 @@ extern "C" { #include "ffmpeg_decoder.h" #include "subtitle.h" +using std::cout; using std::string; using std::vector; using std::stringstream; @@ -253,16 +254,41 @@ FFmpegDecoder::do_pass () } double const pts_seconds = av_q2d (_format_context->streams[_packet.stream_index]->time_base) * _packet.pts; + + avcodec_get_frame_defaults (_frame); if (_packet.stream_index == _video_stream) { if (!_first_video) { _first_video = pts_seconds; } - + int frame_finished; if (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - process_video (_frame); + + /* Where we are in the output, in seconds */ + double const out_pts_seconds = last_video_frame() / frames_per_second(); + + /* Difference between where we are and where we should be */ + double const delta = pts_seconds - out_pts_seconds; + double const one_frame = 1 / frames_per_second(); + + /* Insert frames if required to get out_pts_seconds up to pts_seconds */ + if (delta > one_frame) { + int const extra = rint (delta / one_frame); + for (int i = 0; i < extra; ++i) { + _log->log (String::compose ("Extra frame inserted at %1s", out_pts_seconds)); + process_video (_frame); + } + } + + if (delta > -one_frame) { + /* Process this frame */ + process_video (_frame); + } else { + /* Otherwise we are omitting a frame to keep things right */ + _log->log (String::compose ("Frame removed at %1s", out_pts_seconds)); + } } } else if (_audio_stream >= 0 && _packet.stream_index == _audio_stream && _opt->decode_audio && _first_video && _first_video.get() <= pts_seconds) { @@ -300,8 +326,6 @@ FFmpegDecoder::do_pass () process_audio (silence, b); } - avcodec_get_frame_defaults (_frame); - int frame_finished; if (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { int const data_size = av_samples_get_buffer_size ( |
