diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-09-07 22:32:59 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-09-07 22:58:39 +0200 |
commit | f1b5693027d48a9e448f21595fb9247893c225cf (patch) | |
tree | d01e1b5a8a3abe464cd5be4d86122f0818b60132 | |
parent | a2b66a366d7d9d7dacc217601b5e4406624f91ea (diff) | |
parent | 0ca36b4de76e10578e23199c2932682c0f510e31 (diff) | |
download | ffmpeg-f1b5693027d48a9e448f21595fb9247893c225cf.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
Add LATM muxer
v210enc: clip values according to specifications
v210enc: switch to PIX_FMT_422P10
v210dec: switch to PIX_FMT_422P10
AVOptions: remove AVOption.offset <= 0 checks
AVOptions: deprecate av_opt_set_defaults2
AVOptions: move doxy for av_opt_set_defaults() from opt.c to opt.h
libx264: fix setting some more parameters
libx264: fix setting the H.264 level
libx264: add 'direct-pred' private option
libx264: add 'partitions' private option
Conflicts:
Changelog
libavcodec/Makefile
libavcodec/libx264.c
libavcodec/v210enc.c
libavfilter/src_movie.c
libavformat/version.h
libavutil/opt.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | doc/general.texi | 1 | ||||
-rw-r--r-- | libavcodec/Makefile | 1 | ||||
-rw-r--r-- | libavcodec/avcodec.h | 6 | ||||
-rw-r--r-- | libavcodec/libx264.c | 118 | ||||
-rw-r--r-- | libavcodec/options.c | 4 | ||||
-rw-r--r-- | libavcodec/v210enc.c | 2 | ||||
-rw-r--r-- | libavfilter/src_movie.c | 2 | ||||
-rw-r--r-- | libavfilter/vf_drawtext.c | 2 | ||||
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/allformats.c | 1 | ||||
-rw-r--r-- | libavformat/latmenc.c | 190 | ||||
-rw-r--r-- | libavformat/version.h | 2 | ||||
-rw-r--r-- | libavutil/avutil.h | 3 | ||||
-rw-r--r-- | libavutil/opt.c | 28 | ||||
-rw-r--r-- | libavutil/opt.h | 9 | ||||
-rw-r--r-- | tests/ref/lavf/ffm | 2 |
17 files changed, 297 insertions, 76 deletions
@@ -47,6 +47,7 @@ easier to use. The changes are: - ashowinfo filter added - Windows Media Image decoder - amovie source added +- LATM muxer version 0.8: diff --git a/doc/general.texi b/doc/general.texi index 51af16dfa7..d071ecdc08 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -118,6 +118,7 @@ library: @tab A format generated by IndigoVision 8000 video server. @item IVF (On2) @tab X @tab X @tab A format used by libvpx +@item LATM @tab X @tab X @item LMLM4 @tab @tab X @tab Used by Linux Media Labs MPEG-4 PCI boards @item LOAS @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index ac47c99aab..c9d57814aa 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -547,6 +547,7 @@ OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o vorbis_dat OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o OBJS-$(CONFIG_IFF_DEMUXER) += iff.o +OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o vorbis_data.o \ flacdec.o flacdata.o flac.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o mpegaudiodata.o diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fd9579e7b1..4ce084c574 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2520,14 +2520,13 @@ typedef struct AVCodecContext { * - decoding: unused */ attribute_deprecated int deblockbeta; -#endif /** * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 * - encoding: Set by user. * - decoding: unused */ - int partitions; + attribute_deprecated int partitions; #define X264_PART_I4X4 0x001 /* Analyze i4x4 */ #define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ #define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ @@ -2539,7 +2538,8 @@ typedef struct AVCodecContext { * - encoding: Set by user. * - decoding: unused */ - int directpred; + attribute_deprecated int directpred; +#endif /** * Audio cutoff bandwidth (0 means "automatic") diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index b6d2da8be1..4fd117f9ab 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -66,6 +66,8 @@ typedef struct X264Context { int mbtree; char *deblock; float cplxblur; + char *partitions; + int direct_pred; } X264Context; static void X264_log(void *p, int level, const char *fmt, va_list args) @@ -247,64 +249,19 @@ static av_cold int X264_init(AVCodecContext *avctx) x264_param_default(&x4->params); - x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC; - x4->params.i_bframe_adaptive = avctx->b_frame_strategy; - - x4->params.i_keyint_min = avctx->keyint_min; - if (x4->params.i_keyint_min > x4->params.i_keyint_max) - x4->params.i_keyint_min = x4->params.i_keyint_max; - x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER; - x4->params.analyse.inter = 0; - if (avctx->partitions) { - if (avctx->partitions & X264_PART_I4X4) - x4->params.analyse.inter |= X264_ANALYSE_I4x4; - if (avctx->partitions & X264_PART_I8X8) - x4->params.analyse.inter |= X264_ANALYSE_I8x8; - if (avctx->partitions & X264_PART_P8X8) - x4->params.analyse.inter |= X264_ANALYSE_PSUB16x16; - if (avctx->partitions & X264_PART_P4X4) - x4->params.analyse.inter |= X264_ANALYSE_PSUB8x8; - if (avctx->partitions & X264_PART_B8X8) - x4->params.analyse.inter |= X264_ANALYSE_BSUB16x16; - } - - x4->params.analyse.i_direct_mv_pred = avctx->directpred; - - if (avctx->me_method == ME_EPZS) - x4->params.analyse.i_me_method = X264_ME_DIA; - else if (avctx->me_method == ME_HEX) - x4->params.analyse.i_me_method = X264_ME_HEX; - else if (avctx->me_method == ME_UMH) - x4->params.analyse.i_me_method = X264_ME_UMH; - else if (avctx->me_method == ME_FULL) - x4->params.analyse.i_me_method = X264_ME_ESA; - else if (avctx->me_method == ME_TESA) - x4->params.analyse.i_me_method = X264_ME_TESA; - else x4->params.analyse.i_me_method = X264_ME_HEX; - - x4->params.analyse.i_me_range = avctx->me_range; - x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality; - - x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA; - - x4->params.analyse.i_trellis = avctx->trellis; - x4->params.analyse.i_noise_reduction = avctx->noise_reduction; - x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor); x4->params.rc.f_pb_factor = avctx->b_quant_factor; x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset; - - if (!x4->preset) - check_default_settings(avctx); - - if (x4->preset || x4->tune) { + if (x4->preset || x4->tune) if (x264_param_default_preset(&x4->params, x4->preset, x4->tune) < 0) { av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", x4->preset, x4->tune); return AVERROR(EINVAL); } - } + + if (avctx->level > 0) + x4->params.i_level_idc = avctx->level; x4->params.pf_log = X264_log; x4->params.p_log_private = avctx; @@ -387,6 +344,20 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.i_deblocking_filter_beta = avctx->deblockbeta; if (avctx->complexityblur >= 0) x4->params.rc.f_complexity_blur = avctx->complexityblur; + if (avctx->directpred >= 0) + x4->params.analyse.i_direct_mv_pred = avctx->directpred; + if (avctx->partitions) { + if (avctx->partitions & X264_PART_I4X4) + x4->params.analyse.inter |= X264_ANALYSE_I4x4; + if (avctx->partitions & X264_PART_I8X8) + x4->params.analyse.inter |= X264_ANALYSE_I8x8; + if (avctx->partitions & X264_PART_P8X8) + x4->params.analyse.inter |= X264_ANALYSE_PSUB16x16; + if (avctx->partitions & X264_PART_P4X4) + x4->params.analyse.inter |= X264_ANALYSE_PSUB8x8; + if (avctx->partitions & X264_PART_B8X8) + x4->params.analyse.inter |= X264_ANALYSE_BSUB16x16; + } x4->params.analyse.b_ssim = avctx->flags2 & CODEC_FLAG2_SSIM; x4->params.b_intra_refresh = avctx->flags2 & CODEC_FLAG2_INTRA_REFRESH; x4->params.i_bframe_pyramid = avctx->flags2 & CODEC_FLAG2_BPYRAMID ? X264_B_PYRAMID_NORMAL : X264_B_PYRAMID_NONE; @@ -399,6 +370,17 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.rc.b_mb_tree = !!(avctx->flags2 & CODEC_FLAG2_MBTREE); #endif + if (avctx->me_method == ME_EPZS) + x4->params.analyse.i_me_method = X264_ME_DIA; + else if (avctx->me_method == ME_HEX) + x4->params.analyse.i_me_method = X264_ME_HEX; + else if (avctx->me_method == ME_UMH) + x4->params.analyse.i_me_method = X264_ME_UMH; + else if (avctx->me_method == ME_FULL) + x4->params.analyse.i_me_method = X264_ME_ESA; + else if (avctx->me_method == ME_TESA) + x4->params.analyse.i_me_method = X264_ME_TESA; + if (avctx->gop_size >= 0) x4->params.i_keyint_max = avctx->gop_size; if (avctx->max_b_frames >= 0) @@ -417,6 +399,22 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.rc.f_qcompress = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */ if (avctx->refs >= 0) x4->params.i_frame_reference = avctx->refs; + if (avctx->trellis >= 0) + x4->params.analyse.i_trellis = avctx->trellis; + if (avctx->me_range >= 0) + x4->params.analyse.i_me_range = avctx->me_range; + if (avctx->noise_reduction >= 0) + x4->params.analyse.i_noise_reduction = avctx->noise_reduction; + if (avctx->me_subpel_quality >= 0) + x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality; + if (avctx->b_frame_strategy >= 0) + x4->params.i_bframe_adaptive = avctx->b_frame_strategy; + if (avctx->keyint_min >= 0) + x4->params.i_keyint_min = avctx->keyint_min; + if (avctx->coder_type >= 0) + x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC; + if (avctx->me_cmp >= 0) + x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA; if (x4->aq_mode >= 0) x4->params.rc.i_aq_mode = x4->aq_mode; @@ -424,6 +422,7 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.rc.f_aq_strength = x4->aq_strength; PARSE_X264_OPT("psy-rd", psy_rd); PARSE_X264_OPT("deblock", deblock); + PARSE_X264_OPT("partitions", partitions); if (x4->psy >= 0) x4->params.analyse.b_psy = x4->psy; if (x4->rc_lookahead >= 0) @@ -453,6 +452,8 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.b_aud = x4->aud; if (x4->mbtree >= 0) x4->params.rc.b_mb_tree = x4->mbtree; + if (x4->direct_pred >= 0) + x4->params.analyse.i_direct_mv_pred = x4->direct_pred; if (x4->fastfirstpass) x264_param_apply_fastfirstpass(&x4->params); @@ -516,9 +517,8 @@ static av_cold int X264_init(AVCodecContext *avctx) return 0; } -#define OFFSET(x) offsetof(X264Context,x) +#define OFFSET(x) offsetof(X264Context, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM - static const AVOption options[] = { { "preset", "Set the encoding preset (cf. x264 --fullhelp)", OFFSET(preset), FF_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE}, { "tune", "Tune the encoding params (cf. x264 --fullhelp)", OFFSET(tune), FF_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, @@ -558,6 +558,13 @@ static const AVOption options[] = { { "mbtree", "Use macroblock tree ratecontrol.", OFFSET(mbtree), FF_OPT_TYPE_INT, {-1 }, -1, 1, VE}, { "deblock", "Loop filter parameters, in <alpha:beta> form.", OFFSET(deblock), FF_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, { "cplxblur", "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), FF_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE}, + { "partitions", "A comma-separated list of partitions to consider. " + "Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all", OFFSET(partitions), FF_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, + { "direct-pred", "Direct MV prediction mode", OFFSET(direct_pred), FF_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE, "direct-pred" }, + { "none", NULL, 0, FF_OPT_TYPE_CONST, { X264_DIRECT_PRED_NONE }, 0, 0, VE, "direct-pred" }, + { "spatial", NULL, 0, FF_OPT_TYPE_CONST, { X264_DIRECT_PRED_SPATIAL }, 0, 0, VE, "direct-pred" }, + { "temporal", NULL, 0, FF_OPT_TYPE_CONST, { X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" }, + { "auto", NULL, 0, FF_OPT_TYPE_CONST, { X264_DIRECT_PRED_AUTO }, 0, 0, VE, "direct-pred" }, { NULL }, }; @@ -579,6 +586,15 @@ static const AVCodecDefault x264_defaults[] = { { "qcomp", "-1" }, { "refs", "-1" }, { "sc_threshold", "-1" }, + { "trellis", "-1" }, + { "nr", "-1" }, + { "me_range", "-1" }, + { "me_method", "-1" }, + { "subq", "-1" }, + { "b_strategy", "-1" }, + { "keyint_min", "-1" }, + { "coder", "-1" }, + { "cmp", "-1" }, { "threads", AV_STRINGIFY(X264_THREADS_AUTO) }, { NULL }, }; diff --git a/libavcodec/options.c b/libavcodec/options.c index 882d0d1c3a..c6965343b0 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -402,8 +402,8 @@ static const AVOption options[]={ {"bframebias", "influences how often B-frames are used", OFFSET(bframebias), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, #endif {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, -{"directpred", "direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)", OFFSET(directpred), FF_OPT_TYPE_INT, {.dbl = 2 }, INT_MIN, INT_MAX, V|E}, #if FF_API_X264_GLOBAL_OPTS +{"directpred", "direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)", OFFSET(directpred), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, V|E}, {"bpyramid", "allows B-frames to be used as references for predicting", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_BPYRAMID }, INT_MIN, INT_MAX, V|E, "flags2"}, {"wpred", "weighted biprediction for b-frames (H.264)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_WPRED }, INT_MIN, INT_MAX, V|E, "flags2"}, {"mixed_refs", "one reference per partition, as opposed to one reference per macroblock", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_MIXED_REFS }, INT_MIN, INT_MAX, V|E, "flags2"}, @@ -416,13 +416,13 @@ static const AVOption options[]={ {"complexityblur", "reduce fluctuations in qp (before curve compression)", OFFSET(complexityblur), FF_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, V|E}, {"deblockalpha", "in-loop deblocking filter alphac0 parameter", OFFSET(deblockalpha), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, -6, 6, V|E}, {"deblockbeta", "in-loop deblocking filter beta parameter", OFFSET(deblockbeta), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, -6, 6, V|E}, -#endif {"partitions", "macroblock subpartition sizes to consider", OFFSET(partitions), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "partitions"}, {"parti4x4", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_I4X4 }, INT_MIN, INT_MAX, V|E, "partitions"}, {"parti8x8", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_I8X8 }, INT_MIN, INT_MAX, V|E, "partitions"}, {"partp4x4", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_P4X4 }, INT_MIN, INT_MAX, V|E, "partitions"}, {"partp8x8", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_P8X8 }, INT_MIN, INT_MAX, V|E, "partitions"}, {"partb8x8", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_B8X8 }, INT_MIN, INT_MAX, V|E, "partitions"}, +#endif {"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), FF_OPT_TYPE_INT, {.dbl = 6 }, 0, INT_MAX, V|E}, {"mv0_threshold", NULL, OFFSET(mv0_threshold), FF_OPT_TYPE_INT, {.dbl = 256 }, 0, INT_MAX, V|E}, #if FF_API_MPEGVIDEO_GLOBAL_OPTS diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c index 1991c8ccfe..92577ef80f 100644 --- a/libavcodec/v210enc.c +++ b/libavcodec/v210enc.c @@ -124,6 +124,6 @@ AVCodec ff_v210_encoder = { .init = encode_init, .encode = encode_frame, .close = encode_close, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE}, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), }; diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c index 0f683db0b2..c266654536 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -97,7 +97,7 @@ static av_cold int movie_common_init(AVFilterContext *ctx, const char *args, voi int ret; movie->class = &movie_class; - av_opt_set_defaults2(movie, 0, 0); + av_opt_set_defaults(movie); if (args) movie->file_name = av_get_token(&args, ":"); diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 1ef8e69719..9ad74014e3 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -226,7 +226,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) Glyph *glyph; dtext->class = &drawtext_class; - av_opt_set_defaults2(dtext, 0, 0); + av_opt_set_defaults(dtext); dtext->fontcolor_string = av_strdup("black"); dtext->boxcolor_string = av_strdup("white"); dtext->shadowcolor_string = av_strdup("black"); diff --git a/libavformat/Makefile b/libavformat/Makefile index 59642d7489..87962233c3 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -112,6 +112,7 @@ OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o riff.o OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o +OBJS-$(CONFIG_LATM_MUXER) += latmenc.o OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index e3870a5cfe..5d0a48427a 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -113,6 +113,7 @@ void av_register_all(void) REGISTER_DEMUXER (IV8, iv8); REGISTER_MUXDEMUX (IVF, ivf); REGISTER_DEMUXER (JV, jv); + REGISTER_MUXER (LATM, latm); REGISTER_DEMUXER (LMLM4, lmlm4); REGISTER_DEMUXER (LOAS, loas); REGISTER_DEMUXER (LXF, lxf); diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c new file mode 100644 index 0000000000..8d67b5a615 --- /dev/null +++ b/libavformat/latmenc.c @@ -0,0 +1,190 @@ +/* + * LATM/LOAS muxer + * Copyright (c) 2011 Kieran Kunhya <kieran@kunhya.com> + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/get_bits.h" +#include "libavcodec/put_bits.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/mpeg4audio.h" +#include "libavutil/opt.h" +#include "avformat.h" + +typedef struct { + int off; + int channel_conf; + int object_type; + int counter; + int mod; +} LATMContext; + +static const AVOption options[] = { + {"smc-interval", "StreamMuxConfig interval.", + offsetof(LATMContext, mod), FF_OPT_TYPE_INT, {.dbl = 0x0014}, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, + {NULL}, +}; + +static const AVClass latm_muxer_class = { + .class_name = "LATM/LOAS muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static int latm_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) +{ + GetBitContext gb; + MPEG4AudioConfig m4ac; + + init_get_bits(&gb, buf, size * 8); + ctx->off = ff_mpeg4audio_get_config(&m4ac, buf, size); + if (ctx->off < 0) + return ctx->off; + skip_bits_long(&gb, ctx->off); + + /* FIXME: are any formats not allowed in LATM? */ + + if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) { + av_log(ctx, AV_LOG_ERROR, "Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type); + return AVERROR_INVALIDDATA; + } + ctx->channel_conf = m4ac.chan_config; + ctx->object_type = m4ac.object_type; + + return 0; +} + +static int latm_write_header(AVFormatContext *s) +{ + LATMContext *ctx = s->priv_data; + AVCodecContext *avctx = s->streams[0]->codec; + + if (avctx->extradata_size > 0 && + latm_decode_extradata(ctx, avctx->extradata, avctx->extradata_size) < 0) + return AVERROR_INVALIDDATA; + + return 0; +} + +static int latm_write_frame_header(AVFormatContext *s, PutBitContext *bs) +{ + LATMContext *ctx = s->priv_data; + AVCodecContext *avctx = s->streams[0]->codec; + GetBitContext gb; + int header_size; + + /* AudioMuxElement */ + put_bits(bs, 1, !!ctx->counter); + + if (!ctx->counter) { + init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); + + /* StreamMuxConfig */ + put_bits(bs, 1, 0); /* audioMuxVersion */ + put_bits(bs, 1, 1); /* allStreamsSameTimeFraming */ + put_bits(bs, 6, 0); /* numSubFrames */ + put_bits(bs, 4, 0); /* numProgram */ + put_bits(bs, 3, 0); /* numLayer */ + + /* AudioSpecificConfig */ + if (ctx->object_type == AOT_ALS) { + header_size = avctx->extradata_size-(ctx->off + 7) >> 3; + ff_copy_bits(bs, &avctx->extradata[ctx->off], header_size); + } else { + ff_copy_bits(bs, avctx->extradata, ctx->off + 3); + + if (!ctx->channel_conf) { + ff_copy_pce_data(bs, &gb); + } + } + + put_bits(bs, 3, 0); /* frameLengthType */ + put_bits(bs, 8, 0); /* latmBufferFullness */ + + put_bits(bs, 1, 0); /* otherDataPresent */ + put_bits(bs, 1, 0); /* crcCheckPresent */ + } + + ctx->counter++; + ctx->counter %= ctx->mod; + + return 0; +} + +static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + PutBitContext bs; + int i, len; + uint8_t loas_header[] = "\x56\xe0\x00"; + uint8_t *buf; + + if (pkt->size > 2 && pkt->data[0] == 0xff && (pkt->data[1] >> 4) == 0xf) { + av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n"); + return AVERROR_INVALIDDATA; + } + + buf = av_malloc(pkt->size+1024); + if (!buf) + return AVERROR(ENOMEM); + + init_put_bits(&bs, buf, pkt->size+1024); + + latm_write_frame_header(s, &bs); + + /* PayloadLengthInfo() */ + for (i = 0; i <= pkt->size-255; i+=255) + put_bits(&bs, 8, 255); + + put_bits(&bs, 8, pkt->size-i); + + /* The LATM payload is written unaligned */ + + /* PayloadMux() */ + for (i = 0; i < pkt->size; i++) + put_bits(&bs, 8, pkt->data[i]); + + align_put_bits(&bs); + flush_put_bits(&bs); + + len = put_bits_count(&bs) >> 3; + + loas_header[1] |= (len >> 8) & 0x1f; + loas_header[2] |= len & 0xff; + + avio_write(pb, loas_header, 3); + avio_write(pb, buf, len); + + av_free(buf); + + return 0; +} + +AVOutputFormat ff_latm_muxer = { + .name = "latm", + .long_name = NULL_IF_CONFIG_SMALL("LOAS/LATM"), + .mime_type = "audio/MP4A-LATM", + .extensions = "latm", + .priv_data_size = sizeof(LATMContext), + .audio_codec = CODEC_ID_AAC, + .video_codec = CODEC_ID_NONE, + .write_header = latm_write_header, + .write_packet = latm_write_packet, + .priv_class = &latm_muxer_class, +}; diff --git a/libavformat/version.h b/libavformat/version.h index d9e9f5c886..2e4e50a865 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 11 +#define LIBAVFORMAT_VERSION_MINOR 12 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 06c0470ce7..ef7a1459dc 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -69,6 +69,9 @@ #ifndef FF_API_AV_FIFO_PEEK #define FF_API_AV_FIFO_PEEK (LIBAVUTIL_VERSION_MAJOR < 52) #endif +#ifndef FF_API_OLD_AVOPTIONS +#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 52) +#endif /** * Return the LIBAVUTIL_VERSION_INT constant. diff --git a/libavutil/opt.c b/libavutil/opt.c index 43823690aa..2d4f873847 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -59,7 +59,7 @@ static int av_set_number2(void *obj, const char *name, double num, int den, int6 void *dst; if (o_out) *o_out= o; - if (!o || o->offset<=0) + if (!o) return AVERROR_OPTION_NOT_FOUND; if (o->max*den < num*intnum || o->min*den > num*intnum) { @@ -123,7 +123,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons *o_out = o; if (!o) return AVERROR_OPTION_NOT_FOUND; - if ((!val && o->type != FF_OPT_TYPE_STRING) || o->offset<=0) + if (!val && o->type != FF_OPT_TYPE_STRING) return AVERROR(EINVAL); if (o->type == FF_OPT_TYPE_BINARY) { @@ -233,7 +233,7 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c void *dst; uint8_t *bin; int len, i; - if (!o || o->offset<=0) + if (!o) return NULL; if (o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) return NULL; @@ -414,18 +414,21 @@ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) return 0; } -/** Set the values of the AVCodecContext or AVFormatContext structure. - * They are set to the defaults specified in the according AVOption options - * array default_val field. - * - * @param s AVCodecContext or AVFormatContext for which the defaults will be set - */ +void av_opt_set_defaults(void *s) +{ +#if FF_API_OLD_AVOPTIONS + av_opt_set_defaults2(s, 0, 0); +} + void av_opt_set_defaults2(void *s, int mask, int flags) { +#endif const AVOption *opt = NULL; while ((opt = av_next_option(s, opt)) != NULL) { +#if FF_API_OLD_AVOPTIONS if ((opt->flags & mask) != flags) continue; +#endif switch (opt->type) { case FF_OPT_TYPE_CONST: /* Nothing to be done here */ @@ -467,11 +470,6 @@ void av_opt_set_defaults2(void *s, int mask, int flags) } } -void av_opt_set_defaults(void *s) -{ - av_opt_set_defaults2(s, 0, 0); -} - /** * Store the value in the field in ctx that is named like key. * ctx must be an AVClass context, storing is done using AVOptions. @@ -656,7 +654,7 @@ int main(void) }; test_ctx.class = &test_class; - av_opt_set_defaults2(&test_ctx, 0, 0); + av_opt_set_defaults(&test_ctx); test_ctx.string = av_strdup("default"); av_log_set_level(AV_LOG_DEBUG); diff --git a/libavutil/opt.h b/libavutil/opt.h index efb4408f0d..95ce12c6a7 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -160,8 +160,17 @@ const AVOption *av_next_option(void *obj, const AVOption *last); */ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags); +/** + * Set the values of all AVOption fields to their default values. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + */ void av_opt_set_defaults(void *s); + +#if FF_API_OLD_AVOPTIONS +attribute_deprecated void av_opt_set_defaults2(void *s, int mask, int flags); +#endif /** * Parse the key/value pairs list in opts. For each key/value pair diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm index b20e132b45..f9a8f6740f 100644 --- a/tests/ref/lavf/ffm +++ b/tests/ref/lavf/ffm @@ -1,3 +1,3 @@ -f9bee27ea1b6b83a06b5f9efb0a4ac1f *./tests/data/lavf/lavf.ffm +58a0235967d10543268184eea50a3b65 *./tests/data/lavf/lavf.ffm 376832 ./tests/data/lavf/lavf.ffm ./tests/data/lavf/lavf.ffm CRC=0xf361ed74 |