FFmpeg
truehd_core.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Paul B Mahol
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 "bsf.h"
22 #include "bsf_internal.h"
23 #include "get_bits.h"
24 #include "mlp_parse.h"
25 #include "mlp.h"
26 
27 typedef struct AccessUnit {
28  uint8_t bits[4];
29  uint16_t offset;
30  uint16_t optional;
31 } AccessUnit;
32 
33 typedef struct TrueHDCoreContext {
36 
38 {
40  GetBitContext gbc;
42  int ret, i, last_offset = 0;
43  int in_size, out_size;
44  int have_header = 0;
45  int substream_bytes = 0;
46  int end;
47 
49  if (ret < 0)
50  return ret;
51 
52  if (pkt->size < 4) {
54  goto fail;
55  }
56 
57  in_size = (AV_RB16(pkt->data) & 0xFFF) * 2;
58  if (in_size < 4 || in_size > pkt->size) {
60  goto fail;
61  }
62 
63  ret = init_get_bits8(&gbc, pkt->data + 4, pkt->size - 4);
64  if (ret < 0)
65  goto fail;
66 
67  if (show_bits_long(&gbc, 32) == 0xf8726fba) {
68  if ((ret = ff_mlp_read_major_sync(ctx, &s->hdr, &gbc)) < 0)
69  goto fail;
70  have_header = 1;
71  }
72 
73  if (s->hdr.num_substreams > MAX_SUBSTREAMS) {
75  goto fail;
76  }
77 
78  for (i = 0; i < s->hdr.num_substreams; i++) {
79  for (int j = 0; j < 4; j++)
80  units[i].bits[j] = get_bits1(&gbc);
81 
82  units[i].offset = get_bits(&gbc, 12);
83  if (i < 3) {
84  last_offset = units[i].offset * 2;
85  substream_bytes += 2;
86  }
87 
88  if (units[i].bits[0]) {
89  units[i].optional = get_bits(&gbc, 16);
90  if (i < 3)
91  substream_bytes += 2;
92  }
93  }
94  end = get_bits_count(&gbc) >> 3;
95 
96  out_size = end + 4 + last_offset;
97  if (out_size < in_size) {
98  int bpos = 0, reduce = end - have_header * 28 - substream_bytes;
99  uint16_t parity_nibble, dts = AV_RB16(pkt->data + 2);
100  uint16_t auheader;
101  uint8_t header[28];
102 
103  av_assert1(reduce >= 0 && reduce % 2 == 0);
104 
105  if (have_header) {
106  memcpy(header, pkt->data + 4, 28);
107  header[16] = (header[16] & 0x0c) | (FFMIN(s->hdr.num_substreams, 3) << 4);
108  header[17] &= 0x7f;
109  header[25] &= 0xfe;
111  }
112 
113  pkt->data += reduce;
114  out_size -= reduce;
115  pkt->size = out_size;
116 
118  if (ret < 0)
119  goto fail;
120 
121  AV_WB16(pkt->data + 2, dts);
122  parity_nibble = dts;
123  parity_nibble ^= out_size / 2;
124 
125  for (i = 0; i < FFMIN(s->hdr.num_substreams, 3); i++) {
126  uint16_t substr_hdr = 0;
127 
128  substr_hdr |= (units[i].bits[0] << 15);
129  substr_hdr |= (units[i].bits[1] << 14);
130  substr_hdr |= (units[i].bits[2] << 13);
131  substr_hdr |= (units[i].bits[3] << 12);
132  substr_hdr |= units[i].offset;
133 
134  AV_WB16(pkt->data + have_header * 28 + 4 + bpos, substr_hdr);
135 
136  parity_nibble ^= substr_hdr;
137  bpos += 2;
138 
139  if (units[i].bits[0]) {
140  AV_WB16(pkt->data + have_header * 28 + 4 + bpos, units[i].optional);
141 
142  parity_nibble ^= units[i].optional;
143  bpos += 2;
144  }
145  }
146 
147  parity_nibble ^= parity_nibble >> 8;
148  parity_nibble ^= parity_nibble >> 4;
149  parity_nibble &= 0xF;
150 
151  auheader = (parity_nibble ^ 0xF) << 12;
152  auheader |= (out_size / 2) & 0x0fff;
153  AV_WB16(pkt->data, auheader);
154 
155  if (have_header)
156  memcpy(pkt->data + 4, header, 28);
157  }
158 
159 fail:
160  if (ret < 0)
162 
163  return ret;
164 }
165 
167 {
169  memset(&s->hdr, 0, sizeof(s->hdr));
170 }
171 
172 static const enum AVCodecID codec_ids[] = {
174 };
175 
177  .p.name = "truehd_core",
178  .p.codec_ids = codec_ids,
179  .priv_data_size = sizeof(TrueHDCoreContext),
182 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:429
show_bits_long
static unsigned int show_bits_long(GetBitContext *s, int n)
Show 0-32 bits.
Definition: get_bits.h:495
bsf_internal.h
TrueHDCoreContext
Definition: truehd_core.c:33
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:266
out_size
int out_size
Definition: movenc.c:56
truehd_core_filter
static int truehd_core_filter(AVBSFContext *ctx, AVPacket *pkt)
Definition: truehd_core.c:37
AVPacket::data
uint8_t * data
Definition: packet.h:539
TrueHDCoreContext::hdr
MLPHeaderInfo hdr
Definition: truehd_core.c:34
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
codec_ids
static enum AVCodecID codec_ids[]
Definition: truehd_core.c:172
AV_CODEC_ID_TRUEHD
@ AV_CODEC_ID_TRUEHD
Definition: codec_id.h:490
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
ff_mlp_checksum16
uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size)
Definition: mlp.c:89
bsf.h
fail
#define fail()
Definition: checkasm.h:189
GetBitContext
Definition: get_bits.h:108
pkt
AVPacket * pkt
Definition: movenc.c:60
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:545
s
#define s(width, name)
Definition: cbs_vp9.c:198
bits
uint8_t bits
Definition: vp3data.h:128
ctx
AVFormatContext * ctx
Definition: movenc.c:49
get_bits.h
ff_truehd_core_bsf
const FFBitStreamFilter ff_truehd_core_bsf
Definition: truehd_core.c:176
FFBitStreamFilter
Definition: bsf_internal.h:27
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:388
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:370
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
AccessUnit::optional
uint16_t optional
Definition: truehd_core.c:30
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
AVPacket::size
int size
Definition: packet.h:540
truehd_core_flush
static void truehd_core_flush(AVBSFContext *ctx)
Definition: truehd_core.c:166
MAX_SUBSTREAMS
#define MAX_SUBSTREAMS
Maximum number of substreams that can be decoded.
Definition: mlp.h:51
header
static const uint8_t header[24]
Definition: sdr2.c:68
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:408
ff_mlp_read_major_sync
int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
Read a major sync info header - contains high level information about the stream - sample rate,...
Definition: mlp_parse.c:86
AccessUnit
Definition: truehd_core.c:27
mlp_parse.h
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AccessUnit::offset
uint16_t offset
Definition: truehd_core.c:29
AccessUnit::bits
uint8_t bits[4]
Definition: truehd_core.c:28
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
MLPHeaderInfo
Definition: mlp_parse.h:30
ret
ret
Definition: filter_design.txt:187
av_packet_make_writable
int av_packet_make_writable(AVPacket *pkt)
Create a writable reference for the data described by a given packet, avoiding data copy if possible.
Definition: packet.c:511
mlp.h
AVPacket
This structure stores compressed data.
Definition: packet.h:516
ff_bsf_get_packet_ref
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:256
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1328
AV_RB16
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:98