[FFmpeg-devel] [PATCH] write AC-3 metadata

Michael Niedermayer michaelni
Sat Dec 25 21:05:24 CET 2010


On Wed, Dec 22, 2010 at 01:26:13PM -0500, Justin Ruggles wrote:
> On 12/21/2010 08:25 PM, Justin Ruggles wrote:
> 
> > On 12/21/2010 06:13 PM, Justin Ruggles wrote:
> > 
> >> On 12/21/2010 05:20 PM, Kieran Kunhya wrote:
> >>
> >>>> Date: Tuesday, 21 December, 2010, 21:56
> >>>> Hi,
> >>>>
> >>>> This patch adds writing of AC-3 metadata to the AC-3
> >>>> encoder.
> >>>>
> >>>> I chose to use AVOption instead of trying to move the
> >>>> metadata API to
> >>>> libavcodec because the AC-3 metadata isn't just regular
> >>>> metadata.  Even
> >>>> though it is not audio data, many of the fields actually
> >>>> affect decoding.
> >>>>
> >>>> Some of the options use integers to set a specific code
> >>>> value rather
> >>>> than using a float value directly (e.g. mixing
> >>>> levels).  It looks a bit
> >>>> ugly, but I chose to do this because there are only a few
> >>>> valid values.
> >>>>  Trying to determine which value the user wants by
> >>>> comparing floats
> >>>> seems more complicated.  Plus this allows the help
> >>>> text to tell the user
> >>>> what the valid values are for those options.
> >>>>
> >>>> Thanks,
> >>>> Justin
> >>>
> >>> Is there any possibility of making these metadata options changeable per frame? Quite useful for broadcast applications when the metadata needs to be different during advertising or during specific programming.
> >>
> >>
> >> If you're changing programs, you should probably re-initialize encoding
> >> anyway.  Other things can change too like bitrate, number of channels,
> >> etc...
> >>
> >> As for setting metadata per-frame, it is possible.  New patch attached.
> >>  It adds an option to enable per-frame validation of metadata so that it
> >> won't significantly affect performance when the option is not enabled.
> > 
> > 
> > oops. disregard this patch. i forgot the most important part. i'll send
> > a new one in a little while.
> 
> 
> New patch attached.
> 
> -Justin

>  ac3enc.c |  272 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 264 insertions(+), 8 deletions(-)
> 84663d8c7e570c303bd1e9ed48ec070bb1ed1c57  write_ac3_metadata.patch
> diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
> index 836b97c..db2c279 100644
> --- a/libavcodec/ac3enc.c
> +++ b/libavcodec/ac3enc.c
> @@ -30,6 +30,7 @@
>  
>  #include "libavcore/audioconvert.h"
>  #include "libavutil/crc.h"
> +#include "libavutil/opt.h"
>  #include "avcodec.h"
>  #include "put_bits.h"
>  #include "dsputil.h"
> @@ -67,6 +68,36 @@ typedef struct AC3MDCTContext {
>  } AC3MDCTContext;
>  
>  /**
> + * Encoding Options used by AVOption.
> + */
> +typedef struct AC3EncOptions {
> +    /* AC-3 metadata options*/
> +    int dialogue_level;
> +    int bitstream_mode;
> +    int center_mix_level;
> +    int surround_mix_level;
> +    int dolby_surround_mode;
> +    int audio_production_info;
> +    int mixing_level;
> +    int room_type;
> +    int copyright;
> +    int original;
> +    int extended_bsi_1;
> +    int preferred_stereo_downmix;
> +    int lt_rt_center_mix_level;
> +    int lt_rt_surround_mix_level;
> +    int lo_ro_center_mix_level;
> +    int lo_ro_surround_mix_level;
> +    int extended_bsi_2;
> +    int dolby_surround_ex_mode;
> +    int dolby_headphone_mode;
> +    int ad_converter_type;
> +
> +    /* other encoding options */
> +    int allow_per_frame_metadata;
> +} AC3EncOptions;
> +
> +/**
>   * Data for a single audio block.
>   */
>  typedef struct AC3Block {
> @@ -86,6 +117,8 @@ typedef struct AC3Block {
>   * AC-3 encoder private context.
>   */
>  typedef struct AC3EncodeContext {
> +    AVClass *av_class;                      ///< AVClass used for AVOption
> +    AC3EncOptions options;                  ///< encoding options
>      PutBitContext pb;                       ///< bitstream writer context
>      DSPContext dsp;
>      AC3MDCTContext mdct;                    ///< MDCT context
> @@ -149,6 +182,95 @@ typedef struct AC3EncodeContext {
>  } AC3EncodeContext;
>  
>  
> +#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> +
> +static const AVOption options[] = {
> +/* AC-3 Metadata options
> + * These parameters are described in detail in the Dolby Metadata Guide.
> + * http://www.dolby.com/uploadedFiles/zz-_Shared_Assets/English_PDFs/Professional/18_Metadata.Guide.pdf
> + */
> +{"dialnorm", "Dialogue Level (dB)", offsetof(AC3EncodeContext, options.dialogue_level), FF_OPT_TYPE_INT, 31, 1, 31, AC3ENC_PARAM},
> +{"bsmode", "Bitstream Mode", offsetof(AC3EncodeContext, options.bitstream_mode), FF_OPT_TYPE_INT, 0, 0, 7, AC3ENC_PARAM, "bsmode"},
> +    {"CM", "Complete Main (default)",  0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},

> +    {"ME", "Music and Effects",        0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +    {"VI", "Assoc: Visually Impaired", 0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +    {"HI", "Assoc: Hearing Impaired",  0, FF_OPT_TYPE_CONST, 3, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +    {"D",  "Assoc: Dialogue",          0, FF_OPT_TYPE_CONST, 4, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +    {"C",  "Assoc: Commentary",        0, FF_OPT_TYPE_CONST, 5, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},

these exist in mp3 too, and ideally converting ac3<->mp3 should preserve them



> +    {"E",  "Assoc: Emergency",         0, FF_OPT_TYPE_CONST, 6, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +    {"VO", "Assoc: Voice Over (1 ch)", 0, FF_OPT_TYPE_CONST, 7, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +    {"K",  "Karaoke (2 ch or more)",   0, FF_OPT_TYPE_CONST, 7, INT_MIN, INT_MAX, AC3ENC_PARAM, "bsmode"},
> +{"cmixlev", "Center Mix Level", offsetof(AC3EncodeContext, options.center_mix_level), FF_OPT_TYPE_INT, 1, 0, 2, AC3ENC_PARAM, "cmixlev"},
> +    {"0", "-3.0 dB (0.707)",           0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "cmixlev"},
> +    {"1", "-4.5 dB (0.595) (default)", 0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "cmixlev"},
> +    {"2", "-6.0 dB (0.500)",           0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "cmixlev"},
> +{"surmixlev", "Surround Mix Level", offsetof(AC3EncodeContext, options.surround_mix_level), FF_OPT_TYPE_INT, 1, 0, 2, AC3ENC_PARAM, "surmixlev"},
> +    {"0", "-3.0 dB (0.707)",           0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "surmixlev"},
> +    {"1", "-6.0 dB (0.500) (default)", 0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "surmixlev"},
> +    {"2", "-inf dB (0.000)",           0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "surmixlev"},
> +{"dsurmode", "Dolby Surround Mode", offsetof(AC3EncodeContext, options.dolby_surround_mode), FF_OPT_TYPE_INT, 0, 0, 2, AC3ENC_PARAM, "dsurmode"},
> +    {"notindicated", "Not Indicated (default)",    0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurmode"},
> +    {"on",           "Dolby Surround Encoded",     0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurmode"},
> +    {"off",          "Not Dolby Surround Encoded", 0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurmode"},
> +{"mixlevel", "Mixing Level", offsetof(AC3EncodeContext, options.mixing_level), FF_OPT_TYPE_INT, -1, -1, 31, AC3ENC_PARAM},
> +{"roomtype", "Room Type", offsetof(AC3EncodeContext, options.room_type), FF_OPT_TYPE_INT, -1, -1, 2, AC3ENC_PARAM, "roomtype"},
> +    {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "roomtype"},
> +    {"large",        "Large Room",              0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "roomtype"},
> +    {"small",        "Small Room",              0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "roomtype"},
> +{"copyright", "Copyright Bit", offsetof(AC3EncodeContext, options.copyright), FF_OPT_TYPE_INT, 0, 0, 1, AC3ENC_PARAM},
> +{"original", "Original Bit Stream", offsetof(AC3EncodeContext, options.original), FF_OPT_TYPE_INT, 1, 0, 1, AC3ENC_PARAM},
> +{"dmixmode", "Preferred Stereo Downmix Mode", offsetof(AC3EncodeContext, options.preferred_stereo_downmix), FF_OPT_TYPE_INT, -1, -1, 2, AC3ENC_PARAM, "dmixmode"},
> +    {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmixmode"},
> +    {"ltrt", "Lt/Rt Downmix Preferred",         0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmixmode"},
> +    {"loro", "Lo/Ro Downmix Preferred",         0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmixmode"},
> +{"ltrtcmixlev", "Lt/Rt Center Mix Level", offsetof(AC3EncodeContext, options.lt_rt_center_mix_level), FF_OPT_TYPE_INT, -1, -1, 7, AC3ENC_PARAM, "ltrtcmixlev"},

> +    {"0", "+3.0 dB (1.414)",           0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"1", "+1.5 dB (1.189)",           0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"2", "+0.0 dB (1.000)",           0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"3", "-1.5 dB (0.841)",           0, FF_OPT_TYPE_CONST, 3, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"4", "-3.0 dB (0.707)",           0, FF_OPT_TYPE_CONST, 4, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"5", "-4.5 dB (0.595) (default)", 0, FF_OPT_TYPE_CONST, 5, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"6", "-6.0 dB (0.500)",           0, FF_OPT_TYPE_CONST, 6, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +    {"7", "-inf dB (0.000)",           0, FF_OPT_TYPE_CONST, 7, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtcmixlev"},
> +{"ltrtsurmixlev", "Lt/Rt Surround Mix Level", offsetof(AC3EncodeContext, options.lt_rt_surround_mix_level), FF_OPT_TYPE_INT, -1, -1, 7, AC3ENC_PARAM, "ltrtsurmixlev"},
> +    {"3", "-1.5 dB (0.841)",           0, FF_OPT_TYPE_CONST, 3, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtsurmixlev"},
> +    {"4", "-3.0 dB (0.707)",           0, FF_OPT_TYPE_CONST, 4, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtsurmixlev"},
> +    {"5", "-4.5 dB (0.595)",           0, FF_OPT_TYPE_CONST, 5, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtsurmixlev"},
> +    {"6", "-6.0 dB (0.500) (default)", 0, FF_OPT_TYPE_CONST, 6, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtsurmixlev"},
> +    {"7", "-inf dB (0.000)",           0, FF_OPT_TYPE_CONST, 7, INT_MIN, INT_MAX, AC3ENC_PARAM, "ltrtsurmixlev"},
> +{"lorocmixlev", "Lo/Ro Center Mix Level", offsetof(AC3EncodeContext, options.lo_ro_center_mix_level), FF_OPT_TYPE_INT, -1, -1, 7, AC3ENC_PARAM, "lorocmixlev"},
> +    {"0", "+3.0 dB (1.414)",           0, FF_OPT_TYPE_CONST, 0, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"1", "+1.5 dB (1.189)",           0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"2", "+0.0 dB (1.000)",           0, FF_OPT_TYPE_CONST, 2, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"3", "-1.5 dB (0.841)",           0, FF_OPT_TYPE_CONST, 3, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"4", "-3.0 dB (0.707)",           0, FF_OPT_TYPE_CONST, 4, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"5", "-4.5 dB (0.595) (default)", 0, FF_OPT_TYPE_CONST, 5, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"6", "-6.0 dB (0.500)",           0, FF_OPT_TYPE_CONST, 6, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +    {"7", "-inf dB (0.000)",           0, FF_OPT_TYPE_CONST, 7, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorocmixlev"},
> +{"lorosurmixlev", "Lo/Ro Surround Mix Level", offsetof(AC3EncodeContext, options.lo_ro_surround_mix_level), FF_OPT_TYPE_INT, -1, -1, 7, AC3ENC_PARAM, "lorosurmixlev"},
> +    {"3", "-1.5 dB (0.841)",           0, FF_OPT_TYPE_CONST, 3, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorosurmixlev"},
> +    {"4", "-3.0 dB (0.707)",           0, FF_OPT_TYPE_CONST, 4, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorosurmixlev"},
> +    {"5", "-4.5 dB (0.595)",           0, FF_OPT_TYPE_CONST, 5, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorosurmixlev"},
> +    {"6", "-6.0 dB (0.500) (default)", 0, FF_OPT_TYPE_CONST, 6, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorosurmixlev"},
> +    {"7", "-inf dB (0.000)",           0, FF_OPT_TYPE_CONST, 7, INT_MIN, INT_MAX, AC3ENC_PARAM, "lorosurmixlev"},

dont float/double make more sense here?

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

Its not that you shouldnt use gotos but rather that you should write
readable code and code with gotos often but not always is less readable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101225/af5558f3/attachment.pgp>



More information about the ffmpeg-devel mailing list