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 "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 {
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  .name = "truehd_core",
178  .priv_data_size = sizeof(TrueHDCoreContext),
181  .codec_ids = codec_ids,
182 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
truehd_core_flush
static void truehd_core_flush(AVBSFContext *ctx)
Definition: truehd_core_bsf.c:166
show_bits_long
static unsigned int show_bits_long(GetBitContext *s, int n)
Show 0-32 bits.
Definition: get_bits.h:602
bsf_internal.h
TrueHDCoreContext
Definition: truehd_core_bsf.c:33
AVBitStreamFilter::name
const char * name
Definition: bsf.h:99
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:92
AVPacket::data
uint8_t * data
Definition: packet.h:355
TrueHDCoreContext::hdr
MLPHeaderInfo hdr
Definition: truehd_core_bsf.c:34
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: codec_id.h:454
AVBSFContext
The bitstream filter state.
Definition: bsf.h:49
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:123
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
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: codec_id.h:46
AccessUnit::optional
uint16_t optional
Definition: truehd_core_bsf.c:30
AVPacket::size
int size
Definition: packet.h:356
truehd_core_filter
static int truehd_core_filter(AVBSFContext *ctx, AVPacket *pkt)
Definition: truehd_core_bsf.c:37
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:86
AccessUnit
Definition: truehd_core_bsf.c:27
mlp_parse.h
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
ff_truehd_core_bsf
const AVBitStreamFilter ff_truehd_core_bsf
Definition: truehd_core_bsf.c:176
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
ret
ret
Definition: filter_design.txt:187
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AVBitStreamFilter
Definition: bsf.h:98
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:690
mlp.h
AVPacket
This structure stores compressed data.
Definition: packet.h:332
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:249
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:172
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1363
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