[FFmpeg-devel] [RFC] lavc/ffmpeg sample_fmt implementation

Michael Niedermayer michaelni
Sun Jul 27 23:00:05 CEST 2008


On Sun, Jul 27, 2008 at 06:17:48PM +1000, pross at xvid.org wrote:
> On Sat, Jul 26, 2008 at 01:08:09AM +1000, pross at xvid.org wrote:
> > Hi.
> > 
> > This patch adds sample_fmt conversion support to lavc (and ffmpeg).
> 
> Round two patches enclosed.
> 

> * part1 - modifies all audio codecs to report their supported
>   input/output sample formats.

ok


> * part2 - sample_fmt implementation
> * part3 - removes sample_fmt checks. (these checks will become
>    redudant when parts 1 and 2 are committed).
> 

> I noted that svq1dec is the only video *decoder* that populates
> pix_fmts. This seems unnecesary. Anyone have a view on this?

hmmm, it could be used to avoid a close() function. The generic code could
that way initialize pix/sample_fmt.


[...]

> Index: ffmpeg.c
> ===================================================================
> --- ffmpeg.c	(revision 14412)
> +++ ffmpeg.c	(working copy)
> @@ -103,6 +103,7 @@
>  static int frame_height = 0;
>  static float frame_aspect_ratio = 0;
>  static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
> +static enum SampleFormat audio_sample_fmt = SAMPLE_FMT_NONE;
>  static int frame_padtop  = 0;
>  static int frame_padbottom = 0;
>  static int frame_padleft  = 0;

ok


[...]

> @@ -2453,13 +2488,13 @@
>      }
>  }
>  
> -static void list_pix_fmts(void)
> +static void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
>  {
>      int i;
> -    char pix_fmt_str[128];
> -    for (i=-1; i < PIX_FMT_NB; i++) {
> -        avcodec_pix_fmt_string (pix_fmt_str, sizeof(pix_fmt_str), i);
> -        fprintf(stdout, "%s\n", pix_fmt_str);
> +    char fmt_str[128];
> +    for (i=-1; i < nb_fmts; i++) {
> +        get_fmt_string (fmt_str, sizeof(fmt_str), i);
> +        fprintf(stdout, "%s\n", fmt_str);
>      }
>  }
>  
> @@ -2468,7 +2503,7 @@
>      if (strcmp(arg, "list"))
>          frame_pix_fmt = avcodec_get_pix_fmt(arg);
>      else {
> -        list_pix_fmts();
> +        list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
>          av_exit(0);
>      }
>  }
> @@ -2522,6 +2557,16 @@
>      return 0;
>  }
>  
> +static void opt_audio_sample_fmt(const char *arg)
> +{
> +    if (strcmp(arg, "list"))
> +        audio_sample_fmt = avcodec_get_sample_fmt(arg);
> +    else {
> +        list_fmts(avcodec_sample_fmt_string, SAMPLE_FMT_NB);
> +        av_exit(0);
> +    }
> +}
> +
>  static int opt_audio_rate(const char *opt, const char *arg)
>  {
>      audio_sample_rate = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);

ok


