FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/spdifenc.c
Date: 2026-09-16 18:55:35
Exec Total Coverage
Lines: 326 423 77.1%
Functions: 15 15 100.0%
Branches: 135 212 63.7%

Line Branch Exec Source
1 /*
2 * IEC 61937 muxer
3 * Copyright (c) 2009 Bartlomiej Wolowiec
4 * Copyright (c) 2010, 2020 Anssi Hannula
5 * Copyright (c) 2010 Carl Eugen Hoyos
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * @file
26 * IEC-61937 encapsulation of various formats, used by S/PDIF
27 * @author Bartlomiej Wolowiec
28 * @author Anssi Hannula
29 * @author Carl Eugen Hoyos
30 */
31
32 /*
33 * Terminology used in specification:
34 * data-burst - IEC61937 frame, contains header and encapsuled frame
35 * burst-preamble - IEC61937 frame header, contains 16-bit words named Pa, Pb, Pc and Pd
36 * burst-payload - encapsuled frame
37 * Pa, Pb - syncword - 0xF872, 0x4E1F
38 * Pc - burst-info, contains data-type (bits 0-6), error flag (bit 7), data-type-dependent info (bits 8-12)
39 * and bitstream number (bits 13-15)
40 * data-type - determines type of encapsuled frames
41 * Pd - length code (number of bits or bytes of encapsuled frame - according to data_type)
42 *
43 * IEC 61937 frames at normal usage start every specific count of bytes,
44 * dependent from data-type (spaces between packets are filled by zeros)
45 */
46
47 #include <inttypes.h>
48
49 #include "avformat.h"
50 #include "avio_internal.h"
51 #include "mux.h"
52 #include "spdif.h"
53 #include "libavcodec/ac3defs.h"
54 #include "libavcodec/adts_parser.h"
55 #include "libavcodec/dca.h"
56 #include "libavcodec/dca_syncwords.h"
57 #include "libavcodec/get_bits.h"
58 #include "libavutil/mem.h"
59 #include "libavutil/opt.h"
60
61 /*
62 * With padding up to MAT_FRAME_SIZE*2 allowed, TrueHD/MLP can complete two MAT
63 * buffers with one AVPacket. A third is needed for the active buffer, so no
64 * less than three are required. Since no more than one MAT can be written per
65 * AVPacket, extra headroom has been given.
66 *
67 * E-AC-3 and DTS-HD only need hd_buf[0].
68 */
69 #define HD_BUF_COUNT 6
70
71 typedef struct IEC61937Context {
72 const AVClass *av_class;
73 enum IEC61937DataType data_type;///< burst info - reference to type of payload of the data-burst
74 int length_code; ///< length code in bits or bytes, depending on data type
75 int pkt_offset; ///< data burst repetition period in bytes
76 uint8_t *buffer; ///< allocated buffer, used for swap bytes
77 int buffer_size; ///< size of allocated buffer
78
79 const uint8_t *out_buf; ///< pointer to the outgoing data before byte-swapping
80 int out_bytes; ///< amount of outgoing bytes
81
82 int use_preamble; ///< preamble enabled (disabled for exactly pre-padded DTS)
83 int extra_bswap; ///< extra bswap for payload (for LE DTS => standard BE DTS)
84
85 uint8_t *hd_buf[HD_BUF_COUNT]; ///< allocated buffers to concatenate hd audio frames
86 int hd_buf_size; ///< size of the hd audio buffer (eac3, dts4)
87 int hd_buf_count; ///< number of frames in the hd audio buffer (eac3)
88 int hd_buf_filled; ///< amount of bytes in the hd audio buffer (eac3, truehd)
89 int hd_buf_idx; ///< active hd buffer index (truehd)
90 int hd_buf_next_ready_idx; ///< oldest completed truehd MAT buffer ready to write (truehd)
91 int hd_buf_ready_count; ///< number of completed TrueHD MAT buffers ready to write (truehd)
92
93 int dtshd_skip; ///< counter used for skipping DTS-HD frames
94
95 uint16_t truehd_prev_time; ///< input_timing from the last frame
96 int truehd_prev_size; ///< previous frame size in bytes, including any MAT codes
97 int truehd_samples_per_frame; ///< samples per frame for padding calculation
98 uint16_t truehd_output_timing; ///< expected output_timing for truehd restart headers
99 int truehd_output_timing_valid; ///< restart header output_timing has been read
100 int truehd_oi_delta; ///< signed (output_timing-samples_per_frame)-input_timing
101
102 /* AVOptions: */
103 int dtshd_rate;
104 int dtshd_fallback;
105 #define SPDIF_FLAG_BIGENDIAN 0x01
106 int spdif_flags;
107
108 /// function, which generates codec dependent header information.
109 /// Sets data_type and pkt_offset, and length_code, out_bytes, out_buf if necessary
110 int (*header_info) (AVFormatContext *s, AVPacket *pkt);
111 } IEC61937Context;
112
113 static const AVOption options[] = {
114 { "spdif_flags", "IEC 61937 encapsulation flags", offsetof(IEC61937Context, spdif_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "spdif_flags" },
115 { "be", "output in big-endian format (for use as s16be)", 0, AV_OPT_TYPE_CONST, {.i64 = SPDIF_FLAG_BIGENDIAN}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "spdif_flags" },
116 { "dtshd_rate", "mux complete DTS frames in HD mode at the specified IEC958 rate (in Hz, default 0=disabled)", offsetof(IEC61937Context, dtshd_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 768000, AV_OPT_FLAG_ENCODING_PARAM },
117 { "dtshd_fallback_time", "min secs to strip HD for after an overflow (-1: till the end, default 60)", offsetof(IEC61937Context, dtshd_fallback), AV_OPT_TYPE_INT, {.i64 = 60}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
118 { NULL },
119 };
120
121 static const AVClass spdif_class = {
122 .class_name = "spdif",
123 .item_name = av_default_item_name,
124 .option = options,
125 .version = LIBAVUTIL_VERSION_INT,
126 };
127
128 56 static int spdif_header_ac3(AVFormatContext *s, AVPacket *pkt)
129 {
130 56 IEC61937Context *ctx = s->priv_data;
131 56 int bitstream_mode = pkt->data[5] & 0x7;
132
133 56 ctx->data_type = IEC61937_AC3 | (bitstream_mode << 8);
134 56 ctx->pkt_offset = AC3_FRAME_SIZE << 2;
135 56 return 0;
136 }
137
138 1304 static int spdif_header_eac3(AVFormatContext *s, AVPacket *pkt)
139 {
140 1304 IEC61937Context *ctx = s->priv_data;
141 static const uint8_t eac3_repeat[4] = {6, 3, 2, 1};
142 1304 int repeat = 1;
143 uint8_t *tmp;
144
145 1304 int bsid = pkt->data[5] >> 3;
146
3/4
✓ Branch 0 taken 1304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1302 times.
✓ Branch 3 taken 2 times.
1304 if (bsid > 10 && (pkt->data[4] & 0xc0) != 0xc0) /* fscod */
147 1302 repeat = eac3_repeat[(pkt->data[4] & 0x30) >> 4]; /* numblkscod */
148
149 1304 tmp = av_fast_realloc(ctx->hd_buf[0], &ctx->hd_buf_size, ctx->hd_buf_filled + pkt->size);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1304 times.
1304 if (!tmp)
151 return AVERROR(ENOMEM);
152 1304 ctx->hd_buf[0] = tmp;
153
154 1304 memcpy(&ctx->hd_buf[0][ctx->hd_buf_filled], pkt->data, pkt->size);
155
156 1304 ctx->hd_buf_filled += pkt->size;
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1304 times.
1304 if (++ctx->hd_buf_count < repeat){
158 ctx->pkt_offset = 0;
159 return 0;
160 }
161 1304 ctx->data_type = IEC61937_EAC3;
162 1304 ctx->pkt_offset = 24576;
163 1304 ctx->out_buf = ctx->hd_buf[0];
164 1304 ctx->out_bytes = ctx->hd_buf_filled;
165 1304 ctx->length_code = ctx->hd_buf_filled;
166
167 1304 ctx->hd_buf_count = 0;
168 1304 ctx->hd_buf_filled = 0;
169 1304 return 0;
170 }
171
172 /*
173 * DTS type IV (DTS-HD) can be transmitted with various frame repetition
174 * periods; longer repetition periods allow for longer packets and therefore
175 * higher bitrate. Longer repetition periods mean that the constant bitrate of
176 * the output IEC 61937 stream is higher.
177 * The repetition period is measured in IEC 60958 frames (4 bytes).
178 */
179 2344 static int spdif_dts4_subtype(int period)
180 {
181
2/7
✗ Branch 0 not taken.
✓ Branch 1 taken 1172 times.
✓ Branch 2 taken 1172 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
2344 switch (period) {
182 case 512: return 0x0;
183 1172 case 1024: return 0x1;
184 1172 case 2048: return 0x2;
185 case 4096: return 0x3;
186 case 8192: return 0x4;
187 case 16384: return 0x5;
188 }
189 return -1;
190 }
191
192 2344 static int spdif_header_dts4(AVFormatContext *s, AVPacket *pkt, int core_size,
193 int sample_rate, int blocks)
194 {
195 2344 IEC61937Context *ctx = s->priv_data;
196 static const char dtshd_start_code[10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe };
197 2344 int pkt_size = pkt->size;
198 int period;
199 int subtype;
200
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2344 times.
2344 if (!core_size) {
202 av_log(s, AV_LOG_ERROR, "HD mode not supported for this format\n");
203 return AVERROR(EINVAL);
204 }
205
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2344 times.
2344 if (!sample_rate) {
207 av_log(s, AV_LOG_ERROR, "Unknown DTS sample rate for HD\n");
208 return AVERROR_INVALIDDATA;
209 }
210
211 2344 period = ctx->dtshd_rate * (blocks << 5) / sample_rate;
212 2344 subtype = spdif_dts4_subtype(period);
213
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2344 times.
2344 if (subtype < 0) {
215 av_log(s, AV_LOG_ERROR, "Specified HD rate of %d Hz would require an "
216 "impossible repetition period of %d for the current DTS stream"
217 " (blocks = %d, sample rate = %d)\n", ctx->dtshd_rate, period,
218 blocks << 5, sample_rate);
219 return AVERROR(EINVAL);
220 }
221
222 /* set pkt_offset and DTS IV subtype according to the requested output
223 * rate */
224 2344 ctx->pkt_offset = period * 4;
225 2344 ctx->data_type = IEC61937_DTSHD | subtype << 8;
226
227 /* If the bitrate is too high for transmitting at the selected
228 * repetition period setting, strip DTS-HD until a good amount
229 * of consecutive non-overflowing HD frames have been observed.
230 * This generally only happens if the caller is cramming a Master
231 * Audio stream into 192kHz IEC 60958 (which may or may not fit). */
232 2344 if (sizeof(dtshd_start_code) + 2 + pkt_size
233
3/4
✓ Branch 0 taken 1069 times.
✓ Branch 1 taken 1275 times.
✓ Branch 2 taken 1069 times.
✗ Branch 3 not taken.
2344 > ctx->pkt_offset - BURST_HEADER_SIZE && core_size) {
234
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1068 times.
1069 if (!ctx->dtshd_skip)
235 1 av_log(s, AV_LOG_WARNING, "DTS-HD bitrate too high, "
236 "temporarily sending core only\n");
237
1/2
✓ Branch 0 taken 1069 times.
✗ Branch 1 not taken.
1069 if (ctx->dtshd_fallback > 0)
238 1069 ctx->dtshd_skip = sample_rate * ctx->dtshd_fallback / (blocks << 5);
239 else
240 /* skip permanently (dtshd_fallback == -1) or just once
241 * (dtshd_fallback == 0) */
242 ctx->dtshd_skip = 1;
243 }
244
4/6
✓ Branch 0 taken 1074 times.
✓ Branch 1 taken 1270 times.
✓ Branch 2 taken 1074 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1074 times.
✗ Branch 5 not taken.
2344 if (ctx->dtshd_skip && core_size && core_size <= pkt->size) {
245 1074 pkt_size = core_size;
246
1/2
✓ Branch 0 taken 1074 times.
✗ Branch 1 not taken.
1074 if (ctx->dtshd_fallback >= 0)
247 1074 --ctx->dtshd_skip;
248 }
249
250 2344 ctx->out_bytes = sizeof(dtshd_start_code) + 2 + pkt_size;
251
252 /* Align so that (length_code & 0xf) == 0x8. This is reportedly needed
253 * with some receivers, but the exact requirement is unconfirmed. */
254 2344 ctx->length_code = FFALIGN(ctx->out_bytes + 0x8, 0x10) - 0x8;
255
256 2344 av_fast_malloc(&ctx->hd_buf[0], &ctx->hd_buf_size, ctx->out_bytes);
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2344 times.
2344 if (!ctx->hd_buf[0])
258 return AVERROR(ENOMEM);
259
260 2344 ctx->out_buf = ctx->hd_buf[0];
261
262 2344 memcpy(ctx->hd_buf[0], dtshd_start_code, sizeof(dtshd_start_code));
263 2344 AV_WB16(ctx->hd_buf[0] + sizeof(dtshd_start_code), pkt_size);
264 2344 memcpy(ctx->hd_buf[0] + sizeof(dtshd_start_code) + 2, pkt->data, pkt_size);
265
266 2344 return 0;
267 }
268
269 3529 static int spdif_header_dts(AVFormatContext *s, AVPacket *pkt)
270 {
271 3529 IEC61937Context *ctx = s->priv_data;
272 3529 uint32_t syncword_dts = AV_RB32(pkt->data);
273 int blocks;
274 3529 int sample_rate = 0;
275 3529 int core_size = 0;
276
277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3529 times.
3529 if (pkt->size < 9)
278 return AVERROR_INVALIDDATA;
279
280
1/6
✓ Branch 0 taken 3529 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3529 switch (syncword_dts) {
281 3529 case DCA_SYNCWORD_CORE_BE:
282 3529 blocks = (AV_RB16(pkt->data + 4) >> 2) & 0x7f;
283 3529 core_size = ((AV_RB24(pkt->data + 5) >> 4) & 0x3fff) + 1;
284 3529 sample_rate = ff_dca_sample_rates[(pkt->data[8] >> 2) & 0x0f];
285 3529 break;
286 case DCA_SYNCWORD_CORE_LE:
287 blocks = (AV_RL16(pkt->data + 4) >> 2) & 0x7f;
288 ctx->extra_bswap = 1;
289 break;
290 case DCA_SYNCWORD_CORE_14B_BE:
291 blocks =
292 (((pkt->data[5] & 0x07) << 4) | ((pkt->data[6] & 0x3f) >> 2));
293 break;
294 case DCA_SYNCWORD_CORE_14B_LE:
295 blocks =
296 (((pkt->data[4] & 0x07) << 4) | ((pkt->data[7] & 0x3f) >> 2));
297 ctx->extra_bswap = 1;
298 break;
299 case DCA_SYNCWORD_SUBSTREAM:
300 /* We only handle HD frames that are paired with core. However,
301 sometimes DTS-HD streams with core have a stray HD frame without
302 core in the beginning of the stream. */
303 av_log(s, AV_LOG_ERROR, "stray DTS-HD frame\n");
304 return AVERROR_INVALIDDATA;
305 default:
306 av_log(s, AV_LOG_ERROR, "bad DTS syncword 0x%"PRIx32"\n", syncword_dts);
307 return AVERROR_INVALIDDATA;
308 }
309 3529 blocks++;
310
311
2/2
✓ Branch 0 taken 2344 times.
✓ Branch 1 taken 1185 times.
3529 if (ctx->dtshd_rate)
312 /* DTS type IV output requested */
313 2344 return spdif_header_dts4(s, pkt, core_size, sample_rate, blocks);
314
315
1/4
✓ Branch 0 taken 1185 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1185 switch (blocks) {
316 1185 case 512 >> 5: ctx->data_type = IEC61937_DTS1; break;
317 case 1024 >> 5: ctx->data_type = IEC61937_DTS2; break;
318 case 2048 >> 5: ctx->data_type = IEC61937_DTS3; break;
319 default:
320 av_log(s, AV_LOG_ERROR, "%i samples in DTS frame not supported\n",
321 blocks << 5);
322 return AVERROR(ENOSYS);
323 }
324
325 /* discard extraneous data by default */
326
3/4
✓ Branch 0 taken 1185 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1173 times.
✓ Branch 3 taken 12 times.
1185 if (core_size && core_size < pkt->size) {
327 1173 ctx->out_bytes = core_size;
328 1173 ctx->length_code = core_size << 3;
329 }
330
331 1185 ctx->pkt_offset = blocks << 7;
332
333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1185 times.
1185 if (ctx->out_bytes == ctx->pkt_offset) {
334 /* The DTS stream fits exactly into the output stream, so skip the
335 * preamble as it would not fit in there. This is the case for dts
336 * discs and dts-in-wav. */
337 ctx->use_preamble = 0;
338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1185 times.
1185 } else if (ctx->out_bytes > ctx->pkt_offset - BURST_HEADER_SIZE) {
339 avpriv_request_sample(s, "Unrecognized large DTS frame");
340 /* This will fail with a "bitrate too high" in the caller */
341 }
342
343 1185 return 0;
344 }
345
346 static const enum IEC61937DataType mpeg_data_type[2][3] = {
347 // LAYER1 LAYER2 LAYER3
348 { IEC61937_MPEG2_LAYER1_LSF, IEC61937_MPEG2_LAYER2_LSF, IEC61937_MPEG2_LAYER3_LSF }, // MPEG-2 LSF
349 { IEC61937_MPEG1_LAYER1, IEC61937_MPEG1_LAYER23, IEC61937_MPEG1_LAYER23 }, // MPEG-1
350 };
351
352 82 static int spdif_header_mpeg(AVFormatContext *s, AVPacket *pkt)
353 {
354 82 IEC61937Context *ctx = s->priv_data;
355 82 int version = (pkt->data[1] >> 3) & 3;
356 82 int layer = 3 - ((pkt->data[1] >> 1) & 3);
357 82 int extension = pkt->data[2] & 1;
358
359
2/4
✓ Branch 0 taken 82 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 82 times.
82 if (layer == 3 || version == 1) {
360 av_log(s, AV_LOG_ERROR, "Wrong MPEG file format\n");
361 return AVERROR_INVALIDDATA;
362 }
363 82 av_log(s, AV_LOG_DEBUG, "version: %i layer: %i extension: %i\n", version, layer, extension);
364
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
82 if (version == 2 && extension) {
365 ctx->data_type = IEC61937_MPEG2_EXT;
366 ctx->pkt_offset = 4608;
367 } else {
368 82 ctx->data_type = mpeg_data_type [version & 1][layer];
369 82 ctx->pkt_offset = spdif_mpeg_pkt_offset[version & 1][layer];
370 }
371 // TODO Data type dependent info (normal/karaoke, dynamic range control)
372 82 return 0;
373 }
374
375 86 static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt)
376 {
377 86 IEC61937Context *ctx = s->priv_data;
378 uint32_t samples;
379 uint8_t frames;
380 int ret;
381
382 86 ret = av_adts_header_parse(pkt->data, &samples, &frames);
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
86 if (ret < 0) {
384 av_log(s, AV_LOG_ERROR, "Wrong AAC file format\n");
385 return ret;
386 }
387
388 86 ctx->pkt_offset = samples << 2;
389
1/4
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
86 switch (frames) {
390 86 case 1:
391 86 ctx->data_type = IEC61937_MPEG2_AAC;
392 86 break;
393 case 2:
394 ctx->data_type = IEC61937_MPEG2_AAC_LSF_2048;
395 break;
396 case 4:
397 ctx->data_type = IEC61937_MPEG2_AAC_LSF_4096;
398 break;
399 default:
400 av_log(s, AV_LOG_ERROR,
401 "%"PRIu32" samples in AAC frame not supported\n", samples);
402 return AVERROR(EINVAL);
403 }
404 //TODO Data type dependent info (LC profile/SBR)
405 86 return 0;
406 }
407
408
409 /*
410 * It seems Dolby TrueHD frames have to be encapsulated in MAT frames before
411 * they can be encapsulated in IEC 61937.
412 */
413 #define MAT_PKT_OFFSET 61440
414 #define MAT_FRAME_SIZE 61424
415 #define TRUEHD_NOMINAL_AU_SPACING 2560
416
417 static const uint8_t mat_start_code[20] = {
418 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83,
419 0x49, 0x80, 0x77, 0xE0,
420 };
421 static const uint8_t mat_middle_code[12] = {
422 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0,
423 };
424 static const uint8_t mat_end_code[16] = {
425 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11,
426 };
427
428 #define MAT_CODE(position, data) { .pos = position, .code = data, .len = sizeof(data) }
429
430 static const struct {
431 unsigned int pos;
432 unsigned int len;
433 const uint8_t *code;
434 } mat_codes[] = {
435 MAT_CODE(0, mat_start_code),
436 MAT_CODE(30708, mat_middle_code),
437 MAT_CODE(MAT_FRAME_SIZE - sizeof(mat_end_code), mat_end_code),
438 };
439
440 /**
441 * Get the next index in the MAT buffer ring.
442 */
443 766 static int truehd_next_mat_buffer(int idx)
444 {
445 766 return (idx + 1) % HD_BUF_COUNT;
446 }
447
448 /**
449 * Mark the current MAT buffer ready and advance to the next free buffer.
450 */
451 383 static int truehd_enqueue_mat(AVFormatContext *s)
452 {
453 383 IEC61937Context *ctx = s->priv_data;
454
455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 383 times.
383 if (ctx->hd_buf_ready_count >= HD_BUF_COUNT - 1) {
456 av_log(s, AV_LOG_ERROR, "Too many completed TrueHD MAT frames pending\n");
457 return AVERROR(EINVAL);
458 }
459
460 383 ctx->hd_buf_ready_count++;
461 383 ctx->hd_buf_idx = truehd_next_mat_buffer(ctx->hd_buf_idx);
462 383 return 0;
463 }
464
465 typedef struct TrueHDAccessUnitInfo {
466 uint16_t input_timing;
467 uint16_t output_timing;
468 int has_output_timing;
469 int samples_per_frame;
470 } TrueHDAccessUnitInfo;
471
472 9135 static int truehd_parse_access_unit(const uint8_t *au_data, int au_size,
473 TrueHDAccessUnitInfo *au)
474 {
475 GetBitContext gb;
476 9135 int major_sync_size = 28;
477 int ratebits;
478 int num_substreams;
479 int sync_word;
480 int ret;
481 int i;
482 const uint8_t *data;
483 int size;
484
485 9135 memset(au, 0, sizeof(*au));
486
487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9135 times.
9135 if (au_size < 4)
488 return AVERROR_INVALIDDATA;
489
490 9135 data = au_data + 4;
491 9135 size = au_size - 4;
492
493 9135 au->input_timing = AV_RB16(au_data + 2);
494
495
3/4
✓ Branch 0 taken 9135 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8016 times.
✓ Branch 3 taken 1119 times.
9135 if (size < 6 || AV_RB24(data) != 0xf8726f)
496 8016 return 0;
497
498 /* major sync unit, fetch sample rate */
499
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1115 times.
1119 if (data[3] == 0xba)
500 4 ratebits = data[4] >> 4;
501
1/2
✓ Branch 0 taken 1115 times.
✗ Branch 1 not taken.
1115 else if (data[3] == 0xbb)
502 1115 ratebits = data[5] >> 4;
503 else
504 return AVERROR_INVALIDDATA;
505 1119 au->samples_per_frame = 40 << (ratebits & 3);
506
507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1119 times.
1119 if (size < 27)
508 return 0;
509
510
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1115 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
1119 if (data[3] == 0xba && data[25] & 1) {
511 1 int ext_size = data[26] >> 4;
512 1 major_sync_size += 2 + ext_size * 2;
513 }
514
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1119 times.
1119 if (major_sync_size > size)
516 return 0;
517
518 1119 ret = init_get_bits8(&gb, data + major_sync_size, size - major_sync_size);
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1119 times.
1119 if (ret < 0)
520 return ret;
521
522 1119 num_substreams = data[16] >> 4;
523
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1119 times.
1119 if (num_substreams <= 0)
524 return 0;
525
526
2/2
✓ Branch 0 taken 1122 times.
✓ Branch 1 taken 1119 times.
2241 for (i = 0; i < num_substreams; i++) {
527 int extra_word;
528
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1122 times.
1122 if (get_bits_left(&gb) < 16)
529 return 0;
530 1122 extra_word = get_bits1(&gb);
531 1122 skip_bits_long(&gb, 15);
532
1/2
✓ Branch 0 taken 1122 times.
✗ Branch 1 not taken.
1122 if (!extra_word)
533 1122 continue;
534 if (get_bits_left(&gb) < 16)
535 return 0;
536 skip_bits_long(&gb, 16);
537 }
538
539 /* output timing is always at least found in the first substream if it
540 * is present at all, so only walk the first substream.
541 */
542
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
1119 if (get_bits_left(&gb) < 1)
543 return 0;
544
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
1119 if (!get_bits1(&gb)) /* ! block_header_exists */
545 return 0;
546
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
1119 if (get_bits_left(&gb) < 1)
547 return 0;
548
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
1119 if (!get_bits1(&gb)) /* ! restart_header_exists */
549 return 0;
550
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
1119 if (get_bits_left(&gb) < 13 + 1 + 16)
551 return 0;
552
553 1119 sync_word = get_bits(&gb, 13);
554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1119 times.
1119 if (sync_word != (0x31ea >> 1))
555 return 0;
556 1119 skip_bits1(&gb); /* noise_type */
557
558 1119 au->output_timing = get_bits(&gb, 16);
559 1119 au->has_output_timing = 1;
560
561 1119 return 0;
562 }
563
564 9135 static int spdif_header_truehd(AVFormatContext *s, AVPacket *pkt)
565 {
566 9135 IEC61937Context *ctx = s->priv_data;
567 9135 uint8_t *hd_buf = ctx->hd_buf[ctx->hd_buf_idx];
568 TrueHDAccessUnitInfo au;
569 9135 int padding_remaining = 0;
570 9135 int max_padding_per_packet = MAT_FRAME_SIZE * 2;
571 9135 int output_discontinuity = 0;
572 uint16_t input_timing;
573 9135 int total_frame_size = pkt->size;
574 9135 const uint8_t *dataptr = pkt->data;
575 9135 int data_remaining = pkt->size;
576 9135 int have_pkt = 0;
577 int next_code_idx;
578 int ret;
579
580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9135 times.
9135 if (pkt->size < 10)
581 return AVERROR_INVALIDDATA;
582
583 9135 ret = truehd_parse_access_unit(pkt->data, pkt->size, &au);
584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9135 times.
9135 if (ret < 0)
585 return ret;
586
587
2/2
✓ Branch 0 taken 1119 times.
✓ Branch 1 taken 8016 times.
9135 if (au.samples_per_frame) {
588 1119 ctx->truehd_samples_per_frame = au.samples_per_frame;
589 1119 av_log(s, AV_LOG_TRACE, "TrueHD samples per frame: %d\n",
590 ctx->truehd_samples_per_frame);
591 }
592
593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9135 times.
9135 if (!ctx->truehd_samples_per_frame)
594 return AVERROR_INVALIDDATA;
595
596 9135 input_timing = au.input_timing;
597
598 9135 ctx->truehd_output_timing += ctx->truehd_samples_per_frame;
599
2/2
✓ Branch 0 taken 1119 times.
✓ Branch 1 taken 8016 times.
9135 if (au.has_output_timing) {
600
2/2
✓ Branch 0 taken 1116 times.
✓ Branch 1 taken 3 times.
1119 if (ctx->truehd_output_timing_valid &&
601
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1115 times.
1116 au.output_timing != ctx->truehd_output_timing) {
602 /*
603 * Each TrueHD access unit, output_timing increments by
604 * samples_per_frame, and input_timing nominally increments by the
605 * same amount. However if input_timing has fallen behind relative
606 * to output_timing at a discontinuity then additional padding can be
607 * added to preserve the correct MAT timing and IEC61937 carrier. So
608 * at the discontinuity compute padding based on the output-input
609 * timing delta relative to the new output-input delta. Negative or
610 * excessive padding will be ignored and logged.
611 *
612 * output_timing is always ahead by one frame period, so one period is
613 * always subtracted before comparison.
614 */
615 1 int bytes_per_sample = TRUEHD_NOMINAL_AU_SPACING /
616 1 ctx->truehd_samples_per_frame;
617 1 uint16_t output_timing_minus_spf = au.output_timing -
618 1 ctx->truehd_samples_per_frame;
619 1 int previous_oi_delta = ctx->truehd_oi_delta;
620 1 int current_oi_delta = (int16_t)(output_timing_minus_spf -
621 input_timing);
622 1 int prev_padding = 0;
623 1 int discontinuity_padding = 0;
624
625 1 output_discontinuity = 1;
626 1 discontinuity_padding = (previous_oi_delta - current_oi_delta) *
627 bytes_per_sample;
628
629
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ctx->truehd_prev_size)
630 1 prev_padding = TRUEHD_NOMINAL_AU_SPACING - ctx->truehd_prev_size;
631
632 1 padding_remaining = prev_padding + discontinuity_padding;
633
634
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (padding_remaining < 0 || padding_remaining > max_padding_per_packet) {
635 avpriv_request_sample(s,
636 "Unusual TrueHD output_timing discontinuity: "
637 "expected %"PRIu16" got %"PRIu16", "
638 "timing delta %d => %d, prev padding %d, "
639 "discontinuity padding %d, "
640 "total padding %d ignored",
641 ctx->truehd_output_timing, au.output_timing,
642 previous_oi_delta, current_oi_delta, prev_padding,
643 discontinuity_padding, padding_remaining);
644 padding_remaining = 0;
645 } else {
646 1 av_log(s, AV_LOG_VERBOSE,
647 "TrueHD output_timing discontinuity: "
648 "expected %"PRIu16" got %"PRIu16", "
649 "timing delta %d => %d, prev padding %d, "
650 "discontinuity padding %d, "
651 "total padding %d\n",
652 1 ctx->truehd_output_timing, au.output_timing,
653 previous_oi_delta, current_oi_delta, prev_padding,
654 discontinuity_padding, padding_remaining);
655 }
656 }
657
658 1119 ctx->truehd_output_timing = au.output_timing;
659 1119 ctx->truehd_output_timing_valid = 1;
660 }
661
662
4/4
✓ Branch 0 taken 9132 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 9131 times.
✓ Branch 3 taken 1 times.
9135 if (ctx->truehd_prev_size && !output_discontinuity) {
663 9131 uint16_t delta_samples = input_timing - ctx->truehd_prev_time;
664 /*
665 * One multiple-of-48kHz frame is 1/1200 sec and the IEC 61937 rate
666 * is 768kHz = 768000*4 bytes/sec.
667 * The nominal space per frame is therefore
668 * (768000*4 bytes/sec) * (1/1200 sec) = 2560 bytes.
669 * For multiple-of-44.1kHz frames: 1/1102.5 sec, 705.6kHz, 2560 bytes.
670 *
671 * 2560 is divisible by truehd_samples_per_frame.
672 */
673 9131 int delta_bytes = delta_samples * TRUEHD_NOMINAL_AU_SPACING /
674 9131 ctx->truehd_samples_per_frame;
675
676 /* padding needed before this frame */
677 9131 padding_remaining = delta_bytes - ctx->truehd_prev_size;
678
679 9131 av_log(s, AV_LOG_TRACE, "delta_samples: %"PRIu16", delta_bytes: %d\n",
680 delta_samples, delta_bytes);
681
682 /* sanity check */
683
2/4
✓ Branch 0 taken 9131 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9131 times.
9131 if (padding_remaining < 0 || padding_remaining > max_padding_per_packet) {
684 avpriv_request_sample(s, "Unusual frame timing: %"PRIu16" => %"PRIu16", %d samples/frame",
685 ctx->truehd_prev_time, input_timing, ctx->truehd_samples_per_frame);
686 padding_remaining = 0;
687 }
688 }
689
690
1/2
✓ Branch 0 taken 9135 times.
✗ Branch 1 not taken.
9135 if (ctx->truehd_output_timing_valid) {
691 9135 uint16_t output_timing_minus_spf = ctx->truehd_output_timing -
692 9135 ctx->truehd_samples_per_frame;
693 9135 ctx->truehd_oi_delta = (int16_t)(output_timing_minus_spf - input_timing);
694 }
695
696
1/2
✓ Branch 0 taken 22823 times.
✗ Branch 1 not taken.
22823 for (next_code_idx = 0; next_code_idx < FF_ARRAY_ELEMS(mat_codes); next_code_idx++)
697
2/2
✓ Branch 0 taken 9135 times.
✓ Branch 1 taken 13688 times.
22823 if (ctx->hd_buf_filled <= mat_codes[next_code_idx].pos)
698 9135 break;
699
700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9135 times.
9135 if (next_code_idx >= FF_ARRAY_ELEMS(mat_codes))
701 return AVERROR_BUG;
702
703
4/4
✓ Branch 0 taken 9908 times.
✓ Branch 1 taken 9512 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 9135 times.
19420 while (padding_remaining || data_remaining ||
704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9135 times.
9135 mat_codes[next_code_idx].pos == ctx->hd_buf_filled) {
705
706
2/2
✓ Branch 0 taken 1153 times.
✓ Branch 1 taken 9132 times.
10285 if (mat_codes[next_code_idx].pos == ctx->hd_buf_filled) {
707 /* time to insert MAT code */
708 1153 int code_len = mat_codes[next_code_idx].len;
709 1153 int code_len_remaining = code_len;
710 1153 memcpy(hd_buf + mat_codes[next_code_idx].pos,
711 1153 mat_codes[next_code_idx].code, code_len);
712 1153 ctx->hd_buf_filled += code_len;
713
714 1153 next_code_idx++;
715
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 770 times.
1153 if (next_code_idx == FF_ARRAY_ELEMS(mat_codes)) {
716 383 next_code_idx = 0;
717
718 /* this was the last code, move to the next MAT frame */
719 383 have_pkt = 1;
720 383 ret = truehd_enqueue_mat(s);
721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 383 times.
383 if (ret < 0)
722 return ret;
723
724 383 hd_buf = ctx->hd_buf[ctx->hd_buf_idx];
725 383 ctx->hd_buf_filled = 0;
726
727 /* inter-frame gap has to be counted as well, add it */
728 383 code_len_remaining += MAT_PKT_OFFSET - MAT_FRAME_SIZE;
729 }
730
731
2/2
✓ Branch 0 taken 776 times.
✓ Branch 1 taken 377 times.
1153 if (padding_remaining) {
732 /* consider the MAT code as padding */
733 776 int counted_as_padding = FFMIN(padding_remaining,
734 code_len_remaining);
735 776 padding_remaining -= counted_as_padding;
736 776 code_len_remaining -= counted_as_padding;
737 }
738 /* count the remainder of the code as part of frame size */
739
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 776 times.
1153 if (code_len_remaining)
740 377 total_frame_size += code_len_remaining;
741 }
742
743
2/2
✓ Branch 0 taken 9159 times.
✓ Branch 1 taken 1126 times.
10285 if (padding_remaining) {
744 9159 int padding_to_insert = FFMIN(mat_codes[next_code_idx].pos - ctx->hd_buf_filled,
745 padding_remaining);
746
747 9159 memset(hd_buf + ctx->hd_buf_filled, 0, padding_to_insert);
748 9159 ctx->hd_buf_filled += padding_to_insert;
749 9159 padding_remaining -= padding_to_insert;
750
751
2/2
✓ Branch 0 taken 776 times.
✓ Branch 1 taken 8383 times.
9159 if (padding_remaining)
752 776 continue; /* time to insert MAT code */
753 }
754
755
1/2
✓ Branch 0 taken 9509 times.
✗ Branch 1 not taken.
9509 if (data_remaining) {
756 9509 int data_to_insert = FFMIN(mat_codes[next_code_idx].pos - ctx->hd_buf_filled,
757 data_remaining);
758
759 9509 memcpy(hd_buf + ctx->hd_buf_filled, dataptr, data_to_insert);
760 9509 ctx->hd_buf_filled += data_to_insert;
761 9509 dataptr += data_to_insert;
762 9509 data_remaining -= data_to_insert;
763 }
764 }
765
766 9135 ctx->truehd_prev_size = total_frame_size;
767 9135 ctx->truehd_prev_time = input_timing;
768
769 9135 av_log(s, AV_LOG_TRACE, "TrueHD frame inserted, total size %d, buffer position %d\n",
770 total_frame_size, ctx->hd_buf_filled);
771
772
2/2
✓ Branch 0 taken 8754 times.
✓ Branch 1 taken 381 times.
9135 if (!have_pkt) {
773 8754 ctx->pkt_offset = 0;
774 8754 return 0;
775 }
776
777 381 return 0;
778 }
779
780 14 static int spdif_write_header(AVFormatContext *s)
781 {
782 14 IEC61937Context *ctx = s->priv_data;
783
784
6/7
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
14 switch (s->streams[0]->codecpar->codec_id) {
785 1 case AV_CODEC_ID_AC3:
786 1 ctx->header_info = spdif_header_ac3;
787 1 break;
788 2 case AV_CODEC_ID_EAC3:
789 2 ctx->header_info = spdif_header_eac3;
790 2 break;
791 2 case AV_CODEC_ID_MP1:
792 case AV_CODEC_ID_MP2:
793 case AV_CODEC_ID_MP3:
794 2 ctx->header_info = spdif_header_mpeg;
795 2 break;
796 5 case AV_CODEC_ID_DTS:
797 5 ctx->header_info = spdif_header_dts;
798 5 break;
799 1 case AV_CODEC_ID_AAC:
800 1 ctx->header_info = spdif_header_aac;
801 1 break;
802 3 case AV_CODEC_ID_TRUEHD:
803 case AV_CODEC_ID_MLP:
804 3 ctx->header_info = spdif_header_truehd;
805
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
21 for (int i = 0; i < FF_ARRAY_ELEMS(ctx->hd_buf); i++) {
806 18 ctx->hd_buf[i] = av_malloc(MAT_FRAME_SIZE);
807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (!ctx->hd_buf[i])
808 return AVERROR(ENOMEM);
809 }
810 3 break;
811 default:
812 avpriv_report_missing_feature(s, "Codec %d",
813 s->streams[0]->codecpar->codec_id);
814 return AVERROR_PATCHWELCOME;
815 }
816 14 return 0;
817 }
818
819 14 static void spdif_deinit(AVFormatContext *s)
820 {
821 14 IEC61937Context *ctx = s->priv_data;
822 14 av_freep(&ctx->buffer);
823
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 14 times.
98 for (int i = 0; i < FF_ARRAY_ELEMS(ctx->hd_buf); i++)
824 84 av_freep(&ctx->hd_buf[i]);
825 14 }
826
827 21802 static av_always_inline void spdif_put_16(IEC61937Context *ctx,
828 AVIOContext *pb, unsigned int val)
829 {
830
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 21778 times.
21802 if (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)
831 24 avio_wb16(pb, val);
832 else
833 21778 avio_wl16(pb, val);
834 21802 }
835
836 14192 static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
837 {
838 14192 IEC61937Context *ctx = s->priv_data;
839 int ret, padding;
840
841 14192 ctx->out_buf = pkt->data;
842 14192 ctx->out_bytes = pkt->size;
843 14192 ctx->length_code = FFALIGN(pkt->size, 2) << 3;
844 14192 ctx->use_preamble = 1;
845 14192 ctx->extra_bswap = 0;
846
847 14192 ret = ctx->header_info(s, pkt);
848
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14192 times.
14192 if (ret < 0)
849 return ret;
850
851
2/2
✓ Branch 0 taken 9135 times.
✓ Branch 1 taken 5057 times.
14192 if (ctx->header_info == spdif_header_truehd) {
852 /* TrueHD may complete more than one MAT buffer in one AVPacket. At
853 * most, write one completed buffer per AVPacket.
854 */
855 int ready_idx;
856
857
2/2
✓ Branch 0 taken 8752 times.
✓ Branch 1 taken 383 times.
9135 if (!ctx->hd_buf_ready_count)
858 8752 return 0;
859
860 383 ready_idx = ctx->hd_buf_next_ready_idx;
861 383 ctx->hd_buf_next_ready_idx = truehd_next_mat_buffer(ctx->hd_buf_next_ready_idx);
862 383 ctx->hd_buf_ready_count--;
863
864 383 ctx->out_buf = ctx->hd_buf[ready_idx];
865 383 ctx->out_bytes = MAT_FRAME_SIZE;
866 383 ctx->data_type = IEC61937_TRUEHD;
867 383 ctx->length_code = MAT_FRAME_SIZE;
868 383 ctx->pkt_offset = MAT_PKT_OFFSET;
869 }
870
871
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5440 times.
5440 if (!ctx->pkt_offset)
872 return 0;
873
874 5440 padding = (ctx->pkt_offset - ctx->use_preamble * BURST_HEADER_SIZE - ctx->out_bytes) & ~1;
875
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5440 times.
5440 if (padding < 0) {
876 av_log(s, AV_LOG_ERROR, "bitrate is too high\n");
877 return AVERROR(EINVAL);
878 }
879
880
1/2
✓ Branch 0 taken 5440 times.
✗ Branch 1 not taken.
5440 if (ctx->use_preamble) {
881 5440 spdif_put_16(ctx, s->pb, SYNCWORD1); //Pa
882 5440 spdif_put_16(ctx, s->pb, SYNCWORD2); //Pb
883 5440 spdif_put_16(ctx, s->pb, ctx->data_type); //Pc
884 5440 spdif_put_16(ctx, s->pb, ctx->length_code);//Pd
885 }
886
887
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5434 times.
5440 if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) {
888 6 avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
889 } else {
890 5434 av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + AV_INPUT_BUFFER_PADDING_SIZE);
891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5434 times.
5434 if (!ctx->buffer)
892 return AVERROR(ENOMEM);
893 5434 ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (const uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
894 5434 avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
895 }
896
897 /* a final lone byte has to be MSB aligned */
898
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 5398 times.
5440 if (ctx->out_bytes & 1)
899 42 spdif_put_16(ctx, s->pb, ctx->out_buf[ctx->out_bytes - 1] << 8);
900
901 5440 ffio_fill(s->pb, 0, padding);
902
903 5440 av_log(s, AV_LOG_DEBUG, "type=%x len=%i pkt_offset=%i\n",
904 5440 ctx->data_type, ctx->out_bytes, ctx->pkt_offset);
905
906 5440 return 0;
907 }
908
909 const FFOutputFormat ff_spdif_muxer = {
910 .p.name = "spdif",
911 .p.long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (used on S/PDIF - IEC958)"),
912 .p.extensions = "spdif",
913 .priv_data_size = sizeof(IEC61937Context),
914 .p.audio_codec = AV_CODEC_ID_AC3,
915 .p.video_codec = AV_CODEC_ID_NONE,
916 .p.subtitle_codec = AV_CODEC_ID_NONE,
917 .write_header = spdif_write_header,
918 .write_packet = spdif_write_packet,
919 .deinit = spdif_deinit,
920 .p.flags = AVFMT_NOTIMESTAMPS,
921 .p.priv_class = &spdif_class,
922 .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
923 };
924