diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-05-02 22:15:32 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-05-02 22:15:32 +0100 |
| commit | fdd63a4c9925f0339089dce3a52f0d6ed0d97880 (patch) | |
| tree | ab7c4f759ef49088be58a034851a438c57d5ffad /src/lib | |
| parent | 36fec15b78e6d5017c9f631bd2e828aa9ca91aa1 (diff) | |
Use newer format to specify filter graphs; don't filter unless necessary; fix tiny memory leak.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 45 | ||||
| -rw-r--r-- | src/lib/filter_graph.cc | 19 | ||||
| -rw-r--r-- | src/lib/image.cc | 8 | ||||
| -rw-r--r-- | src/lib/image.h | 3 |
4 files changed, 44 insertions, 31 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 8e09810cb..cd68e5294 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -500,32 +500,41 @@ FFmpegDecoder::set_subtitle_stream (shared_ptr<SubtitleStream> s) void FFmpegDecoder::filter_and_emit_video () { - boost::mutex::scoped_lock lm (_filter_graphs_mutex); + int64_t const bet = av_frame_get_best_effort_timestamp (_frame); + if (bet == AV_NOPTS_VALUE) { + _film->log()->log ("Dropping frame without PTS"); + return; + } - shared_ptr<FilterGraph> graph; - - list<shared_ptr<FilterGraph> >::iterator i = _filter_graphs.begin(); - while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { - ++i; + if (_film->crop() == Crop() && _film->filters().empty()) { + /* No filter graph needed; just emit */ + emit_video (shared_ptr<Image> (new FrameImage (_frame, false)), false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); + return; } + + shared_ptr<FilterGraph> graph; - if (i == _filter_graphs.end ()) { - graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); - _filter_graphs.push_back (graph); - _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); - } else { - graph = *i; + { + boost::mutex::scoped_lock lm (_filter_graphs_mutex); + + list<shared_ptr<FilterGraph> >::iterator i = _filter_graphs.begin(); + while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { + ++i; + } + + if (i == _filter_graphs.end ()) { + graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); + _filter_graphs.push_back (graph); + _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); + } else { + graph = *i; + } } list<shared_ptr<Image> > images = graph->process (_frame); for (list<shared_ptr<Image> >::iterator i = images.begin(); i != images.end(); ++i) { - int64_t const bet = av_frame_get_best_effort_timestamp (_frame); - if (bet != AV_NOPTS_VALUE) { - emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); - } else { - _film->log()->log ("Dropping frame without PTS"); - } + emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); } } diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index f0c49b37c..2624bc4d7 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -79,17 +79,14 @@ FilterGraph::FilterGraph (shared_ptr<Film> film, FFmpegDecoder* decoder, libdcp: } stringstream a; - a << _size.width << N_(":") - << _size.height << N_(":") - << _pixel_format << N_(":") - << decoder->time_base_numerator() << N_(":") - << decoder->time_base_denominator() << N_(":") - << decoder->sample_aspect_ratio_numerator() << N_(":") - << decoder->sample_aspect_ratio_denominator(); + a << "video_size=" << _size.width << "x" << _size.height << ":" + << "pix_fmt=" << _pixel_format << ":" + << "time_base=" << decoder->time_base_numerator() << "/" << decoder->time_base_denominator() << ":" + << "pixel_aspect=" << decoder->sample_aspect_ratio_numerator() << "/" << decoder->sample_aspect_ratio_denominator(); int r; - if ((r = avfilter_graph_create_filter (&_buffer_src_context, buffer_src, N_("in"), a.str().c_str(), 0, graph)) < 0) { + if ((r = avfilter_graph_create_filter (&_buffer_src_context, buffer_src, "in", a.str().c_str(), 0, graph)) < 0) { throw DecodeError (N_("could not create buffer source")); } @@ -103,6 +100,8 @@ FilterGraph::FilterGraph (shared_ptr<Film> film, FFmpegDecoder* decoder, libdcp: throw DecodeError (N_("could not create buffer sink.")); } + av_free (sink_params); + AVFilterInOut* outputs = avfilter_inout_alloc (); outputs->name = av_strdup(N_("in")); outputs->filter_ctx = _buffer_src_context; @@ -133,7 +132,7 @@ list<shared_ptr<Image> > FilterGraph::process (AVFrame* frame) { list<shared_ptr<Image> > images; - + if (av_buffersrc_write_frame (_buffer_src_context, frame) < 0) { throw DecodeError (N_("could not push buffer into filter chain.")); } @@ -146,7 +145,7 @@ FilterGraph::process (AVFrame* frame) } /* This takes ownership of the AVFrame */ - images.push_back (shared_ptr<Image> (new FrameImage (frame))); + images.push_back (shared_ptr<Image> (new FrameImage (frame, true))); } return images; diff --git a/src/lib/image.cc b/src/lib/image.cc index b97291585..1768be924 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -576,9 +576,10 @@ SimpleImage::aligned () const return _aligned; } -FrameImage::FrameImage (AVFrame* frame) +FrameImage::FrameImage (AVFrame* frame, bool own) : Image (static_cast<AVPixelFormat> (frame->format)) , _frame (frame) + , _own (own) { _line_size = (int *) av_malloc (4 * sizeof (int)); _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0; @@ -590,7 +591,10 @@ FrameImage::FrameImage (AVFrame* frame) FrameImage::~FrameImage () { - av_frame_free (&_frame); + if (_own) { + av_frame_free (&_frame); + } + av_free (_line_size); } diff --git a/src/lib/image.h b/src/lib/image.h index 39d84fcd4..16fbd28c2 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -106,7 +106,7 @@ private: class FrameImage : public Image { public: - FrameImage (AVFrame *); + FrameImage (AVFrame *, bool); ~FrameImage (); uint8_t ** data () const; @@ -121,6 +121,7 @@ private: FrameImage& operator= (FrameImage const &); AVFrame* _frame; + bool _own; int* _line_size; }; |
