These two functions are always called after another; after all, what ff_dolby_e_parse_init does is obviously part of parsing the frame header. Also move the DolbyEHeaderInfo into DBEContext so that parsing the frame header only needs one struct (both users used a DBEContext immediately followed by a separate DolbyEHeaderInfo). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>tags/n4.4
| @@ -73,8 +73,6 @@ typedef struct DBEDecodeContext { | |||
| AVCodecContext *avctx; | |||
| DBEContext dectx; | |||
| DolbyEHeaderInfo metadata; | |||
| DBEChannel channels[MAX_SEGMENTS][MAX_CHANNELS]; | |||
| DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256]; | |||
| @@ -667,8 +665,8 @@ static int convert_input(DBEContext *s, int nb_words, int key) | |||
| static int parse_metadata_ext(DBEDecodeContext *s1) | |||
| { | |||
| DBEContext *s = &s1->dectx; | |||
| if (s1->metadata.mtd_ext_size) | |||
| return skip_input(s, s->key_present + s1->metadata.mtd_ext_size + 1); | |||
| if (s->metadata.mtd_ext_size) | |||
| return skip_input(s, s->key_present + s->metadata.mtd_ext_size + 1); | |||
| return 0; | |||
| } | |||
| @@ -830,7 +828,7 @@ static int parse_bit_alloc(DBEDecodeContext *s1, DBEChannel *c) | |||
| for (i = 0, p = NULL, g = c->groups; i < c->nb_groups; i++, p = g, g++) { | |||
| if (c->exp_strategy[i] || bap_strategy[i]) { | |||
| bit_allocate(g->nb_exponent, g->imdct_idx, s1->metadata.fr_code, | |||
| bit_allocate(g->nb_exponent, g->imdct_idx, s->metadata.fr_code, | |||
| c->exponents + g->exp_ofs, c->bap + g->exp_ofs, | |||
| fg_spc[i], fg_ofs[i], msk_mod[i], snr_ofs); | |||
| } else { | |||
| @@ -936,12 +934,12 @@ static int parse_channel(DBEDecodeContext *s1, int ch, int seg_id) | |||
| DBEChannel *c = &s1->channels[seg_id][ch]; | |||
| int i, ret; | |||
| if (s1->metadata.rev_id[ch] > 1) { | |||
| avpriv_report_missing_feature(s->avctx, "Encoder revision %d", s1->metadata.rev_id[ch]); | |||
| if (s->metadata.rev_id[ch] > 1) { | |||
| avpriv_report_missing_feature(s->avctx, "Encoder revision %d", s->metadata.rev_id[ch]); | |||
| return AVERROR_PATCHWELCOME; | |||
| } | |||
| if (ch == lfe_channel_tab[s1->metadata.prog_conf]) { | |||
| if (ch == lfe_channel_tab[s->metadata.prog_conf]) { | |||
| c->gr_code = 3; | |||
| c->bw_code = 29; | |||
| } else { | |||
| @@ -990,18 +988,18 @@ static int parse_audio(DBEDecodeContext *s1, int start, int end, int seg_id) | |||
| return key; | |||
| for (ch = start; ch < end; ch++) { | |||
| if (!s1->metadata.ch_size[ch]) { | |||
| if (!s->metadata.ch_size[ch]) { | |||
| s1->channels[seg_id][ch].nb_groups = 0; | |||
| continue; | |||
| } | |||
| if ((ret = convert_input(s, s1->metadata.ch_size[ch], key)) < 0) | |||
| if ((ret = convert_input(s, s->metadata.ch_size[ch], key)) < 0) | |||
| return ret; | |||
| if ((ret = parse_channel(s1, ch, seg_id)) < 0) { | |||
| if (s1->avctx->err_recognition & AV_EF_EXPLODE) | |||
| return ret; | |||
| s1->channels[seg_id][ch].nb_groups = 0; | |||
| } | |||
| if ((ret = skip_input(s, s1->metadata.ch_size[ch])) < 0) | |||
| if ((ret = skip_input(s, s->metadata.ch_size[ch])) < 0) | |||
| return ret; | |||
| } | |||
| @@ -1011,8 +1009,8 @@ static int parse_audio(DBEDecodeContext *s1, int start, int end, int seg_id) | |||
| static int parse_meter(DBEDecodeContext *s1) | |||
| { | |||
| DBEContext *s = &s1->dectx; | |||
| if (s1->metadata.meter_size) | |||
| return skip_input(s, s->key_present + s1->metadata.meter_size + 1); | |||
| if (s->metadata.meter_size) | |||
| return skip_input(s, s->key_present + s->metadata.meter_size + 1); | |||
| return 0; | |||
| } | |||
| @@ -1086,14 +1084,15 @@ static void apply_gain(DBEDecodeContext *s, int begin, int end, float *output) | |||
| static int filter_frame(DBEDecodeContext *s, AVFrame *frame) | |||
| { | |||
| const DolbyEHeaderInfo *const metadata = &s->dectx.metadata; | |||
| const uint8_t *reorder; | |||
| int ch, ret; | |||
| if (s->metadata.nb_channels == 4) | |||
| if (metadata->nb_channels == 4) | |||
| reorder = ch_reorder_4; | |||
| else if (s->metadata.nb_channels == 6) | |||
| else if (metadata->nb_channels == 6) | |||
| reorder = ch_reorder_6; | |||
| else if (s->metadata.nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) | |||
| else if (metadata->nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) | |||
| reorder = ch_reorder_8; | |||
| else | |||
| reorder = ch_reorder_n; | |||
| @@ -1102,11 +1101,11 @@ static int filter_frame(DBEDecodeContext *s, AVFrame *frame) | |||
| if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) | |||
| return ret; | |||
| for (ch = 0; ch < s->metadata.nb_channels; ch++) { | |||
| for (ch = 0; ch < metadata->nb_channels; ch++) { | |||
| float *output = (float *)frame->extended_data[reorder[ch]]; | |||
| transform(s, &s->channels[0][ch], s->history[ch], output); | |||
| transform(s, &s->channels[1][ch], s->history[ch], output + FRAME_SAMPLES / 2); | |||
| apply_gain(s, s->metadata.begin_gain[ch], s->metadata.end_gain[ch], output); | |||
| apply_gain(s, metadata->begin_gain[ch], metadata->end_gain[ch], output); | |||
| } | |||
| return 0; | |||
| @@ -1119,19 +1118,17 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, | |||
| DBEContext *s = &s1->dectx; | |||
| int i, j, ret; | |||
| if ((ret = ff_dolby_e_parse_init(s, avpkt->data, avpkt->size)) < 0) | |||
| return ret; | |||
| if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0) | |||
| if ((ret = ff_dolby_e_parse_header(s, avpkt->data, avpkt->size)) < 0) | |||
| return ret; | |||
| if (s1->metadata.nb_programs > 1 && !s1->metadata.multi_prog_warned) { | |||
| if (s->metadata.nb_programs > 1 && !s->metadata.multi_prog_warned) { | |||
| av_log(avctx, AV_LOG_WARNING, "Stream has %d programs (configuration %d), " | |||
| "channels will be output in native order.\n", s1->metadata.nb_programs, s1->metadata.prog_conf); | |||
| s1->metadata.multi_prog_warned = 1; | |||
| "channels will be output in native order.\n", | |||
| s->metadata.nb_programs, s->metadata.prog_conf); | |||
| s->metadata.multi_prog_warned = 1; | |||
| } | |||
| switch (s1->metadata.nb_channels) { | |||
| switch (s->metadata.nb_channels) { | |||
| case 4: | |||
| avctx->channel_layout = AV_CH_LAYOUT_4POINT0; | |||
| break; | |||
| @@ -1143,12 +1140,12 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, | |||
| break; | |||
| } | |||
| avctx->channels = s1->metadata.nb_channels; | |||
| avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code]; | |||
| avctx->channels = s->metadata.nb_channels; | |||
| avctx->sample_rate = sample_rate_tab[s->metadata.fr_code]; | |||
| avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; | |||
| i = s1->metadata.nb_channels / 2; | |||
| j = s1->metadata.nb_channels; | |||
| i = s->metadata.nb_channels / 2; | |||
| j = s->metadata.nb_channels; | |||
| if ((ret = parse_audio(s1, 0, i, 0)) < 0) | |||
| return ret; | |||
| if ((ret = parse_audio(s1, i, j, 0)) < 0) | |||
| @@ -1290,7 +1287,7 @@ static av_cold int dolby_e_init(AVCodecContext *avctx) | |||
| if (!(s->fdsp = avpriv_float_dsp_alloc(0))) | |||
| return AVERROR(ENOMEM); | |||
| s->metadata.multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE); | |||
| s->dectx.metadata.multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE); | |||
| s->dectx.avctx = s->avctx = avctx; | |||
| return 0; | |||
| } | |||
| @@ -30,24 +30,6 @@ | |||
| #define MAX_PROGRAMS 8 | |||
| #define MAX_CHANNELS 8 | |||
| /** | |||
| * @struct DBEContext | |||
| * Dolby E reading context used by decoder and parser. | |||
| */ | |||
| typedef struct DBEContext { | |||
| void *avctx; | |||
| GetBitContext gb; | |||
| const uint8_t *input; | |||
| int input_size; | |||
| int word_bits; | |||
| int word_bytes; | |||
| int key_present; | |||
| uint8_t buffer[1024 * 3 + AV_INPUT_BUFFER_PADDING_SIZE]; | |||
| } DBEContext; | |||
| /** | |||
| * @struct DolbyEHeaderInfo | |||
| * Coded Dolby E header values up to end_gain element, plus derived values. | |||
| @@ -79,26 +61,38 @@ typedef struct DolbyEHeaderInfo { | |||
| /** @} */ | |||
| } DolbyEHeaderInfo; | |||
| /** | |||
| * @struct DBEContext | |||
| * Dolby E reading context used by decoder and parser. | |||
| */ | |||
| typedef struct DBEContext { | |||
| void *avctx; | |||
| GetBitContext gb; | |||
| const uint8_t *input; | |||
| int input_size; | |||
| int word_bits; | |||
| int word_bytes; | |||
| int key_present; | |||
| DolbyEHeaderInfo metadata; | |||
| uint8_t buffer[1024 * 3 + AV_INPUT_BUFFER_PADDING_SIZE]; | |||
| } DBEContext; | |||
| static const uint16_t sample_rate_tab[16] = { | |||
| 0, 42965, 43008, 44800, 53706, 53760 | |||
| }; | |||
| /** | |||
| * Initialize DBEContext. | |||
| * Set word_bits/word_bytes, input, input_size, key_present. | |||
| * Initialize DBEContext and parse Dolby E metadata. | |||
| * Set word_bits/word_bytes, input, input_size, key_present | |||
| * and parse the header up to the end_gain element. | |||
| * @param[out] s DBEContext. | |||
| * @param[in] buf raw input buffer. | |||
| * @param[in] buf_size must be 3 bytes at least. | |||
| * @return Returns 0 on success, AVERROR_INVALIDDATA on error | |||
| */ | |||
| int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size); | |||
| /** | |||
| * Parse Dolby E metadata. | |||
| * Parse the header up to the end_gain element. | |||
| * @param[in] s DBEContext . | |||
| * @param[out] hdr Pointer to struct where header info is written. | |||
| * @return Returns 0 on success, AVERROR_INVALIDDATA on error | |||
| */ | |||
| int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr); | |||
| int ff_dolby_e_parse_header(DBEContext *s, const uint8_t *buf, int buf_size); | |||
| #endif | |||
| @@ -88,9 +88,10 @@ static int convert_input(DBEContext *s, int nb_words, int key) | |||
| return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits); | |||
| } | |||
| int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size) | |||
| int ff_dolby_e_parse_header(DBEContext *s, const uint8_t *buf, int buf_size) | |||
| { | |||
| int hdr; | |||
| DolbyEHeaderInfo *const header = &s->metadata; | |||
| int hdr, ret, key, mtd_size; | |||
| if (buf_size < 3) | |||
| return AVERROR_INVALIDDATA; | |||
| @@ -113,13 +114,6 @@ int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size) | |||
| s->input_size = buf_size / s->word_bytes - 1; | |||
| s->key_present = hdr >> 24 - s->word_bits & 1; | |||
| return 0; | |||
| } | |||
| int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr) | |||
| { | |||
| int i, ret, key, mtd_size; | |||
| if ((key = parse_key(s)) < 0) | |||
| return key; | |||
| if ((ret = convert_input(s, 1, key)) < 0) | |||
| @@ -137,37 +131,37 @@ int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr) | |||
| return ret; | |||
| skip_bits(&s->gb, 14); | |||
| hdr->prog_conf = get_bits(&s->gb, 6); | |||
| if (hdr->prog_conf > MAX_PROG_CONF) { | |||
| header->prog_conf = get_bits(&s->gb, 6); | |||
| if (header->prog_conf > MAX_PROG_CONF) { | |||
| if (s->avctx) | |||
| av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| hdr->nb_channels = nb_channels_tab[hdr->prog_conf]; | |||
| hdr->nb_programs = nb_programs_tab[hdr->prog_conf]; | |||
| header->nb_channels = nb_channels_tab[header->prog_conf]; | |||
| header->nb_programs = nb_programs_tab[header->prog_conf]; | |||
| hdr->fr_code = get_bits(&s->gb, 4); | |||
| hdr->fr_code_orig = get_bits(&s->gb, 4); | |||
| if (!sample_rate_tab[hdr->fr_code] || | |||
| !sample_rate_tab[hdr->fr_code_orig]) { | |||
| header->fr_code = get_bits(&s->gb, 4); | |||
| header->fr_code_orig = get_bits(&s->gb, 4); | |||
| if (!sample_rate_tab[header->fr_code] || | |||
| !sample_rate_tab[header->fr_code_orig]) { | |||
| if (s->avctx) | |||
| av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| skip_bits_long(&s->gb, 88); | |||
| for (i = 0; i < hdr->nb_channels; i++) | |||
| hdr->ch_size[i] = get_bits(&s->gb, 10); | |||
| hdr->mtd_ext_size = get_bits(&s->gb, 8); | |||
| hdr->meter_size = get_bits(&s->gb, 8); | |||
| skip_bits_long(&s->gb, 10 * hdr->nb_programs); | |||
| for (i = 0; i < hdr->nb_channels; i++) { | |||
| hdr->rev_id[i] = get_bits(&s->gb, 4); | |||
| for (int i = 0; i < header->nb_channels; i++) | |||
| header->ch_size[i] = get_bits(&s->gb, 10); | |||
| header->mtd_ext_size = get_bits(&s->gb, 8); | |||
| header->meter_size = get_bits(&s->gb, 8); | |||
| skip_bits_long(&s->gb, 10 * header->nb_programs); | |||
| for (int i = 0; i < header->nb_channels; i++) { | |||
| header->rev_id[i] = get_bits(&s->gb, 4); | |||
| skip_bits1(&s->gb); | |||
| hdr->begin_gain[i] = get_bits(&s->gb, 10); | |||
| hdr->end_gain[i] = get_bits(&s->gb, 10); | |||
| header->begin_gain[i] = get_bits(&s->gb, 10); | |||
| header->end_gain[i] = get_bits(&s->gb, 10); | |||
| } | |||
| if (get_bits_left(&s->gb) < 0) { | |||
| @@ -24,8 +24,6 @@ | |||
| typedef struct DBEParseContext { | |||
| DBEContext dectx; | |||
| DolbyEHeaderInfo metadata; | |||
| } DBEParseContext; | |||
| static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, | |||
| @@ -36,14 +34,11 @@ static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, | |||
| DBEContext *s = &s1->dectx; | |||
| int ret; | |||
| if ((ret = ff_dolby_e_parse_init(s, buf, buf_size)) < 0) | |||
| goto end; | |||
| if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0) | |||
| if ((ret = ff_dolby_e_parse_header(s, buf, buf_size)) < 0) | |||
| goto end; | |||
| s2->duration = FRAME_SAMPLES; | |||
| switch (s1->metadata.nb_channels) { | |||
| switch (s->metadata.nb_channels) { | |||
| case 4: | |||
| avctx->channel_layout = AV_CH_LAYOUT_4POINT0; | |||
| break; | |||
| @@ -55,8 +50,8 @@ static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, | |||
| break; | |||
| } | |||
| avctx->channels = s1->metadata.nb_channels; | |||
| avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code]; | |||
| avctx->channels = s->metadata.nb_channels; | |||
| avctx->sample_rate = sample_rate_tab[s->metadata.fr_code]; | |||
| avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; | |||
| end: | |||