[FFmpeg-soc] [soc]: r1866 - in libavfilter: avfilter.c avfilter.h avfiltergraph.c diffs/04_ffmpeg_filters.diff vf_fps.c
vitor
subversion at mplayerhq.hu
Wed Feb 6 20:55:37 CET 2008
Author: vitor
Date: Wed Feb 6 20:55:36 2008
New Revision: 1866
Log:
Implement poll_frame() method. Fix ffmpeg.c bug with
vf_fps filter.
Modified:
libavfilter/avfilter.c
libavfilter/avfilter.h
libavfilter/avfiltergraph.c
libavfilter/diffs/04_ffmpeg_filters.diff
libavfilter/vf_fps.c
Modified: libavfilter/avfilter.c
==============================================================================
--- libavfilter/avfilter.c (original)
+++ libavfilter/avfilter.c Wed Feb 6 20:55:36 2008
@@ -185,6 +185,22 @@ int avfilter_request_frame(AVFilterLink
else return -1;
}
+int avfilter_poll_frame(AVFilterLink *link)
+{
+ int i, min=INT_MAX;
+
+ if(link_spad(link).poll_frame)
+ return link_spad(link).poll_frame(link);
+ else
+ for (i=0; i<link->src->input_count; i++) {
+ if(!link->src->inputs[i])
+ return -1;
+ min = FFMIN(min, avfilter_poll_frame(link->src->inputs[i]));
+ }
+
+ return min;
+}
+
/* XXX: should we do the duplicating of the picture ref here, instead of
* forcing the source filter to do it? */
void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
Modified: libavfilter/avfilter.h
==============================================================================
--- libavfilter/avfilter.h (original)
+++ libavfilter/avfilter.h Wed Feb 6 20:55:36 2008
@@ -186,6 +186,8 @@ void avfilter_formats_ref(AVFilterFormat
*/
void avfilter_formats_unref(AVFilterFormats **ref);
+int avfilter_poll_frame(AVFilterLink *link);
+
/**
* A filter pad used for either input or output
*/
@@ -259,6 +261,17 @@ struct AVFilterPad
void (*draw_slice)(AVFilterLink *link, int y, int height);
/**
+ * Frame poll callback. This returns the number of immediately available
+ * frames. It should return a positive value if the next request_frame()
+ * is guaranteed to return one frame (with no delay).
+ *
+ * Defaults to just calling the source poll_frame() method.
+ *
+ * Output video pads only.
+ */
+ int (*poll_frame)(AVFilterLink *link);
+
+ /**
* Frame request callback. A call to this should result in at least one
* frame being output over the given link. This should return zero on
* success, and another value on error.
Modified: libavfilter/avfiltergraph.c
==============================================================================
--- libavfilter/avfiltergraph.c (original)
+++ libavfilter/avfiltergraph.c Wed Feb 6 20:55:36 2008
@@ -69,6 +69,15 @@ static int link_in_request_frame(AVFilte
return avfilter_request_frame(link2);
}
+
+static int link_in_poll_frame(AVFilterLink *link)
+{
+ AVFilterLink *link2 = get_extern_input_link(link);
+ if(!link2)
+ return -1;
+ return avfilter_poll_frame(link2);
+}
+
static int link_in_config_props(AVFilterLink *link)
{
AVFilterLink *link2 = get_extern_input_link(link);
@@ -236,6 +245,16 @@ static int graph_out_request_frame(AVFil
return -1;
}
+static int graph_out_poll_frame(AVFilterLink *link)
+{
+ AVFilterLink *link2 = get_intern_output_link(link);
+
+ if(!link2)
+ return -1;
+
+ return avfilter_poll_frame(link2);
+}
+
static int graph_out_config_props(AVFilterLink *link)
{
GraphContext *graph = link->src->priv;
@@ -276,6 +295,7 @@ static int add_graph_input(AVFilterConte
.name = NULL, /* FIXME? */
.type = AV_PAD_VIDEO,
.request_frame = link_in_request_frame,
+ .poll_frame = link_in_poll_frame,
.config_props = link_in_config_props,
};
@@ -296,6 +316,7 @@ static int add_graph_output(AVFilterCont
.name = name,
.type = AV_PAD_VIDEO,
.request_frame = graph_out_request_frame,
+ .poll_frame = graph_out_poll_frame,
.config_props = graph_out_config_props,
};
AVFilterPad dummy_inpad =
Modified: libavfilter/diffs/04_ffmpeg_filters.diff
==============================================================================
--- libavfilter/diffs/04_ffmpeg_filters.diff (original)
+++ libavfilter/diffs/04_ffmpeg_filters.diff Wed Feb 6 20:55:36 2008
@@ -24,7 +24,7 @@ Index: ffmpeg.c
static int intra_only = 0;
static int audio_sample_rate = 44100;
-@@ -275,6 +283,12 @@
+@@ -275,6 +283,13 @@
is not defined */
int64_t pts; /* current pts */
int is_start; /* is 1 at the start and after a discontinuity */
@@ -32,12 +32,13 @@ Index: ffmpeg.c
+ AVFilterContext *out_video_filter;
+ AVFilterContext *input_video_filter;
+ AVFrame *filter_frame;
++ int has_filter_frame;
+ AVFilterPicRef *picref;
+#endif
} AVInputStream;
typedef struct AVInputFile {
-@@ -290,6 +304,259 @@
+@@ -290,6 +305,268 @@
static struct termios oldtty;
#endif
@@ -64,6 +65,12 @@ Index: ffmpeg.c
+ 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;
@@ -84,6 +91,8 @@ Index: ffmpeg.c
+ avfilter_end_frame(link);
+ avfilter_unref_pic(picref);
+
++ priv->ist->has_filter_frame = 0;
++
+ return 0;
+}
+
@@ -122,6 +131,7 @@ Index: ffmpeg.c
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AV_PAD_VIDEO,
+ .request_frame = input_request_frame,
++ .poll_frame = poll_frame,
+ .config_props = input_config_props, },
+ { .name = NULL }},
+};
@@ -155,7 +165,7 @@ Index: ffmpeg.c
+}
+
+static int get_filtered_video_pic(AVFilterContext *ctx,
-+ AVFilterPicRef **picref, AVPicture *pic2,
++ AVFilterPicRef **picref, AVFrame *pic2,
+ uint64_t *pts)
+{
+ AVFilterPicRef *pic;
@@ -297,21 +307,7 @@ Index: ffmpeg.c
static void term_exit(void)
{
#ifdef HAVE_TERMIOS_H
-@@ -635,6 +902,13 @@
- frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height,
- 1000000 * ist->pts / AV_TIME_BASE);
-
-+#if ENABLE_AVFILTER
-+ memcpy(ist->filter_frame->data, picture2->data, sizeof(picture2->data));
-+ memcpy(ist->filter_frame->linesize, picture2->linesize, sizeof(picture2->linesize));
-+
-+ if (get_filtered_video_pic(ist->out_video_filter, &ist->picref, picture2, &ist->pts) < 0)
-+ fprintf(stderr, "Error: get_filtered_video_pic failed!\n");
-+#endif
- if (picture != picture2)
- *picture = *picture2;
- *bufp = buf;
-@@ -745,6 +1019,9 @@
+@@ -745,6 +1022,9 @@
if (nb_frames <= 0)
return;
@@ -321,7 +317,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");
-@@ -754,6 +1031,7 @@
+@@ -754,6 +1034,7 @@
} else {
formatted_picture = in_picture;
}
@@ -329,7 +325,7 @@ Index: ffmpeg.c
final_picture = formatted_picture;
padding_src = formatted_picture;
-@@ -769,12 +1047,14 @@
+@@ -769,12 +1050,14 @@
}
}
@@ -344,18 +340,48 @@ Index: ffmpeg.c
if (ost->video_pad) {
av_picture_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
-@@ -1275,6 +1555,10 @@
- }
- }
- }
+@@ -1154,6 +1437,17 @@
+ &buffer_to_free);
+ }
+
+#if ENABLE_AVFILTER
-+ if(ist->picref)
-+ avfilter_unref_pic(ist->picref);
++ 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;
++ }
+#endif
- av_free(buffer_to_free);
- /* XXX: allocate the subtitles in the codec ? */
- if (subtitle_to_free) {
-@@ -1680,10 +1964,21 @@
++
+ // preprocess audio (volume)
+ if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
+ if (audio_volume != 256) {
+@@ -1216,10 +1510,22 @@
+ do_audio_out(os, ost, ist, data_buf, data_size);
+ break;
+ case CODEC_TYPE_VIDEO:
++#if ENABLE_AVFILTER
++ while(avfilter_poll_frame(ist->out_video_filter->inputs[0])) {
++ get_filtered_video_pic(ist->out_video_filter, &ist->picref, &picture, &ist->pts);
++ do_video_out(os, ost, ist, &picture, &frame_size);
++ video_size += frame_size;
++ if (vstats_filename && frame_size)
++ do_video_stats(os, ost, frame_size);
++ if(ist->picref)
++ avfilter_unref_pic(ist->picref);
++ }
++#else
+ do_video_out(os, ost, ist, &picture, &frame_size);
+ video_size += frame_size;
+ if (vstats_filename && frame_size)
+ do_video_stats(os, ost, frame_size);
++#endif
+ break;
+ case CODEC_TYPE_SUBTITLE:
+ do_subtitle_out(os, ost, ist, &subtitle,
+@@ -1680,10 +1986,21 @@
fprintf(stderr, "Cannot get resampling context\n");
exit(1);
}
@@ -377,7 +403,7 @@ Index: ffmpeg.c
break;
case CODEC_TYPE_SUBTITLE:
ost->encoding_needed = 1;
-@@ -3782,6 +4077,9 @@
+@@ -3782,6 +4099,9 @@
#ifdef CONFIG_VHOOK
{ "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
#endif
Modified: libavfilter/vf_fps.c
==============================================================================
--- libavfilter/vf_fps.c (original)
+++ libavfilter/vf_fps.c Wed Feb 6 20:55:36 2008
@@ -32,6 +32,8 @@ typedef struct {
uint64_t timebase;
uint64_t pts;
AVFilterPicRef *pic;
+ int videoend;
+ int has_frame;
} FPSContext;
static int init(AVFilterContext *ctx, const char *args, void *opaque)
@@ -63,6 +65,23 @@ static void start_frame(AVFilterLink *li
fps->pic = picref;
}
+static int poll_frame(AVFilterLink *link)
+{
+ FPSContext *fps = link->src->priv;
+
+ if (fps->has_frame)
+ return 1;
+
+ if(avfilter_poll_frame(link->src->inputs[0]) &&
+ avfilter_request_frame(link->src->inputs[0])) {
+ fps->videoend = 1;
+ return 1;
+ }
+
+ fps->has_frame = !!(fps->pic && fps->pic->pts >= fps->pts);
+ return fps->has_frame;
+}
+
static void end_frame(AVFilterLink *link)
{
}
@@ -71,14 +90,22 @@ static int request_frame(AVFilterLink *l
{
FPSContext *fps = link->src->priv;
- while(!fps->pic || fps->pic->pts < fps->pts)
- if(avfilter_request_frame(link->src->inputs[0]))
- return -1;
+ if (fps->videoend)
+ return -1;
+ if (!fps->has_frame) // Support for filtering without poll_frame usage
+ while(!fps->pic || fps->pic->pts < fps->pts)
+ if(avfilter_request_frame(link->src->inputs[0]))
+ return -1;
+
+ fps->has_frame=0;
avfilter_start_frame(link, avfilter_ref_pic(fps->pic, ~AV_PERM_WRITE));
avfilter_draw_slice (link, 0, fps->pic->h);
avfilter_end_frame (link);
+ avfilter_unref_pic(fps->pic);
+ fps->pic = NULL;
+
fps->pts += fps->timebase;
return 0;
@@ -101,6 +128,7 @@ AVFilter avfilter_vf_fps =
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AV_PAD_VIDEO,
+ .poll_frame = poll_frame,
.request_frame = request_frame, },
{ .name = NULL}},
};
More information about the FFmpeg-soc
mailing list