aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-09-07 22:32:59 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-09-07 22:58:39 +0200
commitf1b5693027d48a9e448f21595fb9247893c225cf (patch)
treed01e1b5a8a3abe464cd5be4d86122f0818b60132
parenta2b66a366d7d9d7dacc217601b5e4406624f91ea (diff)
parent0ca36b4de76e10578e23199c2932682c0f510e31 (diff)
downloadffmpeg-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--Changelog1
-rw-r--r--doc/general.texi1
-rw-r--r--libavcodec/Makefile1
-rw-r--r--libavcodec/avcodec.h6
-rw-r--r--libavcodec/libx264.c118
-rw-r--r--libavcodec/options.c4
-rw-r--r--libavcodec/v210enc.c2
-rw-r--r--libavfilter/src_movie.c2
-rw-r--r--libavfilter/vf_drawtext.c2
-rw-r--r--libavformat/Makefile1
-rw-r--r--libavformat/allformats.c1
-rw-r--r--libavformat/latmenc.c190
-rw-r--r--libavformat/version.h2
-rw-r--r--libavutil/avutil.h3
-rw-r--r--libavutil/opt.c28
-rw-r--r--libavutil/opt.h9
-rw-r--r--tests/ref/lavf/ffm2
17 files changed, 297 insertions, 76 deletions
diff --git a/Changelog b/Changelog
index e9f594d3c4..9dab857fee 100644
--- a/Changelog
+++ b/Changelog
@@ -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