FFmpeg
Loading...
Searching...
No Matches
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"
25#include "libavcodec/mlp.h"
26
27typedef struct AccessUnit {
28 uint8_t bits[4];
29 uint16_t offset;
30 uint16_t optional;
32
36
38{
39 ctx->par_out->profile = AV_PROFILE_UNKNOWN;
40
41 return 0;
42}
43
45{
46 TrueHDCoreContext *s = ctx->priv_data;
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
166fail:
167 if (ret < 0)
169
170 return ret;
171}
172
174{
175 TrueHDCoreContext *s = ctx->priv_data;
176 memset(&s->hdr, 0, sizeof(s->hdr));
177}
178
179static 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};
static enum AVCodecID codec_ids[]
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
const FFBitStreamFilter ff_truehd_core_bsf
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition bsf.c:254
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
static AVPacket * pkt
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:610
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static const uint8_t bits[8]
Definition fastaudio.c:100
bitstream reader API header.
static unsigned int show_bits_long(GetBitContext *s, int n)
Show 0-32 bits.
Definition get_bits.h:498
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static int get_bits_count(const GetBitContext *s)
Definition get_bits.h:254
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
#define fail
Definition test.h:479
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_TRUEHD
Definition codec_id.h:497
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
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
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_WB16(p, v)
#define AV_WL16(p, v)
#define AV_RB16(p)
#define FFMIN(a, b)
Definition macros.h:49
uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size)
Definition mlp.c:87
#define MAX_SUBSTREAMS
Maximum number of substreams that can be decoded.
Definition mlp.h:51
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
static const uint8_t header[24]
Definition sdr2.c:68
The bitstream filter state.
Definition bsf.h:68
This structure stores compressed data.
Definition packet.h:580
uint16_t offset
Definition truehd_core.c:29
uint8_t bits[4]
Definition truehd_core.c:28
uint16_t optional
Definition truehd_core.c:30
MLPHeaderInfo hdr
Definition truehd_core.c:34
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
static int out_size
Definition movenc.c:56
static AVFormatContext * ctx
Definition movenc.c:49
static int truehd_core_init(AVBSFContext *ctx)
Definition truehd_core.c:37
static int truehd_core_filter(AVBSFContext *ctx, AVPacket *pkt)
Definition truehd_core.c:44
static void truehd_core_flush(AVBSFContext *ctx)