[...]
> @@ -3779,6 +3839,7 @@
>      { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, //
>      { "newaudio", OPT_AUDIO, {(void*)opt_new_audio_stream}, "add a new audio stream to the current output stream" },
>      { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" },
> +    { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_sample_fmt}, "set sample format, 'list' as argument shows all the sample formats supported", "format" },
>  
>      /* subtitle options */
>      { "sn", OPT_BOOL | OPT_SUBTITLE, {(void*)&subtitle_disable}, "disable subtitle" },

ok


> Index: libavcodec/utils.c
> ===================================================================
> --- libavcodec/utils.c	(revision 14412)
> +++ libavcodec/utils.c	(working copy)
> @@ -765,7 +765,7 @@
>      s->execute= avcodec_default_execute;
>      s->sample_aspect_ratio= (AVRational){0,1};
>      s->pix_fmt= PIX_FMT_NONE;
> -    s->sample_fmt= SAMPLE_FMT_S16; // FIXME: set to NONE
> +    s->sample_fmt= SAMPLE_FMT_NONE;
>  
>      s->palctrl = NULL;
>      s->reget_buffer= avcodec_default_reget_buffer;
> @@ -1148,6 +1148,10 @@
>                       enc->sample_rate,
>                       channels_str);
>          }
> +        if (enc->sample_fmt != SAMPLE_FMT_NONE) {
> +            snprintf(buf + strlen(buf), buf_size - strlen(buf),
> +                     ", %s", avcodec_get_sample_fmt_name(enc->sample_fmt));
> +        }
>  
>          /* for PCM codecs, compute bitrate directly */
>          switch(enc->codec_id) {

ok


> Index: libavcodec/audioconvert.c
> ===================================================================
> --- libavcodec/audioconvert.c	(revision 14412)
> +++ libavcodec/audioconvert.c	(working copy)
> @@ -27,27 +27,97 @@
>  
>  #include "avcodec.h"
>  
> -int av_audio_convert(void *maybe_dspcontext_or_something_av_convert_specific,
> -                     void *out[6], int out_stride[6], enum SampleFormat out_fmt,
> -                     void * in[6], int  in_stride[6], enum SampleFormat  in_fmt, int len){
> +typedef struct SampleFmtInfo {
> +    const char *name;
> +    int bits;
> +} SampleFmtInfo;
> +

> +/* this table gives more information about formats */
> +static const SampleFmtInfo sample_fmt_info[SAMPLE_FMT_NB] = {

doxygen


> +    [SAMPLE_FMT_U8]  = { .name = "u8",  .bits = 8 },
> +    [SAMPLE_FMT_S16] = { .name = "s16", .bits = 16 },
> +    [SAMPLE_FMT_S24] = { .name = "s24", .bits = 24 },
> +    [SAMPLE_FMT_S32] = { .name = "s32", .bits = 32 },
> +    [SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32 }
> +};
> +

> +const char *avcodec_get_sample_fmt_name(int sample_fmt)
> +{
> +    if (sample_fmt < 0 || sample_fmt >= SAMPLE_FMT_NB)
> +        return "???";

i wonder why this is not NULL?


> +    else
> +        return sample_fmt_info[sample_fmt].name;
> +}
> +

> +enum SampleFormat avcodec_get_sample_fmt(const char* name)
> +{
> +    int i;
> +
> +    for (i=0; i < SAMPLE_FMT_NB; i++)
> +         if (!strcmp(sample_fmt_info[i].name, name))
> +             break;

not 4 space indent


> +    return i;
> +}

this has a flaw, how does a user check for failure? He cannot use 
>=SAMPLE_FMT_NB ...


[...]
> Index: libavcodec/avcodec.h
> ===================================================================
> --- libavcodec/avcodec.h	(revision 14412)
> +++ libavcodec/avcodec.h	(working copy)
> @@ -2338,6 +2338,57 @@
>  void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
>  void av_resample_close(struct AVResampleContext *c);
>  
> +/* audioconvert.c */
> +
> +/**
> + * Print in buf the string corresponding to the sample format with
> + * number sample_fmt, or an header if sample_fmt is negative.
> + *
> + * @param[in] buf the buffer where to write the string
> + * @param[in] buf_size the size of buf
> + * @param[in] sample_fmt the number of the sample format to print the corresponding info string, or
> + * a negative value to print the corresponding header.
> + * Meaningful values for obtaining a sample format info vary from 0 to SAMPLE_FMT_NB -1.
> + */
> +void avcodec_sample_fmt_string(char *buf, int buf_size, int sample_fmt);
> +const char *avcodec_get_sample_fmt_name(int sample_fmt);
> +enum SampleFormat avcodec_get_sample_fmt(const char* name);

i think audioconvert should have its own header


> +
> +
> +struct AVReformatContext;

The name is a little generic and doesnt hint toward audio anything


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I wish the Xiph folks would stop pretending they've got something they
do not.  Somehow I fear this will remain a wish. -- M?ns Rullg?rd
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080727/2786092c/attachment.pgp>



More information about the ffmpeg-devel mailing list