[FFmpeg-devel] [PATCH] ffmpeg: add -map_channel option.

Clément Bœsch ubitux at gmail.com
Mon Oct 24 14:05:55 CEST 2011


On Wed, Oct 19, 2011 at 11:42:15PM +0200, Michael Niedermayer wrote:
> [...]
> > diff --git a/libswresample/audioconvert.h b/libswresample/audioconvert.h
> > index e5fd4df..ca98d54 100644
> > --- a/libswresample/audioconvert.h
> > +++ b/libswresample/audioconvert.h
> > @@ -42,11 +42,14 @@ typedef struct AVAudioConvert AVAudioConvert;
> >   * @param in_fmt Input sample format
> >   * @param channels Number of channels
> >   * @param flags See AV_CPU_FLAG_xx
> > + * @param ch_map list of the channels id to pick from the source stream, NULL
> > + *               if all channels must be selected
> >   * @return NULL on error
> >   */
> >  AVAudioConvert *swr_audio_convert_alloc(enum AVSampleFormat out_fmt,
> >                                          enum AVSampleFormat in_fmt,
> > -                                        int channels, int flags);
> > +                                        int channels, const int *ch_map,
> > +                                        int flags);
> >  
> >  /**
> >   * Free audio sample format converter context.
> > diff --git a/libswresample/swresample.c b/libswresample/swresample.c
> > index bb5b523..67b9831 100644
> > --- a/libswresample/swresample.c
> > +++ b/libswresample/swresample.c
> > @@ -75,7 +75,7 @@ SwrContext *swr_alloc(void){
> >  
> >  SwrContext *swr_alloc2(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
> >                         int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
> > -                       int log_offset, void *log_ctx){
> > +                       const int *channel_map, int log_offset, void *log_ctx){
> >      if(!s) s= swr_alloc();
> >      if(!s) return NULL;
> >  
> > @@ -89,6 +89,7 @@ SwrContext *swr_alloc2(struct SwrContext *s, int64_t out_ch_layout, enum AVSampl
> >      av_set_int(s, "isf", in_sample_fmt);
> >      av_set_int(s, "isr", in_sample_rate);
> >  
> > +    s->channel_map = channel_map;
> >      s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout);
> >      s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);
> >      s->int_sample_fmt = AV_SAMPLE_FMT_S16;
> 
> > @@ -176,7 +177,7 @@ int swr_init(SwrContext *s){
> >      if(!s->out_ch_layout)
> >          s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
> >  
> > -    s->rematrix= s->out_ch_layout  !=s->in_ch_layout;
> > +    s->rematrix= s->out_ch_layout != s->in_ch_layout && s->channel_map < 0;
> 
> pointer < 0 ?
> 

This should be !s->channel_map of course (s->channel_map was an int in the
first version of the patch).

> also shouldnt rematrix be independant of the existence of a channel_map
> 

Well, AFAIU, the rematrix is meant to automatically set the audio gain
levels for each channel; the channel mapping is "incompatible" with this,
it's all about reordering, or maybe with another phrasing: ppl won't
expect the levels to change (the number of output channels being fixed by
the number of -map_channel and not a specific -ac option)

Also, I was thinking of adding an external rematrix flag for libswr to
allow disabling the gain level changes when the number of channels is
changed, would it make any sense? Another solution might be to finish the
MPlayer's af_pan port (which I'll try to send soon™©®), allowing arbitrary
gain levels for each channels.

New patch attached fixing the < 0 chunks.

-- 
Clément B.
-------------- next part --------------
From 8c7770ab8b39663696080cc3c39c41e7baaae748 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <clement.boesch at smartjog.com>
Date: Mon, 17 Oct 2011 10:33:47 +0200
Subject: [PATCH] ffmpeg: add -map_channel option.

Based on an initial work by Baptiste Coudurier.
---
 Changelog                           |    1 +
 doc/ffmpeg.texi                     |   23 +++++++++
 ffmpeg.c                            |   91 +++++++++++++++++++++++++++++++++++
 ffplay.c                            |    2 +-
 libswresample/audioconvert.c        |    8 ++-
 libswresample/audioconvert.h        |    5 ++-
 libswresample/swresample.c          |   13 +++--
 libswresample/swresample.h          |    4 +-
 libswresample/swresample_internal.h |    1 +
 libswresample/swresample_test.c     |    8 ++-
 10 files changed, 141 insertions(+), 15 deletions(-)

diff --git a/Changelog b/Changelog
index 5c9ccb5..f962d23 100644
--- a/Changelog
+++ b/Changelog
@@ -69,6 +69,7 @@ easier to use. The changes are:
 - Speex encoding via libspeex
 - 4:2:2 H.264 decoding support
 - Pulseaudio input device
+- new ffmpeg option: -map_channel
 
 version 0.8:
 
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index c59c757..5f929fd 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -721,6 +721,29 @@ ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
 
 Note that using this option disables the default mappings for this output file.
 
+ at item -map_channel @var{input_file_id}. at var{stream_specifier}. at var{channel_id}[:@var{output_file_id}. at var{stream_specifier}]
+Map an audio channel from a given input to an output. If
+ at var{output_file_id}. at var{stream_specifier} are not set, the audio channel will
+be mapped on all the audio streams.
+
+For example, assuming @var{INPUT} has two mono audio streams (say stream 1 and
+2), the following command creates a stereo audio stream in @var{OUTPUT} with
+first input stream as channel 0 and second input stream as channel 1:
+ at example
+ffmpeg -i INPUT -map_channel 0.1.0 -map_channel 0.2.0 OUTPUT
+ at end example
+
+The order of the "-map_channel" option specifies the order of the channels in
+the output stream. The output channel layout is guessed from the number of
+channels mapped (mono if one "-map_channel", stereo if two, etc.)
+
+You can also extract each channel of an @var{INPUT} to specific outputs; the
+following command extract each channel of the audio stream (file 0, stream 0)
+to the respective @var{OUTPUT_1} and @var{OUTPUT_2}:
+ at example
+ffmpeg -i INPUT -map_channel 0.0.0:0.0 -map_channel 0.0.1:1.0 OUTPUT_1 OUTPUT_2
+ at end example
+
 @item -map_metadata[:@var{metadata_type}][:@var{index}] @var{infile}[:@var{metadata_type}][:@var{index}] (@emph{output,per-metadata})
 Set metadata information of the next output file from @var{infile}. Note that
 those are file indices (zero-based), not filenames.
diff --git a/ffmpeg.c b/ffmpeg.c
index e165818..cd24ec0 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -99,6 +99,11 @@ typedef struct StreamMap {
     int sync_stream_index;
 } StreamMap;
 
+typedef struct {
+    int  file_idx,  stream_idx,  channel_idx; // input
+    int ofile_idx, ostream_idx;               // output
+} AudioChannelMap;
+
 /**
  * select an input file for an output file
  */
@@ -230,6 +235,8 @@ typedef struct OutputStream {
     int forced_kf_index;
 
     /* audio only */
+    int audio_channels_map[SWR_CH_MAX];  ///< list of the channels id to pick from the source stream
+    int audio_channels_mapped;           ///< number of channels in audio_channels_map
     int resample_sample_fmt;
     int resample_channels;
     int resample_sample_rate;
@@ -305,6 +312,8 @@ typedef struct OptionsContext {
     /* output options */
     StreamMap *stream_maps;
     int     nb_stream_maps;
+    AudioChannelMap *audio_channel_maps; ///< one info entry per -map_channel
+    int           nb_audio_channel_maps; ///< number of (valid) -map_channel settings
     /* first item specifies output metadata, second is input */
     MetadataMap (*meta_data_maps)[2];
     int nb_meta_data_maps;
@@ -399,6 +408,7 @@ static void reset_options(OptionsContext *o, int is_input)
     }
 
     av_freep(&o->stream_maps);
+    av_freep(&o->audio_channel_maps);
     av_freep(&o->meta_data_maps);
     av_freep(&o->streamid_map);
 
@@ -872,6 +882,7 @@ need_realloc:
             ost->swr = swr_alloc2(ost->swr,
                                   enc->channel_layout, enc->sample_fmt, enc->sample_rate,
                                   dec->channel_layout, dec->sample_fmt, dec->sample_rate,
+                                  ost->audio_channels_mapped ? ost->audio_channels_map : NULL,
                                   0, NULL);
             av_set_int(ost->swr, "ich", dec->channels);
             av_set_int(ost->swr, "och", enc->channels);
@@ -2170,6 +2181,14 @@ static int transcode_init(OutputFile *output_files, int nb_output_files,
                     codec->channels = icodec->channels;
                     codec->channel_layout = icodec->channel_layout;
                 }
+                if (ost->audio_channels_mapped) {
+                    codec->channels       = ost->audio_channels_mapped;
+                    codec->channel_layout = av_get_default_channel_layout(codec->channels);
+                    if (!codec->channel_layout) {
+                        av_log(NULL, AV_LOG_FATAL, "Unable to find an appropriate channel layout for requested number of channel\n");
+                        exit_program(1);
+                    }
+                }
                 if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
                     codec->channel_layout = 0;
                 icodec->request_channels = codec->channels;
@@ -2367,6 +2386,12 @@ static int transcode_init(OutputFile *output_files, int nb_output_files,
                input_streams[ost->source_index].st->index,
                ost->file_index,
                ost->index);
+        if (ost->audio_channels_mapped) {
+            av_log(NULL, AV_LOG_INFO, " [ch:");
+            for (j = 0; j < ost->audio_channels_mapped; j++)
+                av_log(NULL, AV_LOG_INFO, " %d", ost->audio_channels_map[j]);
+            av_log(NULL, AV_LOG_INFO, "]");
+        }
         if (ost->sync_ist != &input_streams[ost->source_index])
             av_log(NULL, AV_LOG_INFO, " [sync #%d.%d]",
                    ost->sync_ist->file_index,
@@ -2869,6 +2894,55 @@ static int opt_map(OptionsContext *o, const char *opt, const char *arg)
     return 0;
 }
 
+static int opt_map_channel(OptionsContext *o, const char *opt, const char *arg)
+{
+    int n;
+    AVStream *st;
+    AudioChannelMap *m;
+
+    o->audio_channel_maps =
+        grow_array(o->audio_channel_maps, sizeof(*o->audio_channel_maps),
+                   &o->nb_audio_channel_maps, o->nb_audio_channel_maps + 1);
+    m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1];
+    n = sscanf(arg, "%d.%d.%d:%d.%d",
+               &m->file_idx,  &m->stream_idx, &m->channel_idx,
+               &m->ofile_idx, &m->ostream_idx);
+
+    if (n != 3 && n != 5) {
+        av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
+               "file.stream.channel[:syncfile:syncstream]\n");
+        exit_program(1);
+    }
+
+    if (n != 5) // only file.stream.channel specified
+        m->ofile_idx = m->ostream_idx = -1;
+
+    /* check input */
+    if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
+               m->file_idx);
+        exit_program(1);
+    }
+    if (m->stream_idx < 0 ||
+        m->stream_idx >= input_files[m->file_idx].nb_streams) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
+               m->file_idx, m->stream_idx);
+        exit_program(1);
+    }
+    st = input_files[m->file_idx].ctx->streams[m->stream_idx];
+    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
+               m->file_idx, m->stream_idx);
+        exit_program(1);
+    }
+    if (m->channel_idx < 0 || m->channel_idx >= st->codec->channels) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n",
+               m->file_idx, m->stream_idx, m->channel_idx);
+        exit_program(1);
+    }
+    return 0;
+}
+
 static void parse_meta_type(char *arg, char *type, int *index)
 {
     if (*arg) {
@@ -3486,6 +3560,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
 
 static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
 {
+    int n;
     AVStream *st;
     OutputStream *ost;
     AVCodecContext *audio_enc;
@@ -3511,6 +3586,21 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
         MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
     }
 
+    /* check for channel mapping for this audio stream */
+    for (n = 0; n < o->nb_audio_channel_maps; n++) {
+        AudioChannelMap *map = &o->audio_channel_maps[n];
+        if (input_streams[ost->source_index].file_index == map->file_idx    &&
+            input_streams[ost->source_index].st->index  == map->stream_idx  &&
+            (map->ofile_idx   == -1 || ost->file_index == map->ofile_idx)   &&
+            (map->ostream_idx == -1 || ost->st->index  == map->ostream_idx)) {
+            if (ost->audio_channels_mapped < FF_ARRAY_ELEMS(ost->audio_channels_map))
+                ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
+            else
+                av_log(NULL, AV_LOG_FATAL, "Max channel mapping for output %d.%d reached\n",
+                       ost->file_index, ost->st->index);
+        }
+    }
+
     return ost;
 }
 
@@ -4286,6 +4376,7 @@ static const OptionDef options[] = {
     { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
     { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" },
     { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
+    { "map_channel", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_channel}, "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" },
     { "map_meta_data", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile",
       "outfile[,metadata]:infile[,metadata]" },
     { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
diff --git a/ffplay.c b/ffplay.c
index c998b5d..6cd810d 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -2027,7 +2027,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
                     swr_free(&is->swr_ctx);
                 is->swr_ctx = swr_alloc2(NULL, is->audio_tgt_channel_layout, is->audio_tgt_fmt, is->audio_tgt_freq,
                                                dec_channel_layout,          dec->sample_fmt,   dec->sample_rate,
-                                               0, NULL);
+                                               NULL, 0, NULL);
                 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
                     fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
                         dec->sample_rate,
diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c
index a1fa3eb..1a61cac 100644
--- a/libswresample/audioconvert.c
+++ b/libswresample/audioconvert.c
@@ -35,11 +35,13 @@
 struct AVAudioConvert {
     int channels;
     int fmt_pair;
+    const int *ch_map;
 };
 
 AVAudioConvert *swr_audio_convert_alloc(enum AVSampleFormat out_fmt,
                                         enum AVSampleFormat in_fmt,
-                                        int channels, int flags)
+                                        int channels, const int *ch_map,
+                                        int flags)
 {
     AVAudioConvert *ctx;
     ctx = av_malloc(sizeof(AVAudioConvert));
@@ -47,6 +49,7 @@ AVAudioConvert *swr_audio_convert_alloc(enum AVSampleFormat out_fmt,
         return NULL;
     ctx->channels = channels;
     ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
+    ctx->ch_map   = ch_map;
     return ctx;
 }
 
@@ -66,7 +69,8 @@ int swr_audio_convert(AVAudioConvert *ctx, AudioData *out, AudioData*in, int len
     for(ch=0; ch<ctx->channels; ch++){
         const int is= (in ->planar ? 1 : in->ch_count) * in->bps;
         const int os= (out->planar ? 1 :out->ch_count) *out->bps;
-        const uint8_t *pi= in ->ch[ch];
+        const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch;
+        const uint8_t *pi= in ->ch[ich];
         uint8_t       *po= out->ch[ch];
         uint8_t *end= po + os*len;
         if(!po)
diff --git a/libswresample/audioconvert.h b/libswresample/audioconvert.h
index e5fd4df..ca98d54 100644
--- a/libswresample/audioconvert.h
+++ b/libswresample/audioconvert.h
@@ -42,11 +42,14 @@ typedef struct AVAudioConvert AVAudioConvert;
  * @param in_fmt Input sample format
  * @param channels Number of channels
  * @param flags See AV_CPU_FLAG_xx
+ * @param ch_map list of the channels id to pick from the source stream, NULL
+ *               if all channels must be selected
  * @return NULL on error
  */
 AVAudioConvert *swr_audio_convert_alloc(enum AVSampleFormat out_fmt,
                                         enum AVSampleFormat in_fmt,
-                                        int channels, int flags);
+                                        int channels, const int *ch_map,
+                                        int flags);
 
 /**
  * Free audio sample format converter context.
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index a03d531..f9f7399 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -75,7 +75,7 @@ SwrContext *swr_alloc(void){
 
 SwrContext *swr_alloc2(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
                        int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
-                       int log_offset, void *log_ctx){
+                       const int *channel_map, int log_offset, void *log_ctx){
     if(!s) s= swr_alloc();
     if(!s) return NULL;
 
@@ -89,6 +89,7 @@ SwrContext *swr_alloc2(struct SwrContext *s, int64_t out_ch_layout, enum AVSampl
     av_set_int(s, "isf", in_sample_fmt);
     av_set_int(s, "isr", in_sample_rate);
 
+    s->channel_map = channel_map;
     s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout);
     s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);
     s->int_sample_fmt = AV_SAMPLE_FMT_S16;
@@ -176,7 +177,7 @@ int swr_init(SwrContext *s){
     if(!s->out_ch_layout)
         s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
 
-    s->rematrix= s->out_ch_layout  !=s->in_ch_layout;
+    s->rematrix= s->out_ch_layout != s->in_ch_layout && !s->channel_map;
 
 #define RSC 1 //FIXME finetune
     if(!s-> in.ch_count)
@@ -192,16 +193,16 @@ av_assert0(s->out.ch_count);
     s->int_bps= av_get_bits_per_sample_fmt(s->int_sample_fmt)/8;
     s->out.bps= av_get_bits_per_sample_fmt(s->out_sample_fmt)/8;
 
-    if(!s->resample && !s->rematrix){
+    if(!s->resample && !s->rematrix && !s->channel_map){
         s->full_convert = swr_audio_convert_alloc(s->out_sample_fmt,
-                                                  s-> in_sample_fmt, s-> in.ch_count, 0);
+                                                  s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
         return 0;
     }
 
     s->in_convert = swr_audio_convert_alloc(s->int_sample_fmt,
-                                            s-> in_sample_fmt, s-> in.ch_count, 0);
+                                            s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
     s->out_convert= swr_audio_convert_alloc(s->out_sample_fmt,
-                                            s->int_sample_fmt, s->out.ch_count, 0);
+                                            s->int_sample_fmt, s->out.ch_count, s->channel_map, 0);
 
 
     s->postin= s->in;
diff --git a/libswresample/swresample.h b/libswresample/swresample.h
index 05c4f6d..85bd39f 100644
--- a/libswresample/swresample.h
+++ b/libswresample/swresample.h
@@ -25,7 +25,7 @@
 #include "libavutil/samplefmt.h"
 
 #define LIBSWRESAMPLE_VERSION_MAJOR 0
-#define LIBSWRESAMPLE_VERSION_MINOR 0
+#define LIBSWRESAMPLE_VERSION_MINOR 1
 #define LIBSWRESAMPLE_VERSION_MICRO 0
 
 #define SWR_CH_MAX 16
@@ -57,7 +57,7 @@ int swr_init(struct SwrContext *s);
  */
 struct SwrContext *swr_alloc2(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
                               int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
-                              int log_offset, void *log_ctx);
+                              const int *channel_map, int log_offset, void *log_ctx);
 
 /**
  * Free the given SwrContext.
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
index 3137be6..cb9c2fd 100644
--- a/libswresample/swresample_internal.h
+++ b/libswresample/swresample_internal.h
@@ -45,6 +45,7 @@ typedef struct SwrContext {          //FIXME find unused fields
     int     out_sample_rate;
     int flags;
     float slev, clev;
+    const int *channel_map;
 
     //below are private
     int int_bps;
diff --git a/libswresample/swresample_test.c b/libswresample/swresample_test.c
index 61e1b09..bb229f8 100644
--- a/libswresample/swresample_test.c
+++ b/libswresample/swresample_test.c
@@ -131,9 +131,11 @@ int main(int argc, char **argv){
                                in_sample_rate, out_sample_rate,
                                av_get_sample_fmt_name(in_sample_fmt), av_get_sample_fmt_name(out_sample_fmt));
                         forw_ctx  = swr_alloc2(forw_ctx, out_ch_layout, out_sample_fmt+planar_out, out_sample_rate,
-                                                                  in_ch_layout,  in_sample_fmt+planar_in ,  in_sample_rate, 0, 0);
-                        backw_ctx = swr_alloc2(backw_ctx,in_ch_layout,  in_sample_fmt,  in_sample_rate,
-                                                                 out_ch_layout, out_sample_fmt+planar_out, out_sample_rate, 0, 0);
+                                                          in_ch_layout,  in_sample_fmt+planar_in ,  in_sample_rate,
+                                                          NULL, 0, 0);
+                        backw_ctx = swr_alloc2(backw_ctx,in_ch_layout,  in_sample_fmt,             in_sample_rate,
+                                                        out_ch_layout, out_sample_fmt+planar_out, out_sample_rate,
+                                                        NULL, 0, 0);
                         if(swr_init( forw_ctx) < 0)
                             fprintf(stderr, "swr_init(->) failed\n");
                         if(swr_init(backw_ctx) < 0)
-- 
1.7.5.4

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20111024/ceeebe86/attachment.asc>


More information about the ffmpeg-devel mailing list