FFmpeg
dolby_e_parse.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 foo86
3  *
4  * This file is part of FFmpeg.
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include "get_bits.h"
22 #include "put_bits.h"
23 #include "dolby_e.h"
24 
25 static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = {
26  2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1
27 };
28 
29 static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = {
30  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8
31 };
32 
33 static const uint16_t sample_rate_tab[16] = {
34  0, 42965, 43008, 44800, 53706, 53760
35 };
36 
37 static int skip_input(DBEContext *s, int nb_words)
38 {
39  if (nb_words > s->input_size) {
40  return AVERROR_INVALIDDATA;
41  }
42 
43  s->input += nb_words * s->word_bytes;
44  s->input_size -= nb_words;
45  return 0;
46 }
47 
48 static int parse_key(DBEContext *s)
49 {
50  if (s->key_present) {
51  const uint8_t *key = s->input;
52  int ret = skip_input(s, 1);
53  if (ret < 0)
54  return ret;
55  return AV_RB24(key) >> 24 - s->word_bits;
56  }
57  return 0;
58 }
59 
60 int ff_dolby_e_convert_input(DBEContext *s, int nb_words, int key)
61 {
62  const uint8_t *src = s->input;
63  uint8_t *dst = s->buffer;
64  PutBitContext pb;
65  int i;
66 
67  av_assert0(nb_words <= 1024u);
68 
69  if (nb_words > s->input_size) {
70  if (s->avctx)
71  av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n");
72  return AVERROR_INVALIDDATA;
73  }
74 
75  switch (s->word_bits) {
76  case 16:
77  for (i = 0; i < nb_words; i++, src += 2, dst += 2)
78  AV_WB16(dst, AV_RB16(src) ^ key);
79  break;
80  case 20:
81  init_put_bits(&pb, s->buffer, sizeof(s->buffer));
82  for (i = 0; i < nb_words; i++, src += 3)
83  put_bits(&pb, 20, AV_RB24(src) >> 4 ^ key);
84  flush_put_bits(&pb);
85  break;
86  case 24:
87  for (i = 0; i < nb_words; i++, src += 3, dst += 3)
88  AV_WB24(dst, AV_RB24(src) ^ key);
89  break;
90  default:
91  av_assert0(0);
92  }
93 
94  return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits);
95 }
96 
97 int ff_dolby_e_parse_header(DBEContext *s, const uint8_t *buf, int buf_size)
98 {
99  DolbyEHeaderInfo *const header = &s->metadata;
100  int hdr, ret, key, mtd_size;
101 
102  if (buf_size < 3)
103  return AVERROR_INVALIDDATA;
104 
105  hdr = AV_RB24(buf);
106  if ((hdr & 0xfffffe) == 0x7888e) {
107  s->word_bits = 24;
108  } else if ((hdr & 0xffffe0) == 0x788e0) {
109  s->word_bits = 20;
110  } else if ((hdr & 0xfffe00) == 0x78e00) {
111  s->word_bits = 16;
112  } else {
113  if (s->avctx)
114  av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n");
115  return AVERROR_INVALIDDATA;
116  }
117 
118  s->word_bytes = s->word_bits + 7 >> 3;
119  s->input = buf + s->word_bytes;
120  s->input_size = buf_size / s->word_bytes - 1;
121  s->key_present = hdr >> 24 - s->word_bits & 1;
122 
123  if ((key = parse_key(s)) < 0)
124  return key;
125  if ((ret = ff_dolby_e_convert_input(s, 1, key)) < 0)
126  return ret;
127 
128  skip_bits(&s->gb, 4);
129  mtd_size = get_bits(&s->gb, 10);
130  if (!mtd_size) {
131  if (s->avctx)
132  av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n");
133  return AVERROR_INVALIDDATA;
134  }
135 
136  if ((ret = ff_dolby_e_convert_input(s, mtd_size, key)) < 0)
137  return ret;
138 
139  skip_bits(&s->gb, 14);
140  header->prog_conf = get_bits(&s->gb, 6);
141  if (header->prog_conf > MAX_PROG_CONF) {
142  if (s->avctx)
143  av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n");
144  return AVERROR_INVALIDDATA;
145  }
146 
147  header->nb_channels = nb_channels_tab[header->prog_conf];
148  header->nb_programs = nb_programs_tab[header->prog_conf];
149 
150  header->fr_code = get_bits(&s->gb, 4);
151  header->fr_code_orig = get_bits(&s->gb, 4);
152  if (!(header->sample_rate = sample_rate_tab[header->fr_code]) ||
153  !sample_rate_tab[header->fr_code_orig]) {
154  if (s->avctx)
155  av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n");
156  return AVERROR_INVALIDDATA;
157  }
158 
159  skip_bits_long(&s->gb, 88);
160  for (int i = 0; i < header->nb_channels; i++)
161  header->ch_size[i] = get_bits(&s->gb, 10);
162  header->mtd_ext_size = get_bits(&s->gb, 8);
163  header->meter_size = get_bits(&s->gb, 8);
164 
165  skip_bits_long(&s->gb, 10 * header->nb_programs);
166  for (int i = 0; i < header->nb_channels; i++) {
167  header->rev_id[i] = get_bits(&s->gb, 4);
168  skip_bits1(&s->gb);
169  header->begin_gain[i] = get_bits(&s->gb, 10);
170  header->end_gain[i] = get_bits(&s->gb, 10);
171  }
172 
173  if (get_bits_left(&s->gb) < 0) {
174  if (s->avctx)
175  av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n");
176  return AVERROR_INVALIDDATA;
177  }
178 
179  return skip_input(s, mtd_size + 1);
180 }
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static int parse_key(DBEContext *s)
Definition: dolby_e_parse.c:48
int ff_dolby_e_parse_header(DBEContext *s, const uint8_t *buf, int buf_size)
Initialize DBEContext and parse Dolby E metadata.
Definition: dolby_e_parse.c:97
Dolby E reading context used by decoder and parser.
Definition: dolby_e.h:70
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:218
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
int end_gain[MAX_CHANNELS]
Definition: dolby_e.h:54
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:291
const char * key
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:91
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
uint8_t buffer[1024 *3+AV_INPUT_BUFFER_PADDING_SIZE]
Definition: dolby_e.h:83
DolbyEHeaderInfo metadata
Definition: dolby_e.h:81
int ff_dolby_e_convert_input(DBEContext *s, int nb_words, int key)
Use the provided key to transform the input into data (put into s->buffer) suitable for further proce...
Definition: dolby_e_parse.c:60
GetBitContext gb
Definition: dolby_e.h:72
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
const uint8_t * input
Definition: dolby_e.h:74
bitstream reader API header.
static const uint8_t header[24]
Definition: sdr2.c:67
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
#define av_log(a,...)
int key_present
Definition: dolby_e.h:79
#define src
Definition: vp8dsp.c:255
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
int fr_code_orig
Definition: dolby_e.h:46
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
static const uint16_t sample_rate_tab[16]
Definition: dolby_e_parse.c:33
#define MAX_PROG_CONF
Definition: dolby_e.h:29
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
#define s(width, name)
Definition: cbs_vp9.c:257
int word_bytes
Definition: dolby_e.h:78
int mtd_ext_size
Definition: dolby_e.h:49
int input_size
Definition: dolby_e.h:75
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:91
static int skip_input(DBEContext *s, int nb_words)
Definition: dolby_e_parse.c:37
static const uint8_t nb_channels_tab[MAX_PROG_CONF+1]
Definition: dolby_e_parse.c:29
static void skip_bits1(GetBitContext *s)
Definition: get_bits.h:538
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
int rev_id[MAX_CHANNELS]
Definition: dolby_e.h:52
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:117
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:64
int ch_size[MAX_CHANNELS]
Definition: dolby_e.h:48
static const uint8_t nb_programs_tab[MAX_PROG_CONF+1]
Definition: dolby_e_parse.c:25
Coded Dolby E header values up to end_gain element, plus derived values.
Definition: dolby_e.h:37
int begin_gain[MAX_CHANNELS]
Definition: dolby_e.h:53
int word_bits
Definition: dolby_e.h:77
int i
Definition: input.c:407
void * avctx
Definition: dolby_e.h:71
bitstream writer API