[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