[FFmpeg-soc] [soc]: r1423 - in libavfilter: README diffs/04_ffmpeg_filters.diff

vitor subversion at mplayerhq.hu
Mon Oct 29 17:07:34 CET 2007


Author: vitor
Date: Mon Oct 29 17:07:34 2007
New Revision: 1423

Log:
First (possibly buggy) try of ffmpeg integration.
At this point, the integration is quite simple. It is not 
possible yet to use more than one input and one output stream 
for filtering.


Added:
   libavfilter/diffs/04_ffmpeg_filters.diff
Modified:
   libavfilter/README

Modified: libavfilter/README
==============================================================================
--- libavfilter/README	(original)
+++ libavfilter/README	Mon Oct 29 17:07:34 2007
@@ -18,8 +18,7 @@ wiki.  See http://wiki.multimedia.cx/ind
 
 RUNNING IT:
 
-Currently, only ffplay has been modified to make use of libavfilter.  The
-command line syntax for specifying filters is similar to that of mplayer.
+The command line syntax for specifying filters is similar to that of mplayer.
 For example, to vertically flip a video, you would do:
 
 ./ffplay -vfilters vflip input_video.avi

Added: libavfilter/diffs/04_ffmpeg_filters.diff
==============================================================================
--- (empty file)
+++ libavfilter/diffs/04_ffmpeg_filters.diff	Mon Oct 29 17:07:34 2007
@@ -0,0 +1,356 @@
+Index: ffmpeg.c
+===================================================================
+--- ffmpeg.c	(revision 10755)
++++ ffmpeg.c	(working copy)
+@@ -34,6 +34,10 @@
+ #include "fifo.h"
+ #include "avstring.h"
+ 
++#if ENABLE_AVFILTER
++# include "avfilter.h"
++#endif
++
+ #if !defined(HAVE_GETRUSAGE) && defined(HAVE_GETPROCESSTIMES)
+ #include <windows.h>
+ #endif
+@@ -142,6 +146,7 @@
+ static int loop_input = 0;
+ static int loop_output = AVFMT_NOOUTPUTLOOP;
+ static int qp_hist = 0;
++static char *vfilters = NULL;
+ 
+ static int intra_only = 0;
+ static int audio_sample_rate = 44100;
+@@ -277,6 +282,11 @@
+                                 is not defined */
+     int64_t       pts;       /* current pts */
+     int is_start;            /* is 1 at the start and after a discontinuity */
++#if ENABLE_AVFILTER
++    AVFilterContext *out_video_filter;
++    AVFilterContext *input_video_filter;
++    AVFrame *filter_frame;
++#endif
+ } AVInputStream;
+ 
+ typedef struct AVInputFile {
+@@ -292,6 +302,241 @@
+ 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 input_request_frame(AVFilterLink *link)
++{
++    FilterInPriv *priv = link->src->priv;
++    AVFilterPicRef *picref;
++
++    picref = avfilter_get_video_buffer(link, AV_PERM_WRITE);
++
++    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);
++
++    return 0;
++}
++
++static int *input_query_formats(AVFilterLink *link)
++{
++    FilterInPriv *priv = link->src->priv;
++    return avfilter_make_format_list(1, priv->ist->st->codec->pix_fmt);
++}
++
++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",
++    .author    = "Vitor Sessak",
++
++    .priv_size = sizeof(FilterInPriv),
++
++    .init      = input_init,
++    .uninit    = input_uninit,
++
++    .inputs    = (AVFilterPad[]) {{ .name = NULL }},
++    .outputs   = (AVFilterPad[]) {{ .name = "default",
++                                    .type = AV_PAD_VIDEO,
++                                    .request_frame = input_request_frame,
++                                    .query_formats = input_query_formats,
++                                    .config_props  = input_config_props, },
++                                  { .name = NULL }},
++};
++
++typedef struct {
++    int pix_fmt;
++} FilterOutPriv;
++
++
++static int output_init(AVFilterContext *ctx, const char *args, void *opaque)
++{
++    FilterOutPriv *priv = ctx->priv;
++
++    if(!opaque) return -1;
++
++    priv->pix_fmt = *((int *)opaque);
++
++    return 0;
++}
++
++static void output_end_frame(AVFilterLink *link)
++{
++}
++
++static int *output_query_formats(AVFilterLink *link)
++{
++    FilterOutPriv *priv = link->dst->priv;
++    return avfilter_make_format_list(1, priv->pix_fmt);
++}
++
++static int get_filtered_video_pic(AVFilterContext *ctx, AVPicture *pic2,
++                                  uint64_t *pts)
++{
++    AVFilterPicRef *pic;
++
++    if(avfilter_request_frame(ctx->inputs[0]))
++        return -1;
++    if(!(pic = ctx->inputs[0]->cur_pic))
++        return -1;
++    ctx->inputs[0]->cur_pic = NULL;
++
++    *pts          = pic->pts;
++
++    memcpy(pic2->data,     pic->data,     sizeof(pic->data));
++    memcpy(pic2->linesize, pic->linesize, sizeof(pic->linesize));
++
++    return 1;
++}
++
++static AVFilter output_filter =
++{
++    .name      = "ffmpeg_output",
++    .author    = "Vitor Sessak",
++
++    .priv_size = sizeof(FilterOutPriv),
++    .init      = output_init,
++
++    .inputs    = (AVFilterPad[]) {{ .name          = "default",
++                                    .type          = AV_PAD_VIDEO,
++                                    .end_frame     = output_end_frame,
++                                    .query_formats = output_query_formats,
++                                    .min_perms     = AV_PERM_READ, },
++                                  { .name = NULL }},
++    .outputs   = (AVFilterPad[]) {{ .name = NULL }},
++};
++
++static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
++{
++    AVFilterContext *curr_filter;
++    AVFilterContext *filt_graph;
++    AVCodecContext *codec = ost->st->codec;
++    AVCodecContext *icodec = ist->st->codec;
++
++    avfilter_init();
++    
++    if(!(ist->input_video_filter = avfilter_open(&input_filter,  "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))
++        return -1;
++    if(avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
++        return -1;
++
++    curr_filter = ist->input_video_filter;
++
++    if(ost->video_crop) {
++        char crop_args[255];
++        AVFilterContext *filt_crop;
++        snprintf(crop_args, 255, "%d:%d:%d:%d", ost->topBand, ost->topBand, codec->height - frame_topBand, codec->width- frame_bottomBand);
++        filt_crop = avfilter_open(avfilter_get_by_name("crop"), NULL);
++        if (!filt_crop)
++            return -1;
++        if (avfilter_init_filter(filt_crop, crop_args, NULL))
++            return -1;
++        if (avfilter_link(curr_filter, 0, filt_crop, 0))
++            return -1;
++        if (avfilter_config_link(curr_filter->outputs[0]))
++            return -1;
++        curr_filter = filt_crop;
++    }
++
++    if((codec->width !=
++        icodec->width - (frame_leftBand + frame_rightBand) +
++        (frame_padleft + frame_padright)) ||
++       (codec->height != icodec->height - (frame_topBand  + frame_bottomBand) +
++        (frame_padtop + frame_padbottom))) {
++        char crop_args[255];
++        AVFilterContext *filt_scale;
++        snprintf(crop_args, 255, "%d:%d", codec->width -
++                                             (frame_padleft + frame_padright),
++                 codec->height - (frame_padtop + frame_padbottom));
++        filt_scale = avfilter_open(avfilter_get_by_name("scale"), NULL);
++        if (!filt_scale)
++            return -1;
++        if (avfilter_init_filter(filt_scale, crop_args, NULL))
++            return -1;
++        if (avfilter_link(curr_filter, 0, filt_scale, 0))
++            return -1;
++        if (avfilter_config_link(curr_filter->outputs[0]))
++            return -1;
++        curr_filter = filt_scale;
++    }
++      
++
++
++    if(vfilters) {
++        if(!(filt_graph = avfilter_open(avfilter_get_by_name("graph"), NULL)))
++            return -1;
++        if(avfilter_init_filter(filt_graph, vfilters, NULL))
++            return -1;
++        if(avfilter_link(curr_filter, 0, filt_graph, 0))
++            return -1;
++        if(avfilter_link(filt_graph, 0, ist->out_video_filter, 0))
++            return -1;
++        if(avfilter_config_link(curr_filter->outputs[0]))
++            return -1;
++        if(avfilter_graph_config_links(filt_graph))
++            return -1;
++        if(avfilter_config_link(filt_graph->outputs[0]))
++            return -1;
++    } else {
++        if(avfilter_link(curr_filter, 0, ist->out_video_filter, 0) < 0)
++            return -1;
++        if(avfilter_config_link(curr_filter->outputs[0]))
++            return -1;
++
++    }
++
++    codec->width = ist->out_video_filter->inputs[0]->w;
++    codec->height = ist->out_video_filter->inputs[0]->h;
++
++    return 0;
++}
++#endif /* ENABLE_AVFILTER */
++
+ static void term_exit(void)
+ {
+ #ifdef HAVE_TERMIOS_H
+@@ -616,6 +861,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, picture2, &ist->pts) < 0)
++        fprintf(stderr, "Error: get_filtered_video_pic failed!\n");
++#endif    
+     if (picture != picture2)
+         *picture = *picture2;
+     *bufp = buf;
+@@ -726,6 +978,9 @@
+     if (nb_frames <= 0)
+         return;
+ 
++#if ENABLE_AVFILTER
++    formatted_picture = in_picture;
++#else
+     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");
+@@ -735,6 +990,7 @@
+     } else {
+         formatted_picture = in_picture;
+     }
++#endif
+ 
+     final_picture = formatted_picture;
+     padding_src = formatted_picture;
+@@ -750,12 +1006,14 @@
+         }
+     }
+ 
++#if !ENABLE_AVFILTER
+     if (ost->video_resample) {
+         padding_src = NULL;
+         final_picture = &ost->pict_tmp;
+         sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
+               0, ost->resample_height, resampling_dst->data, resampling_dst->linesize);
+     }
++#endif
+ 
+     if (ost->video_pad) {
+         av_picture_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
+@@ -1654,10 +1912,21 @@
+                         fprintf(stderr, "Cannot get resampling context\n");
+                         exit(1);
+                     }
++#if ENABLE_AVFILTER
++                    ost->resample_height = icodec->height;
++#else
+                     ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand);
++#endif
+                 }
+                 ost->encoding_needed = 1;
+                 ist->decoding_needed = 1;
++
++#if ENABLE_AVFILTER
++                if (configure_filters(ist, ost)) {
++                    fprintf(stderr, "Error opening filters!\n");
++                    exit(1);
++                }
++#endif
+                 break;
+             case CODEC_TYPE_SUBTITLE:
+                 ost->encoding_needed = 1;
+@@ -3674,6 +3943,9 @@
+ #ifdef CONFIG_VHOOK
+     { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
+ #endif
++#if ENABLE_AVFILTER
++    { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
++#endif
+     { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
+     { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
+     { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },



More information about the FFmpeg-soc mailing list