summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-05-02 22:15:32 +0100
committerCarl Hetherington <cth@carlh.net>2013-05-02 22:15:32 +0100
commitfdd63a4c9925f0339089dce3a52f0d6ed0d97880 (patch)
treeab7c4f759ef49088be58a034851a438c57d5ffad /src/lib
parent36fec15b78e6d5017c9f631bd2e828aa9ca91aa1 (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.cc45
-rw-r--r--src/lib/filter_graph.cc19
-rw-r--r--src/lib/image.cc8
-rw-r--r--src/lib/image.h3
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;
};