From 46cd0fe7b5b514f0d9456b25f670679cc584a218 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 21 Jun 2013 18:48:46 +0100 Subject: [PATCH] Basics of FFmpeg examiner works. --- src/lib/ffmpeg.cc | 59 +++++++++++++++++++++--------------- src/lib/ffmpeg.h | 15 ++++++--- src/lib/ffmpeg_content.cc | 14 ++++++++- src/lib/ffmpeg_content.h | 2 ++ src/lib/ffmpeg_decoder.cc | 24 ++++++++------- src/lib/ffmpeg_examiner.cc | 59 +++++++++++++++++++++++++++++++++++- src/lib/ffmpeg_examiner.h | 7 +++++ test/ffmpeg_examiner_test.cc | 31 +++++++++++++++++++ test/test.cc | 2 +- 9 files changed, 169 insertions(+), 44 deletions(-) create mode 100644 test/ffmpeg_examiner_test.cc diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc index 0d897abfa..a39de391a 100644 --- a/src/lib/ffmpeg.cc +++ b/src/lib/ffmpeg.cc @@ -40,10 +40,6 @@ FFmpeg::FFmpeg (boost::shared_ptr c) , _format_context (0) , _frame (0) , _video_stream (-1) - , _video_codec_context (0) - , _video_codec (0) - , _audio_codec_context (0) - , _audio_codec (0) { setup_general (); setup_video (); @@ -53,13 +49,12 @@ FFmpeg::FFmpeg (boost::shared_ptr c) FFmpeg::~FFmpeg () { boost::mutex::scoped_lock lm (_mutex); - - if (_audio_codec_context) { - avcodec_close (_audio_codec_context); - } - if (_video_codec_context) { - avcodec_close (_video_codec_context); + for (uint32_t i = 0; i < _format_context->nb_streams; ++i) { + AVCodecContext* context = _format_context->streams[i]->codec; + if (context->codec_type == AVMEDIA_TYPE_VIDEO || context->codec_type == AVMEDIA_TYPE_AUDIO) { + avcodec_close (context); + } } av_free (_frame); @@ -104,14 +99,14 @@ FFmpeg::setup_video () { boost::mutex::scoped_lock lm (_mutex); - _video_codec_context = _format_context->streams[_video_stream]->codec; - _video_codec = avcodec_find_decoder (_video_codec_context->codec_id); + AVCodecContext* context = _format_context->streams[_video_stream]->codec; + AVCodec* codec = avcodec_find_decoder (context->codec_id); - if (_video_codec == 0) { + if (codec == 0) { throw DecodeError (_("could not find video decoder")); } - if (avcodec_open2 (_video_codec_context, _video_codec, 0) < 0) { + if (avcodec_open2 (context, codec, 0) < 0) { throw DecodeError (N_("could not open video decoder")); } } @@ -120,19 +115,33 @@ void FFmpeg::setup_audio () { boost::mutex::scoped_lock lm (_mutex); - - if (!_ffmpeg_content->audio_stream ()) { - return; + + for (uint32_t i = 0; i < _format_context->nb_streams; ++i) { + AVCodecContext* context = _format_context->streams[i]->codec; + if (context->codec_type != AVMEDIA_TYPE_AUDIO) { + continue; + } + + AVCodec* codec = avcodec_find_decoder (context->codec_id); + if (codec == 0) { + throw DecodeError (_("could not find audio decoder")); + } + + if (avcodec_open2 (context, codec, 0) < 0) { + throw DecodeError (N_("could not open audio decoder")); + } } +} - _audio_codec_context = _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec; - _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id); - if (_audio_codec == 0) { - throw DecodeError (_("could not find audio decoder")); - } +AVCodecContext * +FFmpeg::video_codec_context () const +{ + return _format_context->streams[_video_stream]->codec; +} - if (avcodec_open2 (_audio_codec_context, _audio_codec, 0) < 0) { - throw DecodeError (N_("could not open audio decoder")); - } +AVCodecContext * +FFmpeg::audio_codec_context () const +{ + return _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec; } diff --git a/src/lib/ffmpeg.h b/src/lib/ffmpeg.h index dcafe17f7..4d1a45da3 100644 --- a/src/lib/ffmpeg.h +++ b/src/lib/ffmpeg.h @@ -17,6 +17,9 @@ */ +#ifndef DCPOMATIC_FFMPEG_H +#define DCPOMATIC_FFMPEG_H + #include #include #include @@ -46,16 +49,16 @@ public: } protected: + AVCodecContext* video_codec_context () const; + AVCodecContext* audio_codec_context () const; + boost::shared_ptr _ffmpeg_content; + AVFormatContext* _format_context; AVPacket _packet; AVFrame* _frame; - int _video_stream; - AVCodecContext* _video_codec_context; - AVCodec* _video_codec; - AVCodecContext* _audio_codec_context; ///< may be 0 if there is no audio - AVCodec* _audio_codec; ///< may be 0 if there is no audio + int _video_stream; /* It would appear (though not completely verified) that one must have a mutex around calls to avcodec_open* and avcodec_close... and here @@ -68,3 +71,5 @@ private: void setup_video (); void setup_audio (); }; + +#endif diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 43e88c428..68132c5ab 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -76,6 +76,8 @@ FFmpegContent::FFmpegContent (shared_ptr f, shared_ptr >::iterator i = c.begin(); i != c.end(); ++i) { _filters.push_back (Filter::from_id ((*i)->content ())); } + + _first_video = node->optional_number_child