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 "libavcodec/bsf.h"
23 #include "libavcodec/get_bits.h"
24 #include "libavcodec/mlp_parse.h"
25 #include "libavcodec/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 {
39  ctx->par_out->profile = AV_PROFILE_UNKNOWN;
40 
41  return 0;
42 }
43 
45 {
47  GetBitContext gbc;
49  int ret, i, last_offset = 0;
50  int in_size, out_size;
51  int have_header = 0;
52  int substream_bytes = 0;
53  int end;
54 
56  if (ret < 0)
57  return ret;
58 
59  if (pkt->size < 4) {
61  goto fail;
62  }
63 
64  in_size = (AV_RB16(pkt->data) & 0xFFF) * 2;
65  if (in_size < 4 || in_size > pkt->size) {
67  goto fail;
68  }
69 
70  ret = init_get_bits8(&gbc, pkt->data + 4, pkt->size - 4);
71  if (ret < 0)
72  goto fail;
73 
74  if (show_bits_long(&gbc, 32) == 0xf8726fba) {
75  if ((ret = ff_mlp_read_major_sync(ctx, &s->hdr, &gbc)) < 0)
76  goto fail;
77  have_header = 1;
78  }
79 
80  if (s->hdr.num_substreams > MAX_SUBSTREAMS) {
82  goto fail;
83  }
84 
85  for (i = 0; i < s->hdr.num_substreams; i++) {
86  for (int j = 0; j < 4; j++)
87  units[i].bits[j] = get_bits1(&gbc);
88 
89  units[i].offset = get_bits(&gbc, 12);
90  if (i < 3) {
91  last_offset = units[i].offset * 2;
92  substream_bytes += 2;
93  }
94 
95  if (units[i].bits[0]) {
96  units[i].optional = get_bits(&gbc, 16);
97  if (i < 3)
98  substream_bytes += 2;
99  }
100  }
101  end = get_bits_count(&gbc) >> 3;
102 
103  out_size = end + 4 + last_offset;
104  if (out_size < in_size) {
105  int bpos = 0, reduce = end - have_header * 28 - substream_bytes;
106  uint16_t parity_nibble, dts = AV_RB16(pkt->data + 2);
107  uint16_t auheader;
108  uint8_t header[28];
109 
110  av_assert1(reduce >= 0 && reduce % 2 == 0);
111 
112  if (have_header) {
113  memcpy(header, pkt->data + 4, 28);
114  header[16] = (header[16] & 0x0c) | (FFMIN(s->hdr.num_substreams, 3) << 4);
115  header[17] &= 0x7f;
116  header[25] &= 0xfe;
118  }
119 
120  pkt->data += reduce;
121  out_size -= reduce;
122  pkt->size = out_size;
123 
125  if (ret < 0)
126  goto fail;
127 
128  AV_WB16(pkt->data + 2, dts);
129  parity_nibble = dts;
130  parity_nibble ^= out_size / 2;
131 
132  for (i = 0; i < FFMIN(s->hdr.num_substreams, 3); i++) {
133  uint16_t substr_hdr = 0;
134 
135  substr_hdr |= (units[i].bits[0] << 15);
136  substr_hdr |= (units[i].bits[1] << 14);
137  substr_hdr |= (units[i].bits[2] << 13);
138  substr_hdr |= (units[i].bits[3] << 12);
139  substr_hdr |= units[i].offset;
140 
141  AV_WB16(pkt->data + have_header * 28 + 4 + bpos, substr_hdr);
142 
143  parity_nibble ^= substr_hdr;
144  bpos += 2;
145 
146  if (units[i].bits[0]) {
147  AV_WB16(pkt->data + have_header * 28 + 4 + bpos, units[i].optional);
148 
149  parity_nibble ^= units[i].optional;
150  bpos += 2;
151  }
152  }
153 
154  parity_nibble ^= parity_nibble >> 8;
155  parity_nibble ^= parity_nibble >> 4;
156  parity_nibble &= 0xF;
157 
158  auheader = (parity_nibble ^ 0xF) << 12;
159  auheader |= (out_size / 2) & 0x0fff;
160  AV_WB16(pkt->data, auheader);
161 
162  if (have_header)
163  memcpy(pkt->data + 4, header, 28);
164  }
165 
166 fail:
167  if (ret < 0)
169 
170  return ret;
171 }
172 
174 {
176  memset(&s->hdr, 0, sizeof(s->hdr));
177 }
178 
179 static const enum AVCodecID codec_ids[] = {
181 };
182 
184  .p.name = "truehd_core",
185  .p.codec_ids = codec_ids,
186  .priv_data_size = sizeof(TrueHDCoreContext),
190 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
show_bits_long
static unsigned int show_bits_long(GetBitContext *s, int n)
Show 0-32 bits.
Definition: get_bits.h:498
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:254
out_size
static int out_size
Definition: movenc.c:56
truehd_core_filter
static int truehd_core_filter(AVBSFContext *ctx, AVPacket *pkt)
Definition: truehd_core.c:44
AVPacket::data
uint8_t * data
Definition: packet.h:603
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:179
AV_CODEC_ID_TRUEHD
@ AV_CODEC_ID_TRUEHD
Definition: codec_id.h:497
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:337
ff_mlp_checksum16
uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size)
Definition: mlp.c:87
bsf.h
GetBitContext
Definition: get_bits.h:109
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:544
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
bits
uint8_t bits
Definition: vp3data.h:128
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
get_bits.h
fail
#define fail
Definition: test.h:478
ff_truehd_core_bsf
const FFBitStreamFilter ff_truehd_core_bsf
Definition: truehd_core.c:183
FFBitStreamFilter
Definition: bsf_internal.h:29
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:610
truehd_core_init
static int truehd_core_init(AVBSFContext *ctx)
Definition: truehd_core.c:37
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
AccessUnit::optional
uint16_t optional
Definition: truehd_core.c:30
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:33
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
AVPacket::size
int size
Definition: packet.h:604
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
truehd_core_flush
static void truehd_core_flush(AVBSFContext *ctx)
Definition: truehd_core.c:173
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:48
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:58
s
uint8_t s
Definition: llvidencdsp.c:39
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:516
mlp.h
AVPacket
This structure stores compressed data.
Definition: packet.h:580
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:254
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1361
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