[FFmpeg-soc] [soc]: r3760 - in libavfilter: Makefile allfilters.c diffs/02_ffmpeg_filters.diff vsrc_buffer.c vsrc_buffer.h
vitor
subversion at mplayerhq.hu
Wed Oct 8 20:11:14 CEST 2008
Author: vitor
Date: Wed Oct 8 20:11:13 2008
New Revision: 3760
Log:
Create a buffer source filter instead of duplicating it in ffmpeg.c and
ffplay.c
Added:
libavfilter/vsrc_buffer.c
libavfilter/vsrc_buffer.h
Modified:
libavfilter/Makefile
libavfilter/allfilters.c
libavfilter/diffs/02_ffmpeg_filters.diff
Modified: libavfilter/Makefile
==============================================================================
--- libavfilter/Makefile (original)
+++ libavfilter/Makefile Wed Oct 8 20:11:13 2008
@@ -30,6 +30,7 @@ OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_t
OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o
OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o
+OBJS-$(CONFIG_BUFFER_FILTER) += vsrc_buffer.o
HEADERS = avfilter.h
Modified: libavfilter/allfilters.c
==============================================================================
--- libavfilter/allfilters.c (original)
+++ libavfilter/allfilters.c Wed Oct 8 20:11:13 2008
@@ -52,4 +52,5 @@ void avfilter_register_all(void)
REGISTER_FILTER(VFLIP,vflip,vf);
REGISTER_FILTER(MOVIE,movie,vsrc);
+ REGISTER_FILTER(BUFFER,buffer,vsrc);
}
Modified: libavfilter/diffs/02_ffmpeg_filters.diff
==============================================================================
--- libavfilter/diffs/02_ffmpeg_filters.diff (original)
+++ libavfilter/diffs/02_ffmpeg_filters.diff Wed Oct 8 20:11:13 2008
@@ -1,8 +1,8 @@
Index: ffmpeg.c
===================================================================
---- ffmpeg.c (revision 15000)
+--- ffmpeg.c (revision 15585)
+++ ffmpeg.c (working copy)
-@@ -41,6 +41,12 @@
+@@ -41,6 +41,13 @@
#include "libavutil/avstring.h"
#include "libavformat/os_support.h"
@@ -10,12 +10,13 @@ Index: ffmpeg.c
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/graphparser.h"
++# include "libavfilter/vsrc_buffer.h"
+#endif
+
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/types.h>
#include <sys/resource.h>
-@@ -140,6 +146,9 @@
+@@ -144,6 +151,9 @@
static int loop_input = 0;
static int loop_output = AVFMT_NOOUTPUTLOOP;
static int qp_hist = 0;
@@ -25,7 +26,7 @@ Index: ffmpeg.c
static int intra_only = 0;
static int audio_sample_rate = 44100;
-@@ -280,6 +289,13 @@
+@@ -281,6 +291,13 @@
is not defined */
int64_t pts; /* current pts */
int is_start; /* is 1 at the start and after a discontinuity */
@@ -39,107 +40,12 @@ Index: ffmpeg.c
} AVInputStream;
typedef struct AVInputFile {
-@@ -295,6 +311,266 @@
+@@ -296,6 +313,174 @@
static struct termios oldtty;
#endif
+#if ENABLE_AVFILTER
+typedef struct {
-+ AVInputStream *ist;
-+} FilterInPriv;
-+
-+static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
-+{
-+ FilterInPriv *priv = ctx->priv;
-+
-+ if(!opaque) return -1;
-+
-+ priv->ist = opaque;
-+ priv->ist->filter_frame = avcodec_alloc_frame();
-+
-+ return 0;
-+}
-+
-+static void input_uninit(AVFilterContext *ctx)
-+{
-+ FilterInPriv *priv = ctx->priv;
-+ av_free(priv->ist->filter_frame);
-+}
-+
-+static int poll_frame(AVFilterLink *link)
-+{
-+ FilterInPriv *priv = link->src->priv;
-+ return !!(priv->ist->has_filter_frame);
-+}
-+
-+static int input_request_frame(AVFilterLink *link)
-+{
-+ FilterInPriv *priv = link->src->priv;
-+ AVFilterPicRef *picref;
-+
-+ /* This picture will be needed unmodified later for decoding the next
-+ * frame */
-+ picref = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
-+ AV_PERM_REUSE2);
-+
-+ memcpy(picref->data, priv->ist->filter_frame->data,
-+ sizeof(priv->ist->filter_frame->data));
-+
-+ memcpy(picref->linesize, priv->ist->filter_frame->linesize,
-+ sizeof(priv->ist->filter_frame->linesize));
-+
-+ picref->pts = priv->ist->pts;
-+ picref->pixel_aspect = priv->ist->st->codec->sample_aspect_ratio;
-+ avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
-+ avfilter_draw_slice(link, 0, picref->h);
-+ avfilter_end_frame(link);
-+ avfilter_unref_pic(picref);
-+
-+ priv->ist->has_filter_frame = 0;
-+
-+ return 0;
-+}
-+
-+static int input_query_formats(AVFilterContext *ctx)
-+{
-+ FilterInPriv *priv = ctx->priv;
-+ avfilter_set_common_formats(ctx,
-+ avfilter_make_format_list(1, priv->ist->st->codec->pix_fmt));
-+ return 0;
-+}
-+
-+static int input_config_props(AVFilterLink *link)
-+{
-+ FilterInPriv *priv = link->src->priv;
-+ AVCodecContext *c = priv->ist->st->codec;
-+
-+ link->w = c->width;
-+ link->h = c->height;
-+
-+ return 0;
-+}
-+
-+static AVFilter input_filter =
-+{
-+ .name = "ffmpeg_input",
-+
-+ .priv_size = sizeof(FilterInPriv),
-+
-+ .init = input_init,
-+ .uninit = input_uninit,
-+
-+ .query_formats = input_query_formats,
-+
-+ .inputs = (AVFilterPad[]) {{ .name = NULL }},
-+ .outputs = (AVFilterPad[]) {{ .name = "default",
-+ .type = CODEC_TYPE_VIDEO,
-+ .request_frame = input_request_frame,
-+ .poll_frame = poll_frame,
-+ .config_props = input_config_props, },
-+ { .name = NULL }},
-+};
-+
-+typedef struct {
+ int pix_fmt;
+} FilterOutPriv;
+
@@ -212,15 +118,18 @@ Index: ffmpeg.c
+ AVFilterGraph *filt_graph_all = av_mallocz(sizeof(AVFilterGraph));
+ AVCodecContext *codec = ost->st->codec;
+ AVCodecContext *icodec = ist->st->codec;
++ char args[255];
+
+ avfilter_register_all();
+
-+ if(!(ist->input_video_filter = avfilter_open(&input_filter, "src")))
++ if(!(ist->input_video_filter = avfilter_open(avfilter_get_by_name("buffer"), "src")))
+ return -1;
+ if(!(ist->out_video_filter = avfilter_open(&output_filter, "out")))
+ return -1;
+
-+ if(avfilter_init_filter(ist->input_video_filter, NULL, ist))
++ snprintf(args, 255, "%d:%d:%d", ist->st->codec->width,
++ ist->st->codec->height, ist->st->codec->pix_fmt);
++ if(avfilter_init_filter(ist->input_video_filter, args, NULL))
+ return -1;
+ if(avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
+ return -1;
@@ -306,7 +215,7 @@ Index: ffmpeg.c
static void term_exit(void)
{
#ifdef HAVE_TERMIOS_H
-@@ -872,6 +1148,9 @@
+@@ -865,6 +1050,9 @@
if (nb_frames <= 0)
return;
@@ -316,7 +225,7 @@ Index: ffmpeg.c
if (ost->video_crop) {
if (av_picture_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) {
av_log(NULL, AV_LOG_ERROR, "error cropping picture\n");
-@@ -881,6 +1160,7 @@
+@@ -876,6 +1064,7 @@
} else {
formatted_picture = in_picture;
}
@@ -324,7 +233,7 @@ Index: ffmpeg.c
final_picture = formatted_picture;
padding_src = formatted_picture;
-@@ -896,12 +1176,14 @@
+@@ -893,12 +1082,14 @@
}
}
@@ -339,7 +248,7 @@ Index: ffmpeg.c
if (ost->video_pad) {
av_picture_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
-@@ -1172,6 +1454,7 @@
+@@ -1169,6 +1360,7 @@
static short *samples= NULL;
AVSubtitle subtitle, *subtitle_to_free;
int got_subtitle;
@@ -347,28 +256,27 @@ Index: ffmpeg.c
if(ist->next_pts == AV_NOPTS_VALUE)
ist->next_pts= ist->pts;
-@@ -1289,6 +1572,17 @@
+@@ -1286,6 +1478,15 @@
&buffer_to_free);
}
+#if ENABLE_AVFILTER
+ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {
+ // add it to be filtered
-+ memcpy(ist->filter_frame->data, picture.data,
-+ sizeof(picture.data));
-+ memcpy(ist->filter_frame->linesize, picture.linesize,
-+ sizeof(picture.linesize));
-+ ist->has_filter_frame = 1;
++ av_vsrc_buffer_add_frame(ist->input_video_filter, &picture,
++ ist->pts,
++ ist->st->codec->sample_aspect_ratio);
+ }
+#endif
+
// preprocess audio (volume)
if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
if (audio_volume != 256) {
-@@ -1326,9 +1620,16 @@
- }
+@@ -1309,10 +1510,16 @@
+
+ ist->frame++;
}
- #endif
+-
+ loop = ist->st->codec->codec_type != CODEC_TYPE_VIDEO ||
+ avfilter_poll_frame(ist->out_video_filter->inputs[0]);
/* if output time reached then transcode raw format,
@@ -382,7 +290,7 @@ Index: ffmpeg.c
for(i=0;i<nb_ostreams;i++) {
int frame_size;
-@@ -1351,6 +1652,9 @@
+@@ -1335,6 +1542,9 @@
do_audio_out(os, ost, ist, data_buf, data_size);
break;
case CODEC_TYPE_VIDEO:
@@ -392,7 +300,7 @@ Index: ffmpeg.c
do_video_out(os, ost, ist, &picture, &frame_size);
if (vstats_filename && frame_size)
do_video_stats(os, ost, frame_size);
-@@ -1408,7 +1712,15 @@
+@@ -1392,7 +1602,15 @@
av_free_packet(&opkt);
}
}
@@ -408,7 +316,7 @@ Index: ffmpeg.c
av_free(buffer_to_free);
/* XXX: allocate the subtitles in the codec ? */
if (subtitle_to_free) {
-@@ -1826,10 +2138,21 @@
+@@ -1810,10 +2028,21 @@
fprintf(stderr, "Cannot get resampling context\n");
av_exit(1);
}
@@ -430,7 +338,7 @@ Index: ffmpeg.c
break;
case CODEC_TYPE_SUBTITLE:
ost->encoding_needed = 1;
-@@ -3846,6 +4169,9 @@
+@@ -3777,6 +4006,9 @@
#ifdef CONFIG_VHOOK
{ "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
#endif
Added: libavfilter/vsrc_buffer.c
==============================================================================
--- (empty file)
+++ libavfilter/vsrc_buffer.c Wed Oct 8 20:11:13 2008
@@ -0,0 +1,137 @@
+/*
+ * Memory buffer source filter
+ * Copyright (c) 2008 Vitor Sessak
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avfilter.h"
+
+typedef struct {
+ int64_t pts;
+ AVFrame frame;
+ int has_frame;
+ int h, w, pix_fmt;
+ AVRational pixel_aspect;
+} BufferSourceContext;
+
+
+int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
+ int64_t pts, AVRational pixel_aspect)
+{
+ BufferSourceContext *c = buffer_filter->priv;
+
+ if (c->has_frame) {
+ av_log(buffer_filter, AV_LOG_ERROR,
+ "Buffering several frames is not supported. "
+ "Please consume all available frames before adding a new one.\n"
+ );
+ //return -1;
+ }
+
+ memcpy(c->frame.data , frame->data , sizeof(frame->data));
+ memcpy(c->frame.linesize, frame->linesize, sizeof(frame->linesize));
+ c->pts = pts;
+ c->pixel_aspect = pixel_aspect;
+ c->has_frame = 1;
+
+ return 0;
+}
+
+static int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ BufferSourceContext *c = ctx->priv;
+
+ if(args && sscanf(args, "%d:%d:%d", &c->w, &c->h, &c->pix_fmt) == 3)
+ return 0;
+
+ av_log(ctx, AV_LOG_ERROR, "init() expected 3 arguments:'%s'\n", args);
+ return -1;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ BufferSourceContext *c = ctx->priv;
+
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(1, c->pix_fmt));
+ return 0;
+}
+
+static int config_props(AVFilterLink *link)
+{
+ BufferSourceContext *c = link->src->priv;
+
+ link->w = c->w;
+ link->h = c->h;
+
+ return 0;
+}
+
+
+static int request_frame(AVFilterLink *link)
+{
+ BufferSourceContext *c = link->src->priv;
+ AVFilterPicRef *picref;
+
+ if (!c->has_frame) {
+ av_log(link->src, AV_LOG_ERROR,
+ "request_frame() called with no available frame!\n");
+ //return -1;
+ }
+
+ /* This picture will be needed unmodified later for decoding the next
+ * frame */
+ picref = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
+ AV_PERM_REUSE2);
+
+ memcpy(picref->data , c->frame.data , sizeof(c->frame.data ));
+ memcpy(picref->linesize, c->frame.linesize, sizeof(c->frame.linesize));
+
+ picref->pts = c->pts;
+ picref->pixel_aspect = c->pixel_aspect;
+ avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
+ avfilter_draw_slice(link, 0, picref->h);
+ avfilter_end_frame(link);
+ avfilter_unref_pic(picref);
+
+ c->has_frame = 0;
+
+ return 0;
+}
+
+static int poll_frame(AVFilterLink *link)
+{
+ BufferSourceContext *c = link->src->priv;
+ return !!(c->has_frame);
+}
+
+AVFilter avfilter_vsrc_buffer =
+{
+ .name = "buffer",
+ .priv_size = sizeof(BufferSourceContext),
+ .query_formats = query_formats,
+
+ .init = init,
+
+ .inputs = (AVFilterPad[]) {{ .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = CODEC_TYPE_VIDEO,
+ .request_frame = request_frame,
+ .poll_frame = poll_frame,
+ .config_props = config_props, },
+ { .name = NULL}},
+};
Added: libavfilter/vsrc_buffer.h
==============================================================================
--- (empty file)
+++ libavfilter/vsrc_buffer.h Wed Oct 8 20:11:13 2008
@@ -0,0 +1,24 @@
+/*
+ * Memory buffer source filter
+ * Copyright (c) 2008 Vitor Sessak
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
+ int64_t pts, AVRational pixel_aspect);
+
More information about the FFmpeg-soc
mailing list