FFmpeg
truehd_core_bsf.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 "avcodec.h"
22 #include "bsf.h"
23 #include "get_bits.h"
24 #include "mlp_parse.h"
25 #include "mlp.h"
26 
27 typedef struct AccessUnit {
29  uint16_t offset;
30  uint16_t optional;
31 } AccessUnit;
32 
33 typedef struct TrueHDCoreContext {
34  const AVClass *class;
35 
38 
40 {
42  GetBitContext gbc;
44  int ret, i, last_offset = 0;
45  int in_size, out_size;
46  int have_header = 0;
47  int substream_bytes = 0;
48  int end;
49 
51  if (ret < 0)
52  return ret;
53 
54  if (pkt->size < 4) {
56  goto fail;
57  }
58 
59  in_size = (AV_RB16(pkt->data) & 0xFFF) * 2;
60  if (in_size < 4 || in_size > pkt->size) {
62  goto fail;
63  }
64 
65  ret = init_get_bits8(&gbc, pkt->data + 4, pkt->size - 4);
66  if (ret < 0)
67  goto fail;
68 
69  if (show_bits_long(&gbc, 32) == 0xf8726fba) {
70  if ((ret = ff_mlp_read_major_sync(ctx, &s->hdr, &gbc)) < 0)
71  goto fail;
72  have_header = 1;
73  }
74 
75  if (s->hdr.num_substreams > MAX_SUBSTREAMS) {
77  goto fail;
78  }
79 
80  for (i = 0; i < s->hdr.num_substreams; i++) {
81  for (int j = 0; j < 4; j++)
82  units[i].bits[j] = get_bits1(&gbc);
83 
84  units[i].offset = get_bits(&gbc, 12);
85  if (i < 3) {
86  last_offset = units[i].offset * 2;
87  substream_bytes += 2;
88  }
89 
90  if (units[i].bits[0]) {
91  units[i].optional = get_bits(&gbc, 16);
92  if (i < 3)
93  substream_bytes += 2;
94  }
95  }
96  end = get_bits_count(&gbc) >> 3;
97 
98  out_size = end + 4 + last_offset;
99  if (out_size < in_size) {
100  int bpos = 0, reduce = end - have_header * 28 - substream_bytes;
101  uint16_t parity_nibble, dts = AV_RB16(pkt->data + 2);
102  uint16_t auheader;
103  uint8_t header[28];
104 
105  av_assert1(reduce >= 0 && reduce % 2 == 0);
106 
107  if (have_header) {
108  memcpy(header, pkt->data + 4, 28);
109  header[16] = (header[16] & 0x0c) | (FFMIN(s->hdr.num_substreams, 3) << 4);
110  header[17] &= 0x7f;
111  header[25] &= 0xfe;
113  }
114 
115  pkt->data += reduce;
116  out_size -= reduce;
117  pkt->size = out_size;
118 
120  if (ret < 0)
121  goto fail;
122 
123  AV_WB16(pkt->data + 2, dts);
124  parity_nibble = dts;
125  parity_nibble ^= out_size / 2;
126 
127  for (i = 0; i < FFMIN(s->hdr.num_substreams, 3); i++) {
128  uint16_t substr_hdr = 0;
129 
130  substr_hdr |= (units[i].bits[0] << 15);
131  substr_hdr |= (units[i].bits[1] << 14);
132  substr_hdr |= (units[i].bits[2] << 13);
133  substr_hdr |= (units[i].bits[3] << 12);
134  substr_hdr |= units[i].offset;
135 
136  AV_WB16(pkt->data + have_header * 28 + 4 + bpos, substr_hdr);
137 
138  parity_nibble ^= substr_hdr;
139  bpos += 2;
140 
141  if (units[i].bits[0]) {
142  AV_WB16(pkt->data + have_header * 28 + 4 + bpos, units[i].optional);
143 
144  parity_nibble ^= units[i].optional;
145  bpos += 2;
146  }
147  }
148 
149  parity_nibble ^= parity_nibble >> 8;
150  parity_nibble ^= parity_nibble >> 4;
151  parity_nibble &= 0xF;
152 
153  auheader = (parity_nibble ^ 0xF) << 12;
154  auheader |= (out_size / 2) & 0x0fff;
155  AV_WB16(pkt->data, auheader);
156 
157  if (have_header)
158  memcpy(pkt->data + 4, header, 28);
159  }
160 
161 fail:
162  if (ret < 0)
164 
165  return ret;
166 }
167 
169 {
171  memset(&s->hdr, 0, sizeof(s->hdr));
172 }
173 
174 static const enum AVCodecID codec_ids[] = {
176 };
177 
179  .name = "truehd_core",
180  .priv_data_size = sizeof(TrueHDCoreContext),
183  .codec_ids = codec_ids,
184 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
truehd_core_flush
static void truehd_core_flush(AVBSFContext *ctx)
Definition: truehd_core_bsf.c:168
show_bits_long
static unsigned int show_bits_long(GetBitContext *s, int n)
Show 0-32 bits.
Definition: get_bits.h:602
TrueHDCoreContext
Definition: truehd_core_bsf.c:33
AVBitStreamFilter::name
const char * name
Definition: avcodec.h:5813
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:219
out_size
int out_size
Definition: movenc.c:55
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
TrueHDCoreContext::hdr
MLPHeaderInfo hdr
Definition: truehd_core_bsf.c:36
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
AV_CODEC_ID_TRUEHD
@ AV_CODEC_ID_TRUEHD
Definition: avcodec.h:608
AVBSFContext
The bitstream filter state.
Definition: avcodec.h:5763
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
ff_mlp_checksum16
uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size)
Definition: mlp.c:85
bsf.h
fail
#define fail()
Definition: checkasm.h:120
GetBitContext
Definition: get_bits.h:61
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
s
#define s(width, name)
Definition: cbs_vp9.c:257
bits
uint8_t bits
Definition: vp3data.h:202
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
flush
static void flush(AVCodecContext *avctx)
Definition: aacdec_template.c:500
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
AccessUnit::optional
uint16_t optional
Definition: truehd_core_bsf.c:30
AVPacket::size
int size
Definition: avcodec.h:1478
truehd_core_filter
static int truehd_core_filter(AVBSFContext *ctx, AVPacket *pkt)
Definition: truehd_core_bsf.c:39
MAX_SUBSTREAMS
#define MAX_SUBSTREAMS
Maximum number of substreams that can be decoded.
Definition: mlp.h:48
header
static const uint8_t header[24]
Definition: sdr2.c:67
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
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:136
AccessUnit
Definition: truehd_core_bsf.c:27
mlp_parse.h
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: avcodec.h:216
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
ff_truehd_core_bsf
const AVBitStreamFilter ff_truehd_core_bsf
Definition: truehd_core_bsf.c:178
AccessUnit::offset
uint16_t offset
Definition: truehd_core_bsf.c:29
AccessUnit::bits
uint8_t bits[4]
Definition: truehd_core_bsf.c:28
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
MLPHeaderInfo
Definition: mlp_parse.h:26
uint8_t
uint8_t
Definition: audio_convert.c:194
avcodec.h
ret
ret
Definition: filter_design.txt:187
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AVBitStreamFilter
Definition: avcodec.h:5812
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: avpacket.c:682
mlp.h
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
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:239
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
codec_ids
static enum AVCodecID codec_ids[]
Definition: truehd_core_bsf.c:174
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1370
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:94