2 * Copyright (C) 2017 foo86
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #if CONFIG_DOLBY_E_PARSER | CONFIG_DOLBY_E_DECODER
27 #include "dolby_e_parser.h"
28 #include "dolby_e_parser_internal.h"
30 static int skip_input(DBEContext *s, int nb_words)
32 if (nb_words > s->input_size) {
33 return AVERROR_INVALIDDATA;
36 s->input += nb_words * s->word_bytes;
37 s->input_size -= nb_words;
41 static int parse_key(DBEContext *s)
44 const uint8_t *key = s->input;
45 int ret = skip_input(s, 1);
48 return AV_RB24(key) >> 24 - s->word_bits;
53 static int convert_input(DBEContext *s, int nb_words, int key)
55 const uint8_t *src = s->input;
56 uint8_t *dst = s->buffer;
60 av_assert0(nb_words <= 1024u);
62 if (nb_words > s->input_size) {
63 return AVERROR_INVALIDDATA;
66 switch (s->word_bits) {
68 for (i = 0; i < nb_words; i++, src += 2, dst += 2)
69 AV_WB16(dst, AV_RB16(src) ^ key);
72 init_put_bits(&pb, s->buffer, sizeof(s->buffer));
73 for (i = 0; i < nb_words; i++, src += 3)
74 put_bits(&pb, 20, AV_RB24(src) >> 4 ^ key);
78 for (i = 0; i < nb_words; i++, src += 3, dst += 3)
79 AV_WB24(dst, AV_RB24(src) ^ key);
85 return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits);
88 int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size)
93 return AVERROR_INVALIDDATA;
96 if ((hdr & 0xfffffe) == 0x7888e) {
98 } else if ((hdr & 0xffffe0) == 0x788e0) {
100 } else if ((hdr & 0xfffe00) == 0x78e00) {
104 av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n");
105 return AVERROR_INVALIDDATA;
108 s->word_bytes = s->word_bits + 7 >> 3;
109 s->input = buf + s->word_bytes;
110 s->input_size = buf_size / s->word_bytes - 1;
111 s->key_present = hdr >> 24 - s->word_bits & 1;
116 int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr)
118 int i, ret, key, mtd_size;
120 if ((key = parse_key(s)) < 0)
122 if ((ret = convert_input(s, 1, key)) < 0)
125 skip_bits(&s->gb, 4);
126 mtd_size = get_bits(&s->gb, 10);
129 av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n");
130 return AVERROR_INVALIDDATA;
133 if ((ret = convert_input(s, mtd_size, key)) < 0)
136 skip_bits(&s->gb, 14);
137 hdr->prog_conf = get_bits(&s->gb, 6);
138 if (hdr->prog_conf > MAX_PROG_CONF) {
140 av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n");
141 return AVERROR_INVALIDDATA;
144 hdr->nb_channels = nb_channels_tab[hdr->prog_conf];
145 hdr->nb_programs = nb_programs_tab[hdr->prog_conf];
147 hdr->fr_code = get_bits(&s->gb, 4);
148 hdr->fr_code_orig = get_bits(&s->gb, 4);
149 if (!sample_rate_tab[hdr->fr_code] ||
150 !sample_rate_tab[hdr->fr_code_orig]) {
152 av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n");
153 return AVERROR_INVALIDDATA;
156 skip_bits_long(&s->gb, 88);
157 for (i = 0; i < hdr->nb_channels; i++)
158 hdr->ch_size[i] = get_bits(&s->gb, 10);
159 hdr->mtd_ext_size = get_bits(&s->gb, 8);
160 hdr->meter_size = get_bits(&s->gb, 8);
162 skip_bits_long(&s->gb, 10 * hdr->nb_programs);
163 for (i = 0; i < hdr->nb_channels; i++) {
164 hdr->rev_id[i] = get_bits(&s->gb, 4);
166 hdr->begin_gain[i] = get_bits(&s->gb, 10);
167 hdr->end_gain[i] = get_bits(&s->gb, 10);
170 if (get_bits_left(&s->gb) < 0) {
172 av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n");
173 return AVERROR_INVALIDDATA;
176 return skip_input(s, mtd_size + 1);
178 #endif /* CONFIG_DOLBY_E_PARSER | CONFIG_DOLBY_E_DECODER */
180 #if CONFIG_DOLBY_E_PARSER
182 static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx,
183 const uint8_t **poutbuf, int *poutbuf_size,
184 const uint8_t *buf, int buf_size)
186 DBEParseContext *s1 = s2->priv_data;
187 DBEContext *s = &s1->dectx;
190 if ((ret = ff_dolby_e_parse_init(s, buf, buf_size)) < 0)
193 if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0)
196 s2->duration = FRAME_SAMPLES;
197 switch (s1->metadata.nb_channels) {
199 avctx->channel_layout = AV_CH_LAYOUT_4POINT0;
202 avctx->channel_layout = AV_CH_LAYOUT_5POINT1;
205 avctx->channel_layout = AV_CH_LAYOUT_7POINT1;
209 avctx->channels = s1->metadata.nb_channels;
210 avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code];
211 avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
214 /* always return the full packet. this parser isn't doing any splitting or
215 combining, only packet analysis */
217 *poutbuf_size = buf_size;
221 AVCodecParser ff_dolby_e_parser = {
222 .codec_ids = { AV_CODEC_ID_DOLBY_E },
223 .priv_data_size = sizeof(DBEParseContext),
224 .parser_parse = dolby_e_parse,
225 .parser_close = ff_parse_close,
227 #endif /* CONFIG_DOLBY_E_PARSER */