[FFmpeg-cvslog] lavfi: implement ff_inlink_make_frame_writable().
Nicolas George
git at videolan.org
Thu Jan 12 15:15:31 EET 2017
ffmpeg | branch: master | Nicolas George <george at nsup.org> | Tue Dec 20 14:56:03 2016 +0100| [28c62df672865890cbb13e5f0e94bde29c8fbacd] | committer: Nicolas George
lavfi: implement ff_inlink_make_frame_writable().
Unlike av_frame_is_writable(), it uses the link's alloc callback,
making direct rendering possible.
The code comes from ff_filter_frame_framed(), moved with mostly
trivial changes.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=28c62df672865890cbb13e5f0e94bde29c8fbacd
---
libavfilter/avfilter.c | 94 ++++++++++++++++++++++++++++----------------------
libavfilter/filters.h | 7 ++++
2 files changed, 60 insertions(+), 41 deletions(-)
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 823e1ba..c02e43c 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -1107,49 +1107,12 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
if (!(filter_frame = dst->filter_frame))
filter_frame = default_filter_frame;
- /* copy the frame if needed */
- if (dst->needs_writable && !av_frame_is_writable(frame)) {
- av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
-
- switch (link->type) {
- case AVMEDIA_TYPE_VIDEO:
- out = ff_get_video_buffer(link, link->w, link->h);
- break;
- case AVMEDIA_TYPE_AUDIO:
- out = ff_get_audio_buffer(link, frame->nb_samples);
- break;
- default:
- ret = AVERROR(EINVAL);
- goto fail;
- }
- if (!out) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- ret = av_frame_copy_props(out, frame);
+ if (dst->needs_writable) {
+ ret = ff_inlink_make_frame_writable(link, &frame);
if (ret < 0)
goto fail;
-
- switch (link->type) {
- case AVMEDIA_TYPE_VIDEO:
- av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
- frame->format, frame->width, frame->height);
- break;
- case AVMEDIA_TYPE_AUDIO:
- av_samples_copy(out->extended_data, frame->extended_data,
- 0, 0, frame->nb_samples,
- av_frame_get_channels(frame),
- frame->format);
- break;
- default:
- ret = AVERROR(EINVAL);
- goto fail;
- }
-
- av_frame_free(&frame);
- } else
- out = frame;
+ }
+ out = frame; /* TODO rename */
while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){
av_log(link->dst, AV_LOG_DEBUG,
@@ -1559,6 +1522,55 @@ int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts
return 1;
}
+int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
+{
+ AVFrame *frame = *rframe;
+ AVFrame *out;
+ int ret;
+
+ if (av_frame_is_writable(frame))
+ return 0;
+ av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ out = ff_get_video_buffer(link, link->w, link->h);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ out = ff_get_audio_buffer(link, frame->nb_samples);
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+ if (!out)
+ return AVERROR(ENOMEM);
+
+ ret = av_frame_copy_props(out, frame);
+ if (ret < 0) {
+ av_frame_free(&out);
+ return ret;
+ }
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
+ frame->format, frame->width, frame->height);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ av_samples_copy(out->extended_data, frame->extended_data,
+ 0, 0, frame->nb_samples,
+ av_frame_get_channels(frame),
+ frame->format);
+ break;
+ default:
+ av_assert0(!"reached");
+ }
+
+ av_frame_free(&frame);
+ *rframe = out;
+ return 0;
+}
+
const AVClass *avfilter_get_class(void)
{
return &avfilter_class;
diff --git a/libavfilter/filters.h b/libavfilter/filters.h
index 72e5676..3036ba2 100644
--- a/libavfilter/filters.h
+++ b/libavfilter/filters.h
@@ -40,6 +40,13 @@
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority);
/**
+ * Make sure a frame is writable.
+ * This is similar to av_frame_make_writable() except it uses the link's
+ * buffer allocation callback, and therefore allows direct rendering.
+ */
+int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe);
+
+/**
* Test and acknowledge the change of status on the link.
*
* Status means EOF or an error condition; a change from the normal (0)
More information about the ffmpeg-cvslog
mailing list