switch (m4ac->object_type) {
case AOT_AAC_MAIN:
case AOT_AAC_LC:
+ case AOT_AAC_SSR:
case AOT_AAC_LTP:
case AOT_ER_AAC_LC:
case AOT_ER_AAC_LD:
reset_all_predictors(sce->predictor_state);
}
+static void decode_gain_control(SingleChannelElement * sce, GetBitContext * gb)
+{
+ // wd_num, wd_test, aloc_size
+ static const uint8_t gain_mode[4][3] = {
+ {1, 0, 5}, // ONLY_LONG_SEQUENCE = 0,
+ {2, 1, 2}, // LONG_START_SEQUENCE,
+ {8, 0, 2}, // EIGHT_SHORT_SEQUENCE,
+ {2, 1, 5}, // LONG_STOP_SEQUENCE
+ };
+
+ const int mode = sce->ics.window_sequence[0];
+ uint8_t bd, wd, ad;
+
+ // FIXME: Store the gain control data on |sce| and do something with it.
+ uint8_t max_band = get_bits(gb, 2);
+ for (bd = 0; bd < max_band; bd++) {
+ for (wd = 0; wd < gain_mode[mode][0]; wd++) {
+ uint8_t adjust_num = get_bits(gb, 3);
+ for (ad = 0; ad < adjust_num; ad++) {
+ skip_bits(gb, 4 + ((wd == 0 && gain_mode[mode][1])
+ ? 4
+ : gain_mode[mode][2]));
+ }
+ }
+ }
+}
+
/**
* Decode an individual_channel_stream payload; reference: table 4.44.
*
goto fail;
}
if (!eld_syntax && get_bits1(gb)) {
- avpriv_request_sample(ac->avctx, "SSR");
- ret = AVERROR_PATCHWELCOME;
- goto fail;
+ decode_gain_control(sce, gb);
+ if (!ac->warned_gain_control) {
+ avpriv_report_missing_feature(ac->avctx, "Gain control");
+ ac->warned_gain_control = 1;
+ }
}
// I see no textual basis in the spec for this occurring after SSR gain
// control, but this is what both reference and real implmentations do
int samples = 0, multiplier, audio_found = 0, pce_found = 0;
int is_dmono, sce_count = 0;
int payload_alignment;
+ uint8_t che_presence[4][MAX_ELEM_ID] = {{0}};
ac->frame = data;
}
if (elem_type < TYPE_DSE) {
+ if (che_presence[elem_type][elem_id]) {
+ av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d duplicate\n",
+ elem_type, elem_id);
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ che_presence[elem_type][elem_id] = 1;
+
if (!(che=get_che(ac, elem_type, elem_id))) {
av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
elem_type, elem_id);
AV_PKT_DATA_JP_DUALMONO,
&jp_dualmono_size);
- if (new_extradata && 0) {
- av_free(avctx->extradata);
- avctx->extradata = av_mallocz(new_extradata_size +
- AV_INPUT_BUFFER_PADDING_SIZE);
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
- avctx->extradata_size = new_extradata_size;
- memcpy(avctx->extradata, new_extradata, new_extradata_size);
- push_output_configuration(ac);
- if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
- avctx->extradata,
- avctx->extradata_size*8LL, 1) < 0) {
- pop_output_configuration(ac);
- return AVERROR_INVALIDDATA;
+ if (new_extradata) {
+ /* discard previous configuration */
+ ac->oc[1].status = OC_NONE;
+ err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
+ new_extradata,
+ new_extradata_size * 8LL, 1);
+ if (err < 0) {
+ return err;
}
}