FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/matroskaenc.c
Date: 2023-10-02 11:06:47
Exec Total Coverage
Lines: 1602 1845 86.8%
Functions: 96 96 100.0%
Branches: 884 1175 75.2%

Line Branch Exec Source
1 /*
2 * Matroska muxer
3 * Copyright (c) 2007 David Conrad
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <stdint.h>
23
24 #include "config_components.h"
25
26 #include "av1.h"
27 #include "avc.h"
28 #include "hevc.h"
29 #include "avformat.h"
30 #include "avio_internal.h"
31 #include "avlanguage.h"
32 #include "dovi_isom.h"
33 #include "flacenc.h"
34 #include "internal.h"
35 #include "isom.h"
36 #include "matroska.h"
37 #include "mux.h"
38 #include "riff.h"
39 #include "version.h"
40 #include "vorbiscomment.h"
41 #include "wv.h"
42
43 #include "libavutil/avstring.h"
44 #include "libavutil/channel_layout.h"
45 #include "libavutil/crc.h"
46 #include "libavutil/dict.h"
47 #include "libavutil/hdr_dynamic_metadata.h"
48 #include "libavutil/intfloat.h"
49 #include "libavutil/intreadwrite.h"
50 #include "libavutil/lfg.h"
51 #include "libavutil/mastering_display_metadata.h"
52 #include "libavutil/mathematics.h"
53 #include "libavutil/opt.h"
54 #include "libavutil/parseutils.h"
55 #include "libavutil/pixdesc.h"
56 #include "libavutil/random_seed.h"
57 #include "libavutil/rational.h"
58 #include "libavutil/samplefmt.h"
59 #include "libavutil/stereo3d.h"
60
61 #include "libavcodec/av1.h"
62 #include "libavcodec/bytestream.h"
63 #include "libavcodec/codec_desc.h"
64 #include "libavcodec/codec_par.h"
65 #include "libavcodec/defs.h"
66 #include "libavcodec/xiph.h"
67 #include "libavcodec/mpeg4audio.h"
68
69 /* Level 1 elements we create a SeekHead entry for:
70 * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */
71 #define MAX_SEEKHEAD_ENTRIES 7
72
73 /* Largest known-length EBML length */
74 #define MAX_EBML_LENGTH ((1ULL << 56) - 2)
75 /* The dynamic buffer API we rely upon has a limit of INT_MAX;
76 * and so has avio_write(). */
77 #define MAX_SUPPORTED_EBML_LENGTH FFMIN(MAX_EBML_LENGTH, INT_MAX)
78
79 #define MODE_MATROSKAv2 0x01
80 #define MODE_WEBM 0x02
81
82 #define IS_WEBM(mkv) (CONFIG_WEBM_MUXER && CONFIG_MATROSKA_MUXER ? \
83 ((mkv)->mode == MODE_WEBM) : CONFIG_WEBM_MUXER)
84 #define IS_SEEKABLE(pb, mkv) (((pb)->seekable & AVIO_SEEKABLE_NORMAL) && \
85 !(mkv)->is_live)
86
87 enum {
88 DEFAULT_MODE_INFER,
89 DEFAULT_MODE_INFER_NO_SUBS,
90 DEFAULT_MODE_PASSTHROUGH,
91 };
92
93 typedef struct ebml_master {
94 int64_t pos; ///< absolute offset in the containing AVIOContext where the master's elements start
95 int sizebytes; ///< how many bytes were reserved for the size
96 } ebml_master;
97
98 typedef struct ebml_stored_master {
99 AVIOContext *bc;
100 int64_t pos;
101 } ebml_stored_master;
102
103 typedef enum EbmlType {
104 EBML_UINT,
105 EBML_SINT,
106 EBML_FLOAT,
107 EBML_UID,
108 EBML_STR,
109 EBML_UTF8 = EBML_STR,
110 EBML_BIN,
111 EBML_BLOCK, ///< pseudo-type for writing (Simple)Blocks
112 EBML_MASTER,
113 } EbmlType;
114
115 typedef struct BlockContext {
116 struct mkv_track *track;
117 const AVPacket *pkt;
118 int16_t rel_ts;
119 uint8_t flags;
120 NALUList h2645_nalu_list;
121 } BlockContext;
122
123 typedef struct EbmlMaster {
124 int nb_elements; ///< -1 if not finished
125 int containing_master; ///< -1 if no parent exists
126 } EbmlMaster;
127
128 typedef struct EbmlElement {
129 uint32_t id;
130 EbmlType type;
131 unsigned length_size;
132 uint64_t size; ///< excluding id and length field
133 union {
134 uint64_t uint;
135 int64_t sint;
136 double f;
137 const char *str;
138 const uint8_t *bin;
139 struct MatroskaMuxContext *mkv; ///< used by EBML_BLOCK
140 EbmlMaster master;
141 } priv;
142 } EbmlElement;
143
144 typedef struct EbmlWriter {
145 unsigned nb_elements;
146 int current_master_element;
147 EbmlElement *elements;
148 } EbmlWriter;
149
150 #define EBML_WRITER(max_nb_elems) \
151 EbmlElement elements[max_nb_elems]; \
152 EbmlWriter writer = (EbmlWriter){ .elements = elements, \
153 .current_master_element = -1 }
154
155 typedef struct mkv_seekhead_entry {
156 uint32_t elementid;
157 uint64_t segmentpos;
158 } mkv_seekhead_entry;
159
160 typedef struct mkv_seekhead {
161 int64_t filepos;
162 mkv_seekhead_entry entries[MAX_SEEKHEAD_ENTRIES];
163 int num_entries;
164 int reserved_size;
165 } mkv_seekhead;
166
167 typedef struct mkv_cuepoint {
168 uint64_t pts;
169 int stream_idx;
170 int64_t cluster_pos; ///< offset of the cluster containing the block relative to the segment
171 int64_t relative_pos; ///< relative offset from the position of the cluster containing the block
172 int64_t duration; ///< duration of the block according to time base
173 } mkv_cuepoint;
174
175 typedef struct mkv_cues {
176 mkv_cuepoint *entries;
177 int num_entries;
178 } mkv_cues;
179
180 struct MatroskaMuxContext;
181
182 typedef struct mkv_track {
183 int write_dts;
184 int has_cue;
185 uint64_t uid;
186 unsigned track_num;
187 int track_num_size;
188 int sample_rate;
189 unsigned offset;
190 int64_t sample_rate_offset;
191 int64_t last_timestamp;
192 int64_t duration;
193 int64_t duration_offset;
194 uint64_t max_blockaddid;
195 int64_t blockadditionmapping_offset;
196 int codecpriv_offset;
197 unsigned codecpriv_size; ///< size reserved for CodecPrivate excluding header+length field
198 int64_t ts_offset;
199 uint64_t default_duration_low;
200 uint64_t default_duration_high;
201 /* This callback will be called twice: First with a NULL AVIOContext
202 * to return the size of the (Simple)Block's data via size
203 * and a second time with the AVIOContext set when the data
204 * shall be written.
205 * The callback shall not return an error on the second call. */
206 int (*reformat)(struct MatroskaMuxContext *, AVIOContext *,
207 const AVPacket *, int *size);
208 } mkv_track;
209
210 typedef struct MatroskaMuxContext {
211 const AVClass *class;
212 AVFormatContext *ctx;
213
214 int mode;
215 ebml_stored_master info;
216 ebml_stored_master track;
217 ebml_stored_master tags;
218 int64_t segment_offset;
219 AVIOContext *cluster_bc;
220 int64_t cluster_pos; ///< file offset of the current Cluster
221 int64_t cluster_pts;
222 int64_t duration_offset;
223 int64_t duration;
224 mkv_track *tracks;
225 mkv_seekhead seekhead;
226 mkv_cues cues;
227 int64_t cues_pos;
228
229 BlockContext cur_block;
230
231 /* Used as temporary buffer to use the minimal amount of bytes
232 * to write the length field of EBML Masters.
233 * Every user has to reset the buffer after using it and
234 * different uses may not overlap. It is currently used in
235 * mkv_write_tag(), in mkv_assemble_cues() as well as in
236 * mkv_update_codecprivate() and mkv_write_track(). */
237 AVIOContext *tmp_bc;
238
239 AVPacket *cur_audio_pkt;
240
241 unsigned nb_attachments;
242 int have_video;
243
244 int wrote_chapters;
245 int wrote_tags;
246
247 int reserve_cues_space;
248 int cluster_size_limit;
249 int64_t cluster_time_limit;
250 int write_crc;
251 int is_live;
252
253 int is_dash;
254 int dash_track_number;
255 int allow_raw_vfw;
256 int flipped_raw_rgb;
257 int default_mode;
258 int move_cues_to_front;
259
260 uint32_t segment_uid[4];
261 } MatroskaMuxContext;
262
263 /** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit
264 * offset, 4 bytes for target EBML ID */
265 #define MAX_SEEKENTRY_SIZE 21
266
267 /** 4 * (1-byte EBML ID, 1-byte EBML size, 8-byte uint max) */
268 #define MAX_CUETRACKPOS_SIZE 40
269
270 /** DURATION_STRING_LENGTH must be <= 112 or the containing
271 * simpletag will need more than one byte for its length field. */
272 #define DURATION_STRING_LENGTH 19
273
274 /** 2 + 1 Simpletag header, 2 + 1 + 8 Name "DURATION", rest for TagString */
275 #define DURATION_SIMPLETAG_SIZE (2 + 1 + (2 + 1 + 8) + (2 + 1 + DURATION_STRING_LENGTH))
276
277 /** Seek preroll value for opus */
278 #define OPUS_SEEK_PREROLL 80000000
279
280 115360 static int ebml_id_size(uint32_t id)
281 {
282 115360 return (av_log2(id) + 7U) / 8;
283 }
284
285 113199 static void put_ebml_id(AVIOContext *pb, uint32_t id)
286 {
287 113199 int i = ebml_id_size(id);
288
2/2
✓ Branch 0 taken 126908 times.
✓ Branch 1 taken 113199 times.
240107 while (i--)
289 126908 avio_w8(pb, (uint8_t)(id >> (i * 8)));
290 113199 }
291
292 /**
293 * Write an EBML size meaning "unknown size".
294 *
295 * @param bytes The number of bytes the size should occupy (maximum: 8).
296 */
297 18299 static void put_ebml_size_unknown(AVIOContext *pb, int bytes)
298 {
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18299 times.
18299 av_assert0(bytes <= 8);
300 18299 avio_w8(pb, 0x1ff >> bytes);
301 if (av_builtin_constant_p(bytes) && bytes == 1)
302 return;
303 18299 ffio_fill(pb, 0xff, bytes - 1);
304 }
305
306 /**
307 * Returns how many bytes are needed to represent a number
308 * as EBML variable length integer.
309 */
310 131399 static int ebml_num_size(uint64_t num)
311 {
312 131399 int bytes = 0;
313 do {
314 145133 bytes++;
315
2/2
✓ Branch 0 taken 13734 times.
✓ Branch 1 taken 131399 times.
145133 } while (num >>= 7);
316 131399 return bytes;
317 }
318
319 /**
320 * Calculate how many bytes are needed to represent the length field
321 * of an EBML element whose payload has a given length.
322 */
323 131327 static int ebml_length_size(uint64_t length)
324 {
325 131327 return ebml_num_size(length + 1);
326 }
327
328 /**
329 * Write a number as EBML variable length integer on `bytes` bytes.
330 * `bytes` is taken literally without checking.
331 */
332 124168 static void put_ebml_num(AVIOContext *pb, uint64_t num, int bytes)
333 {
334 124168 num |= 1ULL << bytes * 7;
335
2/2
✓ Branch 0 taken 139971 times.
✓ Branch 1 taken 124168 times.
264139 for (int i = bytes - 1; i >= 0; i--)
336 139971 avio_w8(pb, (uint8_t)(num >> i * 8));
337 124168 }
338
339 /**
340 * Write a length as EBML variable length integer.
341 *
342 * @param bytes The number of bytes that need to be used to write the number.
343 * If zero, the minimal number of bytes will be used.
344 */
345 99696 static void put_ebml_length(AVIOContext *pb, uint64_t length, int bytes)
346 {
347 99696 int needed_bytes = ebml_length_size(length);
348
349 // sizes larger than this are currently undefined in EBML
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99696 times.
99696 av_assert0(length < (1ULL << 56) - 1);
351
352
2/2
✓ Branch 0 taken 81136 times.
✓ Branch 1 taken 18560 times.
99696 if (bytes == 0)
353 81136 bytes = needed_bytes;
354 // The bytes needed to write the given size must not exceed
355 // the bytes that we ought to use.
356
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99696 times.
99696 av_assert0(bytes >= needed_bytes);
357 99696 put_ebml_num(pb, length, bytes);
358 99696 }
359
360 /**
361 * Write a (random) UID with fixed size to make the output more deterministic
362 */
363 145 static void put_ebml_uid(AVIOContext *pb, uint32_t elementid, uint64_t uid)
364 {
365 145 put_ebml_id(pb, elementid);
366 145 put_ebml_length(pb, 8, 0);
367 145 avio_wb64(pb, uid);
368 145 }
369
370 66606 static void put_ebml_uint(AVIOContext *pb, uint32_t elementid, uint64_t val)
371 {
372 66606 int i, bytes = 1;
373 66606 uint64_t tmp = val;
374
2/2
✓ Branch 0 taken 61521 times.
✓ Branch 1 taken 66606 times.
128127 while (tmp >>= 8)
375 61521 bytes++;
376
377 66606 put_ebml_id(pb, elementid);
378 66606 put_ebml_length(pb, bytes, 0);
379
2/2
✓ Branch 0 taken 128127 times.
✓ Branch 1 taken 66606 times.
194733 for (i = bytes - 1; i >= 0; i--)
380 128127 avio_w8(pb, (uint8_t)(val >> i * 8));
381 66606 }
382
383 75 static void put_ebml_float(AVIOContext *pb, uint32_t elementid, double val)
384 {
385 75 put_ebml_id(pb, elementid);
386 75 put_ebml_length(pb, 8, 0);
387 75 avio_wb64(pb, av_double2int(val));
388 75 }
389
390 10220 static void put_ebml_binary(AVIOContext *pb, uint32_t elementid,
391 const void *buf, int size)
392 {
393 10220 put_ebml_id(pb, elementid);
394 10220 put_ebml_length(pb, size, 0);
395 10220 avio_write(pb, buf, size);
396 10220 }
397
398 303 static void put_ebml_string(AVIOContext *pb, uint32_t elementid,
399 const char *str)
400 {
401 303 put_ebml_binary(pb, elementid, str, strlen(str));
402 303 }
403
404 /**
405 * Write a void element of a given size. Useful for reserving space in
406 * the file to be written to later.
407 *
408 * @param size The number of bytes to reserve, which must be at least 2.
409 */
410 694 static void put_ebml_void(AVIOContext *pb, int size)
411 {
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 694 times.
694 av_assert0(size >= 2);
413
414 694 put_ebml_id(pb, EBML_ID_VOID);
415 // we need to subtract the length needed to store the size from the
416 // size we need to reserve so 2 cases, we use 8 bytes to store the
417 // size if possible, 1 byte otherwise
418
2/2
✓ Branch 0 taken 480 times.
✓ Branch 1 taken 214 times.
694 if (size < 10) {
419 480 size -= 2;
420 480 put_ebml_length(pb, size, 0);
421 } else {
422 214 size -= 9;
423 214 put_ebml_length(pb, size, 8);
424 }
425 694 ffio_fill(pb, 0, size);
426 694 }
427
428 18257 static ebml_master start_ebml_master(AVIOContext *pb, uint32_t elementid,
429 uint64_t expectedsize)
430 {
431
2/2
✓ Branch 0 taken 18184 times.
✓ Branch 1 taken 73 times.
18257 int bytes = expectedsize ? ebml_length_size(expectedsize) : 8;
432
433 18257 put_ebml_id(pb, elementid);
434 18257 put_ebml_size_unknown(pb, bytes);
435 18257 return (ebml_master) { avio_tell(pb), bytes };
436 }
437
438 18257 static void end_ebml_master(AVIOContext *pb, ebml_master master)
439 {
440 18257 int64_t pos = avio_tell(pb);
441
442
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18257 times.
18257 if (avio_seek(pb, master.pos - master.sizebytes, SEEK_SET) < 0)
443 return;
444 18257 put_ebml_length(pb, pos - master.pos, master.sizebytes);
445 18257 avio_seek(pb, pos, SEEK_SET);
446 }
447
448 35222 static EbmlElement *ebml_writer_add(EbmlWriter *writer,
449 uint32_t id, EbmlType type)
450 {
451 35222 writer->elements[writer->nb_elements].id = id;
452 35222 writer->elements[writer->nb_elements].type = type;
453 35222 return &writer->elements[writer->nb_elements++];
454 }
455
456 22659 static void ebml_writer_open_master(EbmlWriter *writer, uint32_t id)
457 {
458 22659 EbmlElement *const elem = ebml_writer_add(writer, id, EBML_MASTER);
459 22659 EbmlMaster *const master = &elem->priv.master;
460
461 22659 master->containing_master = writer->current_master_element;
462 22659 master->nb_elements = -1;
463
464 22659 writer->current_master_element = writer->nb_elements - 1;
465 22659 }
466
467 272 static void ebml_writer_close_master(EbmlWriter *writer)
468 {
469 EbmlElement *elem;
470 av_assert2(writer->current_master_element >= 0);
471 av_assert2(writer->current_master_element < writer->nb_elements);
472 272 elem = &writer->elements[writer->current_master_element];
473 av_assert2(elem->type == EBML_MASTER);
474 av_assert2(elem->priv.master.nb_elements < 0); /* means unset */
475 272 elem->priv.master.nb_elements = writer->nb_elements - writer->current_master_element - 1;
476 av_assert2(elem->priv.master.containing_master < 0 ||
477 elem->priv.master.containing_master < writer->current_master_element);
478 272 writer->current_master_element = elem->priv.master.containing_master;
479 272 }
480
481 11199 static void ebml_writer_close_or_discard_master(EbmlWriter *writer)
482 {
483 av_assert2(writer->nb_elements > 0);
484 av_assert2(0 <= writer->current_master_element);
485 av_assert2(writer->current_master_element < writer->nb_elements);
486
2/2
✓ Branch 0 taken 11049 times.
✓ Branch 1 taken 150 times.
11199 if (writer->current_master_element == writer->nb_elements - 1) {
487 11049 const EbmlElement *const elem = &writer->elements[writer->nb_elements - 1];
488 /* The master element has no children. Discard it. */
489 av_assert2(elem->type == EBML_MASTER);
490 av_assert2(elem->priv.master.containing_master < 0 ||
491 elem->priv.master.containing_master < writer->current_master_element);
492 11049 writer->current_master_element = elem->priv.master.containing_master;
493 11049 writer->nb_elements--;
494 11049 return;
495 }
496 150 ebml_writer_close_master(writer);
497 }
498
499 299 static void ebml_writer_add_string(EbmlWriter *writer, uint32_t id,
500 const char *str)
501 {
502 299 EbmlElement *const elem = ebml_writer_add(writer, id, EBML_STR);
503
504 299 elem->priv.str = str;
505 299 }
506
507 127 static void ebml_writer_add_bin(EbmlWriter *writer, uint32_t id,
508 const uint8_t *data, size_t size)
509 {
510 127 EbmlElement *const elem = ebml_writer_add(writer, id, EBML_BIN);
511
512 #if SIZE_MAX > UINT64_MAX
513 size = FFMIN(size, UINT64_MAX);
514 #endif
515 127 elem->size = size;
516 127 elem->priv.bin = data;
517 127 }
518
519 27 static void ebml_writer_add_float(EbmlWriter *writer, uint32_t id,
520 double val)
521 {
522 27 EbmlElement *const elem = ebml_writer_add(writer, id, EBML_FLOAT);
523
524 27 elem->priv.f = val;
525 27 }
526
527 1 static void ebml_writer_add_uid(EbmlWriter *writer, uint32_t id,
528 uint64_t val)
529 {
530 1 EbmlElement *const elem = ebml_writer_add(writer, id, EBML_UID);
531 1 elem->priv.uint = val;
532 1 }
533
534 775 static void ebml_writer_add_uint(EbmlWriter *writer, uint32_t id,
535 uint64_t val)
536 {
537 775 EbmlElement *elem = ebml_writer_add(writer, id, EBML_UINT);
538 775 elem->priv.uint = val;
539 775 }
540
541 199 static void ebml_writer_add_sint(EbmlWriter *writer, uint32_t id,
542 int64_t val)
543 {
544 199 EbmlElement *elem = ebml_writer_add(writer, id, EBML_SINT);
545 199 elem->priv.sint = val;
546 199 }
547
548 11135 static void ebml_writer_add_block(EbmlWriter *writer, MatroskaMuxContext *mkv)
549 {
550 11135 EbmlElement *elem = ebml_writer_add(writer, MATROSKA_ID_BLOCK, EBML_BLOCK);
551 11135 elem->priv.mkv = mkv;
552 11135 }
553
554 299 static int ebml_writer_str_len(EbmlElement *elem)
555 {
556 299 size_t len = strlen(elem->priv.str);
557 #if SIZE_MAX > UINT64_MAX
558 len = FF_MIN(len, UINT64_MAX);
559 #endif
560 299 elem->size = len;
561 299 return 0;
562 }
563
564 974 static av_const int uint_size(uint64_t val)
565 {
566 974 int bytes = 0;
567 do {
568 1168 bytes++;
569
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 974 times.
1168 } while (val >>= 8);
570 974 return bytes;
571 }
572
573 775 static int ebml_writer_uint_len(EbmlElement *elem)
574 {
575 775 elem->size = uint_size(elem->priv.uint);
576 775 return 0;
577 }
578
579 199 static av_const int sint_size(int64_t val)
580 {
581
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 23 times.
199 uint64_t tmp = 2 * (uint64_t)(val < 0 ? val^-1 : val);
582 199 return uint_size(tmp);
583 }
584
585 199 static int ebml_writer_sint_len(EbmlElement *elem)
586 {
587 199 elem->size = sint_size(elem->priv.sint);
588 199 return 0;
589 }
590
591 static int ebml_writer_elem_len(EbmlWriter *writer, EbmlElement *elem,
592 int remaining_elems);
593
594 774 static int ebml_writer_master_len(EbmlWriter *writer, EbmlElement *elem,
595 int remaining_elems)
596 {
597
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 502 times.
774 int nb_elems = elem->priv.master.nb_elements >= 0 ? elem->priv.master.nb_elements : remaining_elems - 1;
598 774 EbmlElement *const master = elem;
599 774 uint64_t total_size = 0;
600
601 774 master->priv.master.nb_elements = nb_elems;
602
2/2
✓ Branch 0 taken 2003 times.
✓ Branch 1 taken 774 times.
2777 for (; elem++, nb_elems > 0;) {
603 2003 int ret = ebml_writer_elem_len(writer, elem, nb_elems);
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2003 times.
2003 if (ret < 0)
605 return ret;
606 av_assert2(ret < nb_elems);
607 /* No overflow is possible here, as both total_size and elem->size
608 * are bounded by MAX_SUPPORTED_EBML_LENGTH. */
609 2003 total_size += ebml_id_size(elem->id) + elem->length_size + elem->size;
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2003 times.
2003 if (total_size > MAX_SUPPORTED_EBML_LENGTH)
611 return AVERROR(ERANGE);
612 2003 nb_elems--; /* consume elem */
613 2003 elem += ret, nb_elems -= ret; /* and elem's children */
614 }
615 774 master->size = total_size;
616
617 774 return master->priv.master.nb_elements;
618 }
619
620 11135 static int ebml_writer_block_len(EbmlElement *elem)
621 {
622 11135 MatroskaMuxContext *const mkv = elem->priv.mkv;
623 11135 BlockContext *const block = &mkv->cur_block;
624 11135 mkv_track *const track = block->track;
625 11135 const AVPacket *const pkt = block->pkt;
626 int err, size;
627
628
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 10930 times.
11135 if (track->reformat) {
629 205 err = track->reformat(mkv, NULL, pkt, &size);
630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 205 times.
205 if (err < 0) {
631 av_log(mkv->ctx, AV_LOG_ERROR, "Error when reformatting data of "
632 "a packet from stream %d.\n", pkt->stream_index);
633 return err;
634 }
635 } else {
636 10930 size = pkt->size;
637
1/2
✓ Branch 0 taken 10930 times.
✗ Branch 1 not taken.
10930 if (track->offset <= size)
638 10930 size -= track->offset;
639 }
640 11135 elem->size = track->track_num_size + 3U + size;
641
642 11135 return 0;
643 }
644
645 11135 static void ebml_writer_write_block(const EbmlElement *elem, AVIOContext *pb)
646 {
647 11135 MatroskaMuxContext *const mkv = elem->priv.mkv;
648 11135 BlockContext *const block = &mkv->cur_block;
649 11135 mkv_track *const track = block->track;
650 11135 const AVPacket *const pkt = block->pkt;
651
652 11135 put_ebml_num(pb, track->track_num, track->track_num_size);
653 11135 avio_wb16(pb, block->rel_ts);
654 11135 avio_w8(pb, block->flags);
655
656
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 10930 times.
11135 if (track->reformat) {
657 int size;
658 205 track->reformat(mkv, pb, pkt, &size);
659 } else {
660 10930 const uint8_t *data = pkt->data;
661
1/2
✓ Branch 0 taken 10930 times.
✗ Branch 1 not taken.
10930 unsigned offset = track->offset <= pkt->size ? track->offset : 0;
662 10930 avio_write(pb, data + offset, pkt->size - offset);
663 }
664 11135 }
665
666 13337 static int ebml_writer_elem_len(EbmlWriter *writer, EbmlElement *elem,
667 int remaining_elems)
668 {
669 13337 int ret = 0;
670
671
7/7
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 299 times.
✓ Branch 2 taken 775 times.
✓ Branch 3 taken 199 times.
✓ Branch 4 taken 11135 times.
✓ Branch 5 taken 774 times.
✓ Branch 6 taken 127 times.
13337 switch (elem->type) {
672 28 case EBML_FLOAT:
673 case EBML_UID:
674 28 elem->size = 8;
675 28 break;
676 299 case EBML_STR:
677 299 ret = ebml_writer_str_len(elem);
678 299 break;
679 775 case EBML_UINT:
680 775 ret = ebml_writer_uint_len(elem);
681 775 break;
682 199 case EBML_SINT:
683 199 ret = ebml_writer_sint_len(elem);
684 199 break;
685 11135 case EBML_BLOCK:
686 11135 ret = ebml_writer_block_len(elem);
687 11135 break;
688 774 case EBML_MASTER:
689 774 ret = ebml_writer_master_len(writer, elem, remaining_elems);
690 774 break;
691 }
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13337 times.
13337 if (ret < 0)
693 return ret;
694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13337 times.
13337 if (elem->size > MAX_SUPPORTED_EBML_LENGTH)
695 return AVERROR(ERANGE);
696 13337 elem->length_size = ebml_length_size(elem->size);
697 13337 return ret; /* number of elements consumed excluding elem itself */
698 }
699
700 13337 static int ebml_writer_elem_write(const EbmlElement *elem, AVIOContext *pb)
701 {
702 13337 put_ebml_id(pb, elem->id);
703 13337 put_ebml_num(pb, elem->size, elem->length_size);
704
5/6
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 974 times.
✓ Branch 2 taken 426 times.
✓ Branch 3 taken 11135 times.
✓ Branch 4 taken 774 times.
✗ Branch 5 not taken.
13337 switch (elem->type) {
705 28 case EBML_UID:
706 case EBML_FLOAT: {
707 56 uint64_t val = elem->type == EBML_UID ? elem->priv.uint
708
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 27 times.
28 : av_double2int(elem->priv.f);
709 28 avio_wb64(pb, val);
710 28 break;
711 }
712 974 case EBML_UINT:
713 case EBML_SINT: {
714 1948 uint64_t val = elem->type == EBML_UINT ? elem->priv.uint
715
2/2
✓ Branch 0 taken 775 times.
✓ Branch 1 taken 199 times.
974 : elem->priv.sint;
716
2/2
✓ Branch 0 taken 1168 times.
✓ Branch 1 taken 974 times.
2142 for (int i = elem->size; --i >= 0; )
717 1168 avio_w8(pb, (uint8_t)(val >> i * 8));
718 974 break;
719 }
720 426 case EBML_STR:
721 case EBML_BIN: {
722 852 const uint8_t *data = elem->type == EBML_BIN ? elem->priv.bin
723
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 299 times.
426 : (const uint8_t*)elem->priv.str;
724 426 avio_write(pb, data, elem->size);
725 426 break;
726 }
727 11135 case EBML_BLOCK:
728 11135 ebml_writer_write_block(elem, pb);
729 11135 break;
730 774 case EBML_MASTER: {
731 774 int nb_elems = elem->priv.master.nb_elements;
732
733 774 elem++;
734
2/2
✓ Branch 0 taken 2003 times.
✓ Branch 1 taken 774 times.
2777 for (int i = 0; i < nb_elems; i++)
735 2003 i += ebml_writer_elem_write(elem + i, pb);
736
737 774 return nb_elems;
738 }
739 }
740 12563 return 0;
741 }
742
743 11334 static int ebml_writer_write(EbmlWriter *writer, AVIOContext *pb)
744 {
745 11334 int ret = ebml_writer_elem_len(writer, writer->elements,
746 11334 writer->nb_elements);
747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11334 times.
11334 if (ret < 0)
748 return ret;
749 11334 ebml_writer_elem_write(writer->elements, pb);
750 11334 return 0;
751 }
752
753 158 static void mkv_add_seekhead_entry(MatroskaMuxContext *mkv, uint32_t elementid,
754 uint64_t filepos)
755 {
756 158 mkv_seekhead *seekhead = &mkv->seekhead;
757
758 av_assert1(seekhead->num_entries < MAX_SEEKHEAD_ENTRIES);
759
760 158 seekhead->entries[seekhead->num_entries].elementid = elementid;
761 158 seekhead->entries[seekhead->num_entries++].segmentpos = filepos - mkv->segment_offset;
762 158 }
763
764 3358 static int start_ebml_master_crc32(AVIOContext **dyn_cp, MatroskaMuxContext *mkv)
765 {
766 int ret;
767
768
3/4
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 3116 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 242 times.
3358 if (!*dyn_cp && (ret = avio_open_dyn_buf(dyn_cp)) < 0)
769 return ret;
770
771
2/2
✓ Branch 0 taken 479 times.
✓ Branch 1 taken 2879 times.
3358 if (mkv->write_crc)
772 479 put_ebml_void(*dyn_cp, 6); /* Reserve space for CRC32 so position/size calculations using avio_tell() take it into account */
773
774 3358 return 0;
775 }
776
777 3355 static int end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp,
778 MatroskaMuxContext *mkv, uint32_t id,
779 int length_size, int keep_buffer,
780 int add_seekentry)
781 {
782 uint8_t *buf, crc[4];
783 3355 int ret, size, skip = 0;
784
785 3355 size = avio_get_dyn_buf(*dyn_cp, &buf);
786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3355 times.
3355 if ((ret = (*dyn_cp)->error) < 0)
787 goto fail;
788
789
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 3299 times.
3355 if (add_seekentry)
790 56 mkv_add_seekhead_entry(mkv, id, avio_tell(pb));
791
792 3355 put_ebml_id(pb, id);
793 3355 put_ebml_length(pb, size, length_size);
794
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 2877 times.
3355 if (mkv->write_crc) {
795 478 skip = 6; /* Skip reserved 6-byte long void element from the dynamic buffer. */
796 478 AV_WL32(crc, av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), UINT32_MAX, buf + skip, size - skip) ^ UINT32_MAX);
797 478 put_ebml_binary(pb, EBML_ID_CRC32, crc, sizeof(crc));
798 }
799 3355 avio_write(pb, buf + skip, size - skip);
800
801 3355 fail:
802
2/2
✓ Branch 0 taken 3113 times.
✓ Branch 1 taken 242 times.
3355 if (keep_buffer) {
803 3113 ffio_reset_dyn_buf(*dyn_cp);
804 } else {
805 242 ffio_free_dyn_buf(dyn_cp);
806 }
807 3355 return ret;
808 }
809
810 /**
811 * Output EBML master. Keep the buffer if seekable, allowing for later updates.
812 * Furthermore always add a SeekHead Entry for this element.
813 */
814 122 static int end_ebml_master_crc32_tentatively(AVIOContext *pb,
815 ebml_stored_master *elem,
816 MatroskaMuxContext *mkv, uint32_t id)
817 {
818
4/4
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 102 times.
✓ Branch 3 taken 9 times.
122 if (IS_SEEKABLE(pb, mkv)) {
819 uint8_t *buf;
820 102 int size = avio_get_dyn_buf(elem->bc, &buf);
821
822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (elem->bc->error < 0)
823 return elem->bc->error;
824
825 102 elem->pos = avio_tell(pb);
826 102 mkv_add_seekhead_entry(mkv, id, elem->pos);
827
828 102 put_ebml_id(pb, id);
829 102 put_ebml_length(pb, size, 0);
830 102 avio_write(pb, buf, size);
831
832 102 return 0;
833 } else
834 20 return end_ebml_master_crc32(pb, &elem->bc, mkv, id, 0, 0, 1);
835 }
836
837 16 static void put_xiph_size(AVIOContext *pb, int size)
838 {
839 16 ffio_fill(pb, 255, size / 255);
840 16 avio_w8(pb, size % 255);
841 16 }
842
843 /**
844 * Free the members allocated in the mux context.
845 */
846 42 static void mkv_deinit(AVFormatContext *s)
847 {
848 42 MatroskaMuxContext *mkv = s->priv_data;
849
850 42 ffio_free_dyn_buf(&mkv->cluster_bc);
851 42 ffio_free_dyn_buf(&mkv->info.bc);
852 42 ffio_free_dyn_buf(&mkv->track.bc);
853 42 ffio_free_dyn_buf(&mkv->tags.bc);
854 42 ffio_free_dyn_buf(&mkv->tmp_bc);
855
856 42 av_freep(&mkv->cur_block.h2645_nalu_list.nalus);
857 42 av_freep(&mkv->cues.entries);
858 42 av_freep(&mkv->tracks);
859 42 }
860
861 /**
862 * Initialize the SeekHead element to be ready to index level 1 Matroska
863 * elements. Enough space to write MAX_SEEKHEAD_ENTRIES SeekHead entries
864 * will be reserved at the current file location.
865 */
866 42 static void mkv_start_seekhead(MatroskaMuxContext *mkv, AVIOContext *pb)
867 {
868 42 mkv->seekhead.filepos = avio_tell(pb);
869 // 21 bytes max for a Seek entry, 6 bytes max for the SeekHead ID
870 // and size, 6 bytes for a CRC32 element, and 2 bytes to guarantee
871 // that an EBML void element will fit afterwards
872 42 mkv->seekhead.reserved_size = MAX_SEEKHEAD_ENTRIES * MAX_SEEKENTRY_SIZE + 14;
873 42 put_ebml_void(pb, mkv->seekhead.reserved_size);
874 42 }
875
876 /**
877 * Write the SeekHead to the file at the location reserved for it
878 * and seek to destpos afterwards. When error_on_seek_failure
879 * is not set, failure to seek to the position designated for the
880 * SeekHead is not considered an error and it is presumed that
881 * destpos is the current position; failure to seek to destpos
882 * afterwards is always an error.
883 *
884 * @return 0 on success, < 0 on error.
885 */
886 42 static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv,
887 int error_on_seek_failure, int64_t destpos)
888 {
889 42 AVIOContext *dyn_cp = NULL;
890 42 mkv_seekhead *seekhead = &mkv->seekhead;
891 int64_t remaining, ret64;
892 int i, ret;
893
894
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
42 if ((ret64 = avio_seek(pb, seekhead->filepos, SEEK_SET)) < 0)
895 return error_on_seek_failure ? ret64 : 0;
896
897 42 ret = start_ebml_master_crc32(&dyn_cp, mkv);
898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (ret < 0)
899 return ret;
900
901
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 42 times.
200 for (i = 0; i < seekhead->num_entries; i++) {
902 158 mkv_seekhead_entry *entry = &seekhead->entries[i];
903 158 ebml_master seekentry = start_ebml_master(dyn_cp, MATROSKA_ID_SEEKENTRY,
904 MAX_SEEKENTRY_SIZE);
905
906 158 put_ebml_id(dyn_cp, MATROSKA_ID_SEEKID);
907 158 put_ebml_length(dyn_cp, ebml_id_size(entry->elementid), 0);
908 158 put_ebml_id(dyn_cp, entry->elementid);
909
910 158 put_ebml_uint(dyn_cp, MATROSKA_ID_SEEKPOSITION, entry->segmentpos);
911 158 end_ebml_master(dyn_cp, seekentry);
912 }
913 42 ret = end_ebml_master_crc32(pb, &dyn_cp, mkv,
914 MATROSKA_ID_SEEKHEAD, 0, 0, 0);
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (ret < 0)
916 return ret;
917
918 42 remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
919 42 put_ebml_void(pb, remaining);
920
921
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
42 if ((ret64 = avio_seek(pb, destpos, SEEK_SET)) < 0)
922 return ret64;
923
924 42 return 0;
925 }
926
927 6552 static int mkv_add_cuepoint(MatroskaMuxContext *mkv, int stream, int64_t ts,
928 int64_t cluster_pos, int64_t relative_pos, int64_t duration)
929 {
930 6552 mkv_cues *cues = &mkv->cues;
931 6552 mkv_cuepoint *entries = cues->entries;
932 6552 unsigned idx = cues->num_entries;
933
934
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6552 times.
6552 if (ts < 0)
935 return 0;
936
937 6552 entries = av_realloc_array(entries, cues->num_entries + 1, sizeof(mkv_cuepoint));
938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6552 times.
6552 if (!entries)
939 return AVERROR(ENOMEM);
940 6552 cues->entries = entries;
941
942 /* Make sure the cues entries are sorted by pts. */
943
3/4
✓ Branch 0 taken 6518 times.
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6518 times.
6552 while (idx > 0 && entries[idx - 1].pts > ts)
944 idx--;
945 6552 memmove(&entries[idx + 1], &entries[idx],
946 6552 (cues->num_entries - idx) * sizeof(entries[0]));
947
948 6552 entries[idx].pts = ts;
949 6552 entries[idx].stream_idx = stream;
950 6552 entries[idx].cluster_pos = cluster_pos - mkv->segment_offset;
951 6552 entries[idx].relative_pos = relative_pos;
952 6552 entries[idx].duration = duration;
953
954 6552 cues->num_entries++;
955
956 6552 return 0;
957 }
958
959 37 static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, AVIOContext *cuepoint,
960 const mkv_cues *cues, mkv_track *tracks, int num_tracks,
961 uint64_t offset)
962 {
963 37 for (mkv_cuepoint *entry = cues->entries, *end = entry + cues->num_entries;
964
2/2
✓ Branch 0 taken 9290 times.
✓ Branch 1 taken 37 times.
9327 entry < end;) {
965 9290 uint64_t pts = entry->pts;
966 uint8_t *buf;
967 int size;
968
969 9290 put_ebml_uint(cuepoint, MATROSKA_ID_CUETIME, pts);
970
971 // put all the entries from different tracks that have the exact same
972 // timestamp into the same CuePoint
973
2/2
✓ Branch 0 taken 18597 times.
✓ Branch 1 taken 9290 times.
27887 for (int j = 0; j < num_tracks; j++)
974 18597 tracks[j].has_cue = 0;
975 do {
976 ebml_master track_positions;
977 17814 int idx = entry->stream_idx;
978
979
2/4
✓ Branch 0 taken 17814 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17814 times.
17814 av_assert0(idx >= 0 && idx < num_tracks);
980
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 17812 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
17814 if (tracks[idx].has_cue && streams[idx]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
981 continue;
982 17814 tracks[idx].has_cue = 1;
983 17814 track_positions = start_ebml_master(cuepoint, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);
984 17814 put_ebml_uint(cuepoint, MATROSKA_ID_CUETRACK , tracks[idx].track_num);
985 17814 put_ebml_uint(cuepoint, MATROSKA_ID_CUECLUSTERPOSITION , entry->cluster_pos + offset);
986 17814 put_ebml_uint(cuepoint, MATROSKA_ID_CUERELATIVEPOSITION, entry->relative_pos);
987
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 17731 times.
17814 if (entry->duration > 0)
988 83 put_ebml_uint(cuepoint, MATROSKA_ID_CUEDURATION , entry->duration);
989 17814 end_ebml_master(cuepoint, track_positions);
990
4/4
✓ Branch 0 taken 17777 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 8524 times.
✓ Branch 3 taken 9253 times.
17814 } while (++entry < end && entry->pts == pts);
991 9290 size = avio_get_dyn_buf(cuepoint, &buf);
992
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9290 times.
9290 if (cuepoint->error < 0)
993 return cuepoint->error;
994 9290 put_ebml_binary(dyn_cp, MATROSKA_ID_POINTENTRY, buf, size);
995 9290 ffio_reset_dyn_buf(cuepoint);
996 }
997
998 37 return 0;
999 }
1000
1001 8 static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb,
1002 const AVCodecParameters *par,
1003 const uint8_t *extradata, int extradata_size)
1004 {
1005 const uint8_t *header_start[3];
1006 int header_len[3];
1007 int first_header_size;
1008 int err, j;
1009
1010
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (par->codec_id == AV_CODEC_ID_VORBIS)
1011 1 first_header_size = 30;
1012 else
1013 7 first_header_size = 42;
1014
1015 8 err = avpriv_split_xiph_headers(extradata, extradata_size,
1016 first_header_size, header_start, header_len);
1017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (err < 0) {
1018 av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
1019 return err;
1020 }
1021
1022 8 avio_w8(pb, 2); // number packets - 1
1023
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 for (j = 0; j < 2; j++) {
1024 16 put_xiph_size(pb, header_len[j]);
1025 }
1026
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 for (j = 0; j < 3; j++)
1027 24 avio_write(pb, header_start[j], header_len[j]);
1028
1029 8 return 0;
1030 }
1031
1032 #if CONFIG_MATROSKA_MUXER
1033 2 static int put_wv_codecpriv(AVIOContext *pb, const uint8_t *extradata, int extradata_size)
1034 {
1035
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if (extradata && extradata_size == 2)
1036 2 avio_write(pb, extradata, 2);
1037 else
1038 avio_wl16(pb, 0x410); // fallback to the most recent version
1039 2 return 0;
1040 }
1041
1042 6 static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb,
1043 const AVCodecParameters *par,
1044 const uint8_t *extradata, int extradata_size)
1045 {
1046 18 int write_comment = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
1047
4/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2 times.
12 !(par->ch_layout.u.mask & ~0x3ffffULL) &&
1048 6 !ff_flac_is_native_layout(par->ch_layout.u.mask));
1049 6 int ret = ff_flac_write_header(pb, extradata, extradata_size,
1050 !write_comment);
1051
1052
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
1053 return ret;
1054
1055
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (write_comment) {
1056 8 const char *vendor = (s->flags & AVFMT_FLAG_BITEXACT) ?
1057
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 "Lavf" : LIBAVFORMAT_IDENT;
1058 4 AVDictionary *dict = NULL;
1059 uint8_t buf[32];
1060 int64_t len;
1061
1062 4 snprintf(buf, sizeof(buf), "0x%"PRIx64, par->ch_layout.u.mask);
1063 4 av_dict_set(&dict, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", buf, 0);
1064
1065 4 len = ff_vorbiscomment_length(dict, vendor, NULL, 0);
1066 av_assert1(len < (1 << 24) - 4);
1067
1068 4 avio_w8(pb, 0x84);
1069 4 avio_wb24(pb, len);
1070
1071 4 ff_vorbiscomment_write(pb, dict, vendor, NULL, 0);
1072
1073 4 av_dict_free(&dict);
1074 }
1075
1076 6 return 0;
1077 }
1078
1079 7 static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv,
1080 const uint8_t *extradata, int extradata_size,
1081 int *sample_rate, int *output_sample_rate)
1082 {
1083 MPEG4AudioConfig mp4ac;
1084 int ret;
1085
1086 7 ret = avpriv_mpeg4audio_get_config2(&mp4ac, extradata, extradata_size, 1, s);
1087 /* Don't abort if the failure is because of missing extradata. Assume in that
1088 * case a bitstream filter will provide the muxer with the extradata in the
1089 * first packet.
1090 * Abort however if s->pb is not seekable, as we would not be able to seek back
1091 * to write the sample rate elements once the extradata shows up, anyway. */
1092
5/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
7 if (ret < 0 && (extradata_size || !IS_SEEKABLE(s->pb, mkv))) {
1093 av_log(s, AV_LOG_ERROR,
1094 "Error parsing AAC extradata, unable to determine samplerate.\n");
1095 return AVERROR(EINVAL);
1096 }
1097
1098
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (ret < 0) {
1099 /* This will only happen when this function is called while writing the
1100 * header and no extradata is available. The space for this element has
1101 * to be reserved for when this function is called again after the
1102 * extradata shows up in the first packet, as there's no way to know if
1103 * output_sample_rate will be different than sample_rate or not. */
1104 1 *output_sample_rate = *sample_rate;
1105 } else {
1106 6 *sample_rate = mp4ac.sample_rate;
1107 6 *output_sample_rate = mp4ac.ext_sample_rate;
1108 }
1109 7 return 0;
1110 }
1111 #endif
1112
1113 67 static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp,
1114 const AVCodecParameters *par,
1115 const uint8_t *extradata,
1116 int extradata_size,
1117 unsigned *size_to_reserve)
1118 {
1119
9/10
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 32 times.
67 switch (par->codec_id) {
1120 8 case AV_CODEC_ID_VORBIS:
1121 case AV_CODEC_ID_THEORA:
1122 8 return put_xiph_codecpriv(s, dyn_cp, par, extradata, extradata_size);
1123 3 case AV_CODEC_ID_AV1:
1124
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (extradata_size)
1125 2 return ff_isom_write_av1c(dyn_cp, extradata,
1126 extradata_size, 1);
1127 else
1128 1 *size_to_reserve = (AV1_SANE_SEQUENCE_HEADER_MAX_BITS + 7) / 8 + 100;
1129 1 break;
1130 #if CONFIG_MATROSKA_MUXER
1131 6 case AV_CODEC_ID_FLAC:
1132 6 return put_flac_codecpriv(s, dyn_cp, par, extradata, extradata_size);
1133 2 case AV_CODEC_ID_WAVPACK:
1134 2 return put_wv_codecpriv(dyn_cp, extradata, extradata_size);
1135 5 case AV_CODEC_ID_H264:
1136 5 return ff_isom_write_avcc(dyn_cp, extradata,
1137 extradata_size);
1138 3 case AV_CODEC_ID_HEVC:
1139 3 return ff_isom_write_hvcc(dyn_cp, extradata,
1140 extradata_size, 0);
1141 1 case AV_CODEC_ID_ALAC:
1142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (extradata_size < 36) {
1143 av_log(s, AV_LOG_ERROR,
1144 "Invalid extradata found, ALAC expects a 36-byte "
1145 "QuickTime atom.");
1146 return AVERROR_INVALIDDATA;
1147 } else
1148 1 avio_write(dyn_cp, extradata + 12,
1149 extradata_size - 12);
1150 1 break;
1151 7 case AV_CODEC_ID_AAC:
1152
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (extradata_size)
1153 6 avio_write(dyn_cp, extradata, extradata_size);
1154 else
1155 1 *size_to_reserve = MAX_PCE_SIZE;
1156 7 break;
1157 case AV_CODEC_ID_ARIB_CAPTION: {
1158 unsigned stream_identifier, data_component_id;
1159 switch (par->profile) {
1160 case AV_PROFILE_ARIB_PROFILE_A:
1161 stream_identifier = 0x30;
1162 data_component_id = 0x0008;
1163 break;
1164 case AV_PROFILE_ARIB_PROFILE_C:
1165 stream_identifier = 0x87;
1166 data_component_id = 0x0012;
1167 break;
1168 default:
1169 av_log(s, AV_LOG_ERROR,
1170 "Unset/unknown ARIB caption profile %d utilized!\n",
1171 par->profile);
1172 return AVERROR_INVALIDDATA;
1173 }
1174 avio_w8(dyn_cp, stream_identifier);
1175 avio_wb16(dyn_cp, data_component_id);
1176 break;
1177 }
1178 #endif
1179 32 default:
1180
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
33 if (CONFIG_MATROSKA_MUXER && par->codec_id == AV_CODEC_ID_PRORES &&
1181 1 ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == AV_CODEC_ID_PRORES) {
1182 1 avio_wl32(dyn_cp, par->codec_tag);
1183
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
31 } else if (extradata_size && par->codec_id != AV_CODEC_ID_TTA)
1184 10 avio_write(dyn_cp, extradata, extradata_size);
1185 }
1186
1187 41 return 0;
1188 }
1189
1190 73 static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp,
1191 AVCodecParameters *par,
1192 const uint8_t *extradata, int extradata_size,
1193 int native_id, int qt_id,
1194 uint8_t **codecpriv, int *codecpriv_size,
1195 unsigned *max_payload_size)
1196 {
1197 73 MatroskaMuxContext av_unused *const mkv = s->priv_data;
1198 73 unsigned size_to_reserve = 0;
1199 int ret;
1200
1201
2/2
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 6 times.
73 if (native_id) {
1202 67 ret = mkv_assemble_native_codecprivate(s, dyn_cp, par,
1203 extradata, extradata_size,
1204 &size_to_reserve);
1205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if (ret < 0)
1206 return ret;
1207 #if CONFIG_MATROSKA_MUXER
1208
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
1209
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (qt_id) {
1210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!par->codec_tag)
1211 par->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags,
1212 par->codec_id);
1213
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if ( ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == par->codec_id
1214
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 && (!extradata_size || ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(extradata + 4)) != par->codec_id)
1215 ) {
1216 1 avio_wb32(dyn_cp, 0x5a + extradata_size);
1217 1 avio_wl32(dyn_cp, par->codec_tag);
1218 1 ffio_fill(dyn_cp, 0, 0x5a - 8);
1219 }
1220 1 avio_write(dyn_cp, extradata, extradata_size);
1221 } else {
1222
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (!ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id))
1223 2 av_log(s, AV_LOG_WARNING, "codec %s is not supported by this format\n",
1224 avcodec_get_name(par->codec_id));
1225
1226
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (!par->codec_tag)
1227 2 par->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags,
1228 par->codec_id);
1229
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
4 if (!par->codec_tag && par->codec_id != AV_CODEC_ID_RAWVIDEO) {
1230 av_log(s, AV_LOG_ERROR, "No bmp codec tag found for codec %s\n",
1231 avcodec_get_name(par->codec_id));
1232 return AVERROR(EINVAL);
1233 }
1234
1235 /* If vfw extradata updates are supported, this will have
1236 * to be updated to pass extradata(_size) explicitly. */
1237 4 ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb);
1238 }
1239
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
1240 unsigned int tag;
1241 1 tag = ff_codec_get_tag(ff_codec_wav_tags, par->codec_id);
1242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!tag) {
1243 av_log(s, AV_LOG_ERROR, "No wav codec tag found for codec %s\n",
1244 avcodec_get_name(par->codec_id));
1245 return AVERROR(EINVAL);
1246 }
1247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!par->codec_tag)
1248 par->codec_tag = tag;
1249
1250 /* Same comment as for ff_put_bmp_header applies here. */
1251 1 ff_put_wav_header(s, dyn_cp, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX);
1252 #endif
1253 }
1254
1255 73 *codecpriv_size = avio_get_dyn_buf(dyn_cp, codecpriv);
1256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (dyn_cp->error < 0)
1257 return dyn_cp->error;
1258 73 *max_payload_size = *codecpriv_size + size_to_reserve;
1259
1260 73 return 0;
1261 }
1262
1263 73 static void mkv_put_codecprivate(AVIOContext *pb, unsigned max_payload_size,
1264 const uint8_t *codecpriv, unsigned codecpriv_size)
1265 {
1266 73 unsigned total_codecpriv_size = 0, total_size;
1267
1268 av_assert1(codecpriv_size <= max_payload_size);
1269
1270
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 52 times.
73 if (!max_payload_size)
1271 21 return;
1272
1273 52 total_size = 2 + ebml_length_size(max_payload_size) + max_payload_size;
1274
1275
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 2 times.
52 if (codecpriv_size) {
1276 50 unsigned length_size = ebml_length_size(codecpriv_size);
1277
1278 50 total_codecpriv_size = 2U + length_size + codecpriv_size;
1279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (total_codecpriv_size + 1 == total_size) {
1280 /* It is impossible to add one byte of padding via an EBML Void. */
1281 length_size++;
1282 total_codecpriv_size++;
1283 }
1284 50 put_ebml_id(pb, MATROSKA_ID_CODECPRIVATE);
1285 50 put_ebml_length(pb, codecpriv_size, length_size);
1286 50 avio_write(pb, codecpriv, codecpriv_size);
1287 }
1288
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 48 times.
52 if (total_codecpriv_size < total_size)
1289 4 put_ebml_void(pb, total_size - total_codecpriv_size);
1290 }
1291
1292 5 static int mkv_update_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv,
1293 uint8_t *side_data, int side_data_size,
1294 AVCodecParameters *par, AVIOContext *pb,
1295 mkv_track *track, unsigned alternative_size)
1296 {
1297 5 AVIOContext *const dyn_bc = mkv->tmp_bc;
1298 uint8_t *codecpriv;
1299 unsigned max_payload_size;
1300 int ret, codecpriv_size;
1301
1302 5 ret = mkv_assemble_codecprivate(s, dyn_bc, par,
1303 side_data, side_data_size, 1, 0,
1304 &codecpriv, &codecpriv_size, &max_payload_size);
1305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
1306 goto fail;
1307
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5 if (codecpriv_size > track->codecpriv_size && !alternative_size) {
1308 ret = AVERROR(ENOSPC);
1309 goto fail;
1310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 } else if (codecpriv_size > track->codecpriv_size) {
1311 av_assert1(alternative_size < track->codecpriv_size);
1312 codecpriv_size = alternative_size;
1313 }
1314 5 avio_seek(pb, track->codecpriv_offset, SEEK_SET);
1315 5 mkv_put_codecprivate(pb, track->codecpriv_size,
1316 codecpriv, codecpriv_size);
1317
1318
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (!par->extradata_size) {
1319 2 ret = ff_alloc_extradata(par, side_data_size);
1320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
1321 goto fail;
1322 2 memcpy(par->extradata, side_data, side_data_size);
1323 }
1324 3 fail:
1325 5 ffio_reset_dyn_buf(dyn_bc);
1326 5 return ret;
1327 }
1328
1329 #define MAX_VIDEO_COLOR_ELEMS 20
1330 31 static void mkv_write_video_color(EbmlWriter *writer, const AVStream *st,
1331 const AVCodecParameters *par)
1332 {
1333 const void *side_data;
1334
1335 31 ebml_writer_open_master(writer, MATROSKA_ID_VIDEOCOLOR);
1336
1337
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 20 times.
31 if (par->color_trc != AVCOL_TRC_UNSPECIFIED &&
1338
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 par->color_trc < AVCOL_TRC_NB) {
1339 11 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS,
1340 11 par->color_trc);
1341 }
1342
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 22 times.
31 if (par->color_space != AVCOL_SPC_UNSPECIFIED &&
1343
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 par->color_space < AVCOL_SPC_NB) {
1344 9 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORMATRIXCOEFF,
1345 9 par->color_space);
1346 }
1347
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 22 times.
31 if (par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
1348
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 par->color_primaries < AVCOL_PRI_NB) {
1349 9 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORPRIMARIES,
1350 9 par->color_primaries);
1351 }
1352
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 16 times.
31 if (par->color_range != AVCOL_RANGE_UNSPECIFIED &&
1353
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 par->color_range < AVCOL_RANGE_NB) {
1354 15 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORRANGE, par->color_range);
1355 }
1356
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 14 times.
31 if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED &&
1357
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 par->chroma_location <= AVCHROMA_LOC_TOP) {
1358 int xpos, ypos;
1359
1360 17 av_chroma_location_enum_to_pos(&xpos, &ypos, par->chroma_location);
1361 17 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ,
1362 17 (xpos >> 7) + 1);
1363 17 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT,
1364 17 (ypos >> 7) + 1);
1365 }
1366
1367 31 side_data = av_stream_get_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
1368 NULL);
1369
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if (side_data) {
1370 2 const AVContentLightMetadata *metadata = side_data;
1371 2 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORMAXCLL,
1372 2 metadata->MaxCLL);
1373 2 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOCOLORMAXFALL,
1374 2 metadata->MaxFALL);
1375 }
1376
1377 31 side_data = av_stream_get_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
1378 NULL);
1379
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if (side_data) {
1380 2 const AVMasteringDisplayMetadata *metadata = side_data;
1381 2 ebml_writer_open_master(writer, MATROSKA_ID_VIDEOCOLORMASTERINGMETA);
1382
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (metadata->has_primaries) {
1383 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_RX,
1384 av_q2d(metadata->display_primaries[0][0]));
1385 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_RY,
1386 av_q2d(metadata->display_primaries[0][1]));
1387 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_GX,
1388 av_q2d(metadata->display_primaries[1][0]));
1389 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_GY,
1390 av_q2d(metadata->display_primaries[1][1]));
1391 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_BX,
1392 av_q2d(metadata->display_primaries[2][0]));
1393 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_BY,
1394 av_q2d(metadata->display_primaries[2][1]));
1395 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_WHITEX,
1396 av_q2d(metadata->white_point[0]));
1397 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_WHITEY,
1398 av_q2d(metadata->white_point[1]));
1399 }
1400
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (metadata->has_luminance) {
1401 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX,
1402 av_q2d(metadata->max_luminance));
1403 2 ebml_writer_add_float(writer, MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN,
1404 av_q2d(metadata->min_luminance));
1405 }
1406 2 ebml_writer_close_or_discard_master(writer);
1407 }
1408
1409 31 ebml_writer_close_or_discard_master(writer);
1410 31 }
1411
1412 #define MAX_VIDEO_PROJECTION_ELEMS 6
1413 29 static void mkv_handle_rotation(void *logctx, const AVStream *st,
1414 double *yaw, double *roll)
1415 {
1416 const int32_t *matrix =
1417 29 (const int32_t*)av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
1418
1419
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 2 times.
29 if (!matrix)
1420 27 return;
1421
1422 /* Check whether this is an affine transformation */
1423
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (matrix[2] || matrix[5])
1424 goto ignore;
1425
1426 /* This together with the checks below test whether
1427 * the upper-left 2x2 matrix is nonsingular. */
1428
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (!matrix[0] && !matrix[1])
1429 goto ignore;
1430
1431 /* We ignore the translation part of the matrix (matrix[6] and matrix[7])
1432 * as well as any scaling, i.e. we only look at the upper left 2x2 matrix.
1433 * We only accept matrices that are an exact multiple of an orthogonal one.
1434 * Apart from the multiple, every such matrix can be obtained by
1435 * potentially flipping in the x-direction (corresponding to yaw = 180)
1436 * followed by a rotation of (say) an angle phi in the counterclockwise
1437 * direction. The upper-left 2x2 matrix then looks like this:
1438 * | (+/-)cos(phi) (-/+)sin(phi) |
1439 * scale * | |
1440 * | sin(phi) cos(phi) |
1441 * The first set of signs in the first row apply in case of no flipping,
1442 * the second set applies in case of flipping. */
1443
1444 /* The casts to int64_t are needed because -INT32_MIN doesn't fit
1445 * in an int32_t. */
1446
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if (matrix[0] == matrix[4] && -(int64_t)matrix[1] == matrix[3]) {
1447 /* No flipping case */
1448 1 *yaw = 0;
1449
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 } else if (-(int64_t)matrix[0] == matrix[4] && matrix[1] == matrix[3]) {
1450 /* Horizontal flip */
1451 *yaw = 180;
1452 } else {
1453 1 ignore:
1454 1 av_log(logctx, AV_LOG_INFO, "Ignoring display matrix indicating "
1455 "non-orthogonal transformation.\n");
1456 1 return;
1457 }
1458 1 *roll = 180 / M_PI * atan2(matrix[3], matrix[4]);
1459
1460 /* We do not write a ProjectionType element indicating "rectangular",
1461 * because this is the default value. */
1462 }
1463
1464 31 static int mkv_handle_spherical(void *logctx, EbmlWriter *writer,
1465 const AVStream *st, uint8_t private[],
1466 double *yaw, double *pitch, double *roll)
1467 {
1468 const AVSphericalMapping *spherical =
1469 31 (const AVSphericalMapping *)av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL,
1470 NULL);
1471
1472
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2 times.
31 if (!spherical)
1473 29 return 0;
1474
1475
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
1476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
1477 spherical->projection != AV_SPHERICAL_CUBEMAP) {
1478 av_log(logctx, AV_LOG_WARNING, "Unknown projection type\n");
1479 return 0;
1480 }
1481
1482
1/3
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2 switch (spherical->projection) {
1483 2 case AV_SPHERICAL_EQUIRECTANGULAR:
1484 case AV_SPHERICAL_EQUIRECTANGULAR_TILE:
1485 2 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOPROJECTIONTYPE,
1486 MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR);
1487 2 AV_WB32(private, 0); // version + flags
1488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) {
1489 AV_WB32(private + 4, 0);
1490 AV_WB32(private + 8, 0);
1491 AV_WB32(private + 12, 0);
1492 AV_WB32(private + 16, 0);
1493 } else {
1494 2 AV_WB32(private + 4, spherical->bound_top);
1495 2 AV_WB32(private + 8, spherical->bound_bottom);
1496 2 AV_WB32(private + 12, spherical->bound_left);
1497 2 AV_WB32(private + 16, spherical->bound_right);
1498 }
1499 2 ebml_writer_add_bin(writer, MATROSKA_ID_VIDEOPROJECTIONPRIVATE,
1500 private, 20);
1501 2 break;
1502 case AV_SPHERICAL_CUBEMAP:
1503 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOPROJECTIONTYPE,
1504 MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP);
1505 AV_WB32(private, 0); // version + flags
1506 AV_WB32(private + 4, 0); // layout
1507 AV_WB32(private + 8, spherical->padding);
1508 ebml_writer_add_bin(writer, MATROSKA_ID_VIDEOPROJECTIONPRIVATE,
1509 private, 12);
1510 break;
1511 default:
1512 av_assert0(0);
1513 }
1514
1515 2 *yaw = (double) spherical->yaw / (1 << 16);
1516 2 *pitch = (double) spherical->pitch / (1 << 16);
1517 2 *roll = (double) spherical->roll / (1 << 16);
1518
1519 2 return 1; /* Projection included */
1520 }
1521
1522 31 static void mkv_write_video_projection(void *logctx, EbmlWriter *wr,
1523 const AVStream *st, uint8_t private[])
1524 {
1525 31 double yaw = 0, pitch = 0, roll = 0;
1526 int ret;
1527
1528 31 ebml_writer_open_master(wr, MATROSKA_ID_VIDEOPROJECTION);
1529
1530 31 ret = mkv_handle_spherical(logctx, wr, st, private, &yaw, &pitch, &roll);
1531
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2 times.
31 if (!ret)
1532 29 mkv_handle_rotation(logctx, st, &yaw, &roll);
1533
1534
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if (yaw)
1535 2 ebml_writer_add_float(wr, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, yaw);
1536
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if (pitch)
1537 2 ebml_writer_add_float(wr, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, pitch);
1538
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 28 times.
31 if (roll)
1539 3 ebml_writer_add_float(wr, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, roll);
1540
1541 31 ebml_writer_close_or_discard_master(wr);
1542 31 }
1543
1544 #define MAX_FIELD_ORDER_ELEMS 2
1545 31 static void mkv_write_field_order(EbmlWriter *writer, int is_webm,
1546 enum AVFieldOrder field_order)
1547 {
1548
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
31 switch (field_order) {
1549 17 case AV_FIELD_UNKNOWN:
1550 17 break;
1551 10 case AV_FIELD_PROGRESSIVE:
1552 10 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOFLAGINTERLACED,
1553 MATROSKA_VIDEO_INTERLACE_FLAG_PROGRESSIVE);
1554 10 break;
1555 4 case AV_FIELD_TT:
1556 case AV_FIELD_BB:
1557 case AV_FIELD_TB:
1558 case AV_FIELD_BT:
1559 4 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOFLAGINTERLACED,
1560 MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED);
1561
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!is_webm) {
1562 switch (field_order) {
1563 3 case AV_FIELD_TT:
1564 3 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOFIELDORDER,
1565 MATROSKA_VIDEO_FIELDORDER_TT);
1566 3 break;
1567 1 case AV_FIELD_BB:
1568 1 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOFIELDORDER,
1569 MATROSKA_VIDEO_FIELDORDER_BB);
1570 1 break;
1571 case AV_FIELD_TB:
1572 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOFIELDORDER,
1573 MATROSKA_VIDEO_FIELDORDER_TB);
1574 break;
1575 case AV_FIELD_BT:
1576 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOFIELDORDER,
1577 MATROSKA_VIDEO_FIELDORDER_BT);
1578 break;
1579 }
1580 }
1581 }
1582 31 }
1583
1584 #define MAX_STEREO_MODE_ELEMS 1
1585 31 static int mkv_write_stereo_mode(AVFormatContext *s, EbmlWriter *writer,
1586 const AVStream *st, int is_webm,
1587 int *h_width, int *h_height)
1588 {
1589 31 const char *error_message_addendum = "";
1590 const AVDictionaryEntry *tag;
1591 31 MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
1592
1593 /* The following macros create bitfields where the ith bit
1594 * indicates whether the MatroskaVideoStereoModeType with that value
1595 * uses double width/height or is WebM compatible. */
1596 #define FLAG(STEREOMODETYPE, BOOL) | (BOOL) << (STEREOMODETYPE)
1597 #define WDIV1(STEREOMODETYPE, STEREO3DTYPE, FLAGS, WDIV, HDIV, WEBM) \
1598 FLAG(STEREOMODETYPE, WDIV)
1599 #define WDIV2(STEREOMODETYPE, WDIV, HDIV, WEBM) \
1600 FLAG(STEREOMODETYPE, WDIV)
1601 // The zero in the following line consumes the first '|'.
1602 31 const unsigned width_bitfield = 0 STEREOMODE_STEREO3D_MAPPING(WDIV1, WDIV2);
1603
1604 #define HDIV1(STEREOMODETYPE, STEREO3DTYPE, FLAGS, WDIV, HDIV, WEBM) \
1605 FLAG(STEREOMODETYPE, HDIV)
1606 #define HDIV2(STEREOMODETYPE, WDIV, HDIV, WEBM) \
1607 FLAG(STEREOMODETYPE, HDIV)
1608 31 const unsigned height_bitfield = 0 STEREOMODE_STEREO3D_MAPPING(HDIV1, HDIV2);
1609
1610 #define WEBM1(STEREOMODETYPE, STEREO3DTYPE, FLAGS, WDIV, HDIV, WEBM) \
1611 FLAG(STEREOMODETYPE, WEBM)
1612 #define WEBM2(STEREOMODETYPE, WDIV, HDIV, WEBM) \
1613 FLAG(STEREOMODETYPE, WEBM)
1614 31 const unsigned webm_bitfield = 0 STEREOMODE_STEREO3D_MAPPING(WEBM1, WEBM2);
1615
1616 31 *h_width = 1;
1617 31 *h_height = 1;
1618
1619
3/4
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25 times.
56 if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) ||
1620 25 (tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
1621
1622
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 1 times.
48 for (int i = 0; i < MATROSKA_VIDEO_STEREOMODE_TYPE_NB; i++)
1623
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 42 times.
47 if (!strcmp(tag->value, ff_matroska_video_stereo_mode[i])){
1624 5 format = i;
1625 5 break;
1626 }
1627
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (format == MATROSKA_VIDEO_STEREOMODE_TYPE_NB) {
1628 1 long stereo_mode = strtol(tag->value, NULL, 0);
1629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if ((unsigned long)stereo_mode >= MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
1630 goto fail;
1631 1 format = stereo_mode;
1632 }
1633 } else {
1634 const AVStereo3D *stereo;
1635 /* The following macro presumes all MATROSKA_VIDEO_STEREOMODE_TYPE_*
1636 * values to be in the range 0..254. */
1637 #define STEREOMODE(STEREOMODETYPE, STEREO3DTYPE, FLAGS, WDIV, HDIV, WEBM) \
1638 [(STEREO3DTYPE)][!!((FLAGS) & AV_STEREO3D_FLAG_INVERT)] = (STEREOMODETYPE) + 1,
1639 #define NOTHING(STEREOMODETYPE, WDIV, HDIV, WEBM)
1640 static const unsigned char conversion_table[][2] = {
1641 STEREOMODE_STEREO3D_MAPPING(STEREOMODE, NOTHING)
1642 };
1643 int fmt;
1644
1645 25 stereo = (const AVStereo3D*)av_stream_get_side_data(st, AV_PKT_DATA_STEREO3D,
1646 NULL);
1647
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 4 times.
25 if (!stereo)
1648 21 return 0;
1649
1650 /* A garbage AVStereo3D or something with no Matroska analogon. */
1651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ((unsigned)stereo->type >= FF_ARRAY_ELEMS(conversion_table))
1652 return 0;
1653
1654 4 fmt = conversion_table[stereo->type][!!(stereo->flags & AV_STEREO3D_FLAG_INVERT)];
1655 /* Format with no Matroska analogon; ignore it */
1656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!fmt)
1657 return 0;
1658 4 format = fmt - 1;
1659 }
1660
1661 // if webm, do not write unsupported modes
1662
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if (is_webm && !(webm_bitfield >> format)) {
1663 error_message_addendum = " for WebM";
1664 goto fail;
1665 }
1666
1667 10 *h_width = 1 << ((width_bitfield >> format) & 1);
1668 10 *h_height = 1 << ((height_bitfield >> format) & 1);
1669
1670 // write StereoMode if format is valid
1671 10 ebml_writer_add_uint(writer, MATROSKA_ID_VIDEOSTEREOMODE, format);
1672
1673 10 return 0;
1674 fail:
1675 av_log(s, AV_LOG_ERROR,
1676 "The specified stereo mode is not valid%s.\n",
1677 error_message_addendum);
1678 return AVERROR(EINVAL);
1679 }
1680
1681 65 static void mkv_write_blockadditionmapping(AVFormatContext *s, const MatroskaMuxContext *mkv,
1682 const AVCodecParameters *par, AVIOContext *pb,
1683 mkv_track *track, const AVStream *st)
1684 {
1685 #if CONFIG_MATROSKA_MUXER
1686 const AVDOVIDecoderConfigurationRecord *dovi;
1687
1688
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 3 times.
65 if (IS_SEEKABLE(s->pb, mkv)) {
1689 57 track->blockadditionmapping_offset = avio_tell(pb);
1690 // We can't know at this point if there will be a block with BlockAdditions, so
1691 // we either write the default value here, or a void element. Either of them will
1692 // be overwritten when finishing the track.
1693 57 put_ebml_uint(pb, MATROSKA_ID_TRACKMAXBLKADDID, 0);
1694
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 29 times.
57 if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
1695 // Similarly, reserve space for an eventual
1696 // HDR10+ ITU T.35 metadata BlockAdditionMapping.
1697 28 put_ebml_void(pb, 3 /* BlockAdditionMapping */
1698 + 4 /* BlockAddIDValue */
1699 + 4 /* BlockAddIDType */);
1700 }
1701 }
1702
1703 dovi = (const AVDOVIDecoderConfigurationRecord *)
1704 65 av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL);
1705
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
65 if (dovi && dovi->dv_profile <= 10) {
1706 ebml_master mapping;
1707 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
1708 uint32_t type;
1709
1710 2 uint64_t expected_size = (2 + 1 + (sizeof(DVCC_DVVC_BLOCK_TYPE_NAME) - 1))
1711 + (2 + 1 + 4) + (2 + 1 + ISOM_DVCC_DVVC_SIZE);
1712
1713
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (dovi->dv_profile > 7) {
1714 1 type = MATROSKA_BLOCK_ADD_ID_TYPE_DVVC;
1715 } else {
1716 1 type = MATROSKA_BLOCK_ADD_ID_TYPE_DVCC;
1717 }
1718
1719 2 ff_isom_put_dvcc_dvvc(s, buf, dovi);
1720
1721 2 mapping = start_ebml_master(pb, MATROSKA_ID_TRACKBLKADDMAPPING, expected_size);
1722
1723 2 put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, DVCC_DVVC_BLOCK_TYPE_NAME);
1724 2 put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type);
1725 2 put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, sizeof(buf));
1726
1727 2 end_ebml_master(pb, mapping);
1728 }
1729 #endif
1730 65 }
1731
1732 31 static int mkv_write_track_video(AVFormatContext *s, MatroskaMuxContext *mkv,
1733 const AVStream *st, const AVCodecParameters *par,
1734 AVIOContext *pb)
1735 {
1736 const AVDictionaryEntry *tag;
1737 31 int display_width_div = 1, display_height_div = 1;
1738 uint8_t color_space[4], projection_private[20];
1739 31 EBML_WRITER(MAX_FIELD_ORDER_ELEMS + MAX_STEREO_MODE_ELEMS +
1740 MAX_VIDEO_COLOR_ELEMS + MAX_VIDEO_PROJECTION_ELEMS + 8);
1741 int ret;
1742
1743 31 ebml_writer_open_master(&writer, MATROSKA_ID_TRACKVIDEO);
1744
1745 31 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEOPIXELWIDTH , par->width);
1746 31 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEOPIXELHEIGHT, par->height);
1747
1748 31 mkv_write_field_order(&writer, IS_WEBM(mkv), par->field_order);
1749
1750 // check both side data and metadata for stereo information,
1751 // write the result to the bitstream if any is found
1752 31 ret = mkv_write_stereo_mode(s, &writer, st, IS_WEBM(mkv),
1753 &display_width_div,
1754 &display_height_div);
1755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
1756 return ret;
1757
1758
3/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 1 times.
62 if (par->format == AV_PIX_FMT_YUVA420P ||
1759
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
61 ((tag = av_dict_get(st->metadata, "alpha_mode", NULL, 0)) ||
1760
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
31 (tag = av_dict_get( s->metadata, "alpha_mode", NULL, 0))) && strtol(tag->value, NULL, 0))
1761 1 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEOALPHAMODE, 1);
1762
1763 // write DisplayWidth and DisplayHeight, they contain the size of
1764 // a single source view and/or the display aspect ratio
1765
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 14 times.
31 if (st->sample_aspect_ratio.num) {
1766 17 int64_t d_width = av_rescale(par->width, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
1767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (d_width > INT_MAX) {
1768 av_log(s, AV_LOG_ERROR, "Overflow in display width\n");
1769 return AVERROR(EINVAL);
1770 }
1771
4/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
17 if (d_width != par->width || display_width_div != 1 || display_height_div != 1) {
1772
6/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 6 times.
9 if (IS_WEBM(mkv) || display_width_div != 1 || display_height_div != 1) {
1773 3 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYWIDTH,
1774 3 d_width / display_width_div);
1775 3 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYHEIGHT,
1776 3 par->height / display_height_div);
1777 } else {
1778 AVRational display_aspect_ratio;
1779 6 av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
1780 6 par->width * (int64_t)st->sample_aspect_ratio.num,
1781 6 par->height * (int64_t)st->sample_aspect_ratio.den,
1782 1024 * 1024);
1783 6 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYWIDTH,
1784 6 display_aspect_ratio.num);
1785 6 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYHEIGHT,
1786 6 display_aspect_ratio.den);
1787 6 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYUNIT,
1788 MATROSKA_VIDEO_DISPLAYUNIT_DAR);
1789 }
1790 }
1791
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 12 times.
14 } else if (display_width_div != 1 || display_height_div != 1) {
1792 2 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYWIDTH,
1793 2 par->width / display_width_div);
1794 2 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYHEIGHT,
1795 2 par->height / display_height_div);
1796
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 } else if (!IS_WEBM(mkv))
1797 12 ebml_writer_add_uint(&writer, MATROSKA_ID_VIDEODISPLAYUNIT,
1798 MATROSKA_VIDEO_DISPLAYUNIT_UNKNOWN);
1799
1800
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if (par->codec_id == AV_CODEC_ID_RAWVIDEO) {
1801 2 AV_WL32(color_space, par->codec_tag);
1802 2 ebml_writer_add_bin(&writer, MATROSKA_ID_VIDEOCOLORSPACE,
1803 color_space, sizeof(color_space));
1804 }
1805 31 mkv_write_video_color(&writer, st, par);
1806 31 mkv_write_video_projection(s, &writer, st, projection_private);
1807
1808 31 return ebml_writer_write(&writer, pb);
1809 }
1810
1811 37 static void mkv_write_default_duration(mkv_track *track, AVIOContext *pb,
1812 AVRational duration)
1813 {
1814 37 put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION,
1815 37 1000000000LL * duration.num / duration.den);
1816 37 track->default_duration_low = 1000LL * duration.num / duration.den;
1817 37 track->default_duration_high = track->default_duration_low +
1818 37 !!(1000LL * duration.num % duration.den);
1819 37 }
1820
1821 73 static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
1822 AVStream *st, mkv_track *track, AVIOContext *pb,
1823 int is_default)
1824 {
1825 73 AVCodecParameters *par = st->codecpar;
1826 ebml_master subinfo, track_master;
1827 73 int native_id = 0;
1828 73 int qt_id = 0;
1829 int bit_depth;
1830 73 int sample_rate = par->sample_rate;
1831 73 int output_sample_rate = 0;
1832 int j, ret;
1833 const AVDictionaryEntry *tag;
1834
1835
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 72 times.
73 if (par->codec_type == AVMEDIA_TYPE_ATTACHMENT)
1836 1 return 0;
1837
1838 72 track_master = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0);
1839 72 put_ebml_uint(pb, MATROSKA_ID_TRACKNUMBER, track->track_num);
1840 72 put_ebml_uid (pb, MATROSKA_ID_TRACKUID, track->uid);
1841 72 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGLACING, 0); // no lacing (yet)
1842
1843
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 69 times.
72 if ((tag = av_dict_get(st->metadata, "title", NULL, 0)))
1844 3 put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
1845 72 tag = av_dict_get(st->metadata, "language", NULL, 0);
1846
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 39 times.
105 put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE,
1847
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 tag && tag->value[0] ? tag->value : "und");
1848
1849 // The default value for TRACKFLAGDEFAULT is 1, so add element
1850 // if we need to clear it.
1851
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 29 times.
72 if (!is_default)
1852 43 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, 0);
1853
1854
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 70 times.
72 if (st->disposition & AV_DISPOSITION_FORCED)
1855 2 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1);
1856
1857
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 65 times.
72 if (IS_WEBM(mkv)) {
1858 const char *codec_id;
1859
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (par->codec_id != AV_CODEC_ID_WEBVTT) {
1860
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 for (j = 0; ff_webm_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
1861
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
9 if (ff_webm_codec_tags[j].id == par->codec_id) {
1862 3 codec_id = ff_webm_codec_tags[j].str;
1863 3 native_id = 1;
1864 3 break;
1865 }
1866 }
1867 } else {
1868
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (st->disposition & AV_DISPOSITION_CAPTIONS) {
1869 1 codec_id = "D_WEBVTT/CAPTIONS";
1870 1 native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
1871
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 } else if (st->disposition & AV_DISPOSITION_DESCRIPTIONS) {
1872 1 codec_id = "D_WEBVTT/DESCRIPTIONS";
1873 1 native_id = MATROSKA_TRACK_TYPE_METADATA;
1874
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 } else if (st->disposition & AV_DISPOSITION_METADATA) {
1875 1 codec_id = "D_WEBVTT/METADATA";
1876 1 native_id = MATROSKA_TRACK_TYPE_METADATA;
1877 } else {
1878 1 codec_id = "D_WEBVTT/SUBTITLES";
1879 1 native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
1880 }
1881 }
1882
1883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!native_id) {
1884 av_log(s, AV_LOG_ERROR,
1885 "Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.\n");
1886 return AVERROR(EINVAL);
1887 }
1888
1889 7 put_ebml_string(pb, MATROSKA_ID_CODECID, codec_id);
1890 } else {
1891
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 64 times.
65 if (st->disposition & AV_DISPOSITION_COMMENT)
1892 1 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGCOMMENTARY, 1);
1893
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 61 times.
65 if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
1894 4 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGHEARINGIMPAIRED, 1);
1895
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 64 times.
65 if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
1896 1 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGVISUALIMPAIRED, 1);
1897
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 63 times.
65 if (st->disposition & (AV_DISPOSITION_ORIGINAL | AV_DISPOSITION_DUB) &&
1898
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 (st->disposition & (AV_DISPOSITION_ORIGINAL | AV_DISPOSITION_DUB))
1899 != (AV_DISPOSITION_ORIGINAL | AV_DISPOSITION_DUB))
1900 2 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGORIGINAL,
1901 2 !!(st->disposition & AV_DISPOSITION_ORIGINAL));
1902
1903 // look for a codec ID string specific to mkv to use,
1904 // if none are found, use AVI codes
1905
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 1 times.
65 if (par->codec_id == AV_CODEC_ID_FFV1) {
1906 /* FFV1 is actually supported natively in Matroska,
1907 * yet we use the VfW way to mux it for compatibility
1908 * with old demuxers. (FIXME: Are they really important?) */
1909
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
64 } else if (par->codec_id != AV_CODEC_ID_RAWVIDEO || par->codec_tag) {
1910
2/2
✓ Branch 0 taken 2346 times.
✓ Branch 1 taken 3 times.
2349 for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
1911
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 2287 times.
2346 if (ff_mkv_codec_tags[j].id == par->codec_id) {
1912 59 put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
1913 59 native_id = 1;
1914 59 break;
1915 }
1916 }
1917 } else {
1918
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mkv->allow_raw_vfw) {
1919 2 native_id = 0;
1920 } else {
1921 av_log(s, AV_LOG_ERROR, "Raw RGB is not supported Natively in Matroska, you can use AVI or NUT or\n"
1922 "If you would like to store it anyway using VFW mode, enable allow_raw_vfw (-allow_raw_vfw 1)\n");
1923 return AVERROR(EINVAL);
1924 }
1925 }
1926 }
1927
1928
3/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
72 switch (par->codec_type) {
1929 AVRational frame_rate;
1930 int audio_frame_samples;
1931
1932 31 case AVMEDIA_TYPE_VIDEO:
1933 31 mkv->have_video = 1;
1934 31 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
1935
1936 31 frame_rate = (AVRational){ 0, 1 };
1937
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
31 if (st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0)
1938 29 frame_rate = st->avg_frame_rate;
1939
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 else if (st->r_frame_rate.num > 0 && st->r_frame_rate.den > 0)
1940 1 frame_rate = st->r_frame_rate;
1941
1942
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 1 times.
31 if (frame_rate.num > 0)
1943 30 mkv_write_default_duration(track, pb, av_inv_q(frame_rate));
1944
1945
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
36 if (CONFIG_MATROSKA_MUXER && !native_id &&
1946
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
8 ff_codec_get_tag(ff_codec_movvideo_tags, par->codec_id) &&
1947
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
5 ((!ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id) && par->codec_id != AV_CODEC_ID_RAWVIDEO) ||
1948
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 par->codec_id == AV_CODEC_ID_SVQ1 ||
1949
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 par->codec_id == AV_CODEC_ID_SVQ3 ||
1950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 par->codec_id == AV_CODEC_ID_CINEPAK))
1951 1 qt_id = 1;
1952
1953
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 30 times.
31 if (qt_id)
1954 1 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME");
1955
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 26 times.
30 else if (!native_id) {
1956 // if there is no mkv-specific codec ID, use VFW mode
1957 4 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC");
1958 4 track->write_dts = 1;
1959 4 ffformatcontext(s)->avoid_negative_ts_use_pts = 0;
1960 }
1961
1962 31 ret = mkv_write_track_video(s, mkv, st, par, pb);
1963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
1964 return ret;
1965
1966 31 break;
1967
1968 30 case AVMEDIA_TYPE_AUDIO:
1969
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 25 times.
30 if (par->initial_padding) {
1970 5 int64_t codecdelay = av_rescale_q(par->initial_padding,
1971 5 (AVRational){ 1, par->sample_rate },
1972 5 (AVRational){ 1, 1000000000 });
1973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (codecdelay < 0) {
1974 av_log(s, AV_LOG_ERROR, "Initial padding is invalid\n");
1975 return AVERROR(EINVAL);
1976 }
1977 5 put_ebml_uint(pb, MATROSKA_ID_CODECDELAY, codecdelay);
1978
1979 5 track->ts_offset = av_rescale_q(par->initial_padding,
1980 5 (AVRational){ 1, par->sample_rate },
1981 st->time_base);
1982 5 ffstream(st)->lowest_ts_allowed = -track->ts_offset;
1983 }
1984
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 28 times.
30 if (par->codec_id == AV_CODEC_ID_OPUS)
1985 2 put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL);
1986 #if CONFIG_MATROSKA_MUXER
1987
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 22 times.
28 else if (par->codec_id == AV_CODEC_ID_AAC) {
1988 6 ret = get_aac_sample_rates(s, mkv, par->extradata, par->extradata_size,
1989 &sample_rate, &output_sample_rate);
1990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
1991 return ret;
1992 }
1993 #endif
1994
1995 30 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO);
1996
1997 30 audio_frame_samples = av_get_audio_frame_duration2(par, 0);
1998
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 23 times.
30 if (audio_frame_samples)
1999 7 mkv_write_default_duration(track, pb, (AVRational){ audio_frame_samples,
2000 7 par->sample_rate });
2001
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
30 if (!native_id)
2002 // no mkv-specific ID, use ACM mode
2003 1 put_ebml_string(pb, MATROSKA_ID_CODECID, "A_MS/ACM");
2004
2005 30 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 6 + 4 * 9);
2006 30 put_ebml_uint(pb, MATROSKA_ID_AUDIOCHANNELS, par->ch_layout.nb_channels);
2007
2008 30 track->sample_rate_offset = avio_tell(pb);
2009 30 put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate);
2010
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
30 if (output_sample_rate)
2011 1 put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate);
2012
2013 30 bit_depth = av_get_bits_per_sample(par->codec_id);
2014
3/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
30 if (!bit_depth && par->codec_id != AV_CODEC_ID_ADPCM_G726) {
2015
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 13 times.
23 if (par->bits_per_raw_sample)
2016 10 bit_depth = par->bits_per_raw_sample;
2017 else
2018 13 bit_depth = av_get_bytes_per_sample(par->format) << 3;
2019 }
2020
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
30 if (!bit_depth)
2021 1 bit_depth = par->bits_per_coded_sample;
2022
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (bit_depth)
2023 30 put_ebml_uint(pb, MATROSKA_ID_AUDIOBITDEPTH, bit_depth);
2024 30 end_ebml_master(pb, subinfo);
2025 30 break;
2026
2027 11 case AVMEDIA_TYPE_SUBTITLE:
2028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!native_id) {
2029 av_log(s, AV_LOG_ERROR, "Subtitle codec %d is not supported.\n", par->codec_id);
2030 return AVERROR(ENOSYS);
2031 }
2032
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
11 if (!IS_WEBM(mkv) && st->disposition & AV_DISPOSITION_DESCRIPTIONS)
2033 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGTEXTDESCRIPTIONS, 1);
2034
2035
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
11 if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT)
2036 7 native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
2037
2038 11 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, native_id);
2039 11 break;
2040 default:
2041 av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska.\n");
2042 return AVERROR(EINVAL);
2043 }
2044
2045
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 7 times.
72 if (!IS_WEBM(mkv))
2046 65 mkv_write_blockadditionmapping(s, mkv, par, pb, track, st);
2047
2048
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 4 times.
72 if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT) {
2049 uint8_t *codecpriv;
2050 int codecpriv_size, max_payload_size;
2051 68 track->codecpriv_offset = avio_tell(pb);
2052 68 ret = mkv_assemble_codecprivate(s, mkv->tmp_bc, par,
2053 68 par->extradata, par->extradata_size,
2054 native_id, qt_id,
2055 &codecpriv, &codecpriv_size, &max_payload_size);
2056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if (ret < 0)
2057 goto fail;
2058 68 mkv_put_codecprivate(pb, max_payload_size, codecpriv, codecpriv_size);
2059 68 track->codecpriv_size = max_payload_size;
2060 }
2061
2062 72 end_ebml_master(pb, track_master);
2063 72 ret = 0;
2064 72 fail:
2065 72 ffio_reset_dyn_buf(mkv->tmp_bc);
2066
2067 72 return ret;
2068 }
2069
2070 42 static int mkv_write_tracks(AVFormatContext *s)
2071 {
2072 42 MatroskaMuxContext *mkv = s->priv_data;
2073 42 AVIOContext *pb = s->pb;
2074 42 int video_default_idx = -1, audio_default_idx = -1, subtitle_default_idx = -1;
2075 int i, ret;
2076
2077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (mkv->nb_attachments == s->nb_streams)
2078 return 0;
2079
2080 42 ret = start_ebml_master_crc32(&mkv->track.bc, mkv);
2081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (ret < 0)
2082 return ret;
2083
2084
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 39 times.
42 if (mkv->default_mode != DEFAULT_MODE_PASSTHROUGH) {
2085 3 int video_idx = -1, audio_idx = -1, subtitle_idx = -1;
2086
2087
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
13 for (i = s->nb_streams - 1; i >= 0; i--) {
2088 10 AVStream *st = s->streams[i];
2089
2090
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
10 switch (st->codecpar->codec_type) {
2091 #define CASE(type, variable) \
2092 case AVMEDIA_TYPE_ ## type: \
2093 variable ## _idx = i; \
2094 if (st->disposition & AV_DISPOSITION_DEFAULT) \
2095 variable ## _default_idx = i; \
2096 break;
2097
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 CASE(VIDEO, video)
2098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 CASE(AUDIO, audio)
2099
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 CASE(SUBTITLE, subtitle)
2100 #undef CASE
2101 }
2102 }
2103
2104 3 video_default_idx = FFMAX(video_default_idx, video_idx);
2105 3 audio_default_idx = FFMAX(audio_default_idx, audio_idx);
2106
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (mkv->default_mode != DEFAULT_MODE_INFER_NO_SUBS)
2107 2 subtitle_default_idx = FFMAX(subtitle_default_idx, subtitle_idx);
2108 }
2109
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 42 times.
115 for (i = 0; i < s->nb_streams; i++) {
2110 73 AVStream *st = s->streams[i];
2111
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 int is_default = st->disposition & AV_DISPOSITION_DEFAULT ||
2112
5/6
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
118 i == video_default_idx || i == audio_default_idx ||
2113 i == subtitle_default_idx;
2114 73 ret = mkv_write_track(s, mkv, st, &mkv->tracks[i],
2115 mkv->track.bc, is_default);
2116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (ret < 0)
2117 return ret;
2118 }
2119
2120 42 return end_ebml_master_crc32_tentatively(pb, &mkv->track, mkv,
2121 MATROSKA_ID_TRACKS);
2122 }
2123
2124 121 static int mkv_write_simpletag(AVIOContext *pb, const AVDictionaryEntry *t)
2125 {
2126 121 EBML_WRITER(4);
2127 121 uint8_t *key = av_strdup(t->key);
2128 121 uint8_t *p = key;
2129 121 const uint8_t *lang = NULL;
2130 int ret;
2131
2132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 121 times.
121 if (!key)
2133 return AVERROR(ENOMEM);
2134
2135
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2 times.
128 if ((p = strrchr(p, '-')) &&
2136 7 (lang = ff_convert_lang_to(p + 1, AV_LANG_ISO639_2_BIBL)))
2137 5 *p = 0;
2138
2139 121 p = key;
2140
2/2
✓ Branch 0 taken 1396 times.
✓ Branch 1 taken 121 times.
1517 while (*p) {
2141
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1395 times.
1396 if (*p == ' ')
2142 1 *p = '_';
2143
3/4
✓ Branch 0 taken 1225 times.
✓ Branch 1 taken 170 times.
✓ Branch 2 taken 1225 times.
✗ Branch 3 not taken.
1395 else if (*p >= 'a' && *p <= 'z')
2144 1225 *p -= 'a' - 'A';
2145 1396 p++;
2146 }
2147
2148 121 ebml_writer_open_master(&writer, MATROSKA_ID_SIMPLETAG);
2149 121 ebml_writer_add_string(&writer, MATROSKA_ID_TAGNAME, key);
2150
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 116 times.
121 if (lang)
2151 5 ebml_writer_add_string(&writer, MATROSKA_ID_TAGLANG, lang);
2152 121 ebml_writer_add_string(&writer, MATROSKA_ID_TAGSTRING, t->value);
2153 121 ret = ebml_writer_write(&writer, pb);
2154
2155 121 av_freep(&key);
2156 121 return ret;
2157 }
2158
2159 115 static void mkv_write_tag_targets(MatroskaMuxContext *mkv, AVIOContext *pb,
2160 uint32_t elementid, uint64_t uid)
2161 {
2162 115 ebml_master targets = start_ebml_master(pb, MATROSKA_ID_TAGTARGETS,
2163 4 + 1 + 8);
2164
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 42 times.
115 if (elementid)
2165 73 put_ebml_uid(pb, elementid, uid);
2166 115 end_ebml_master(pb, targets);
2167 115 }
2168
2169 188 static int mkv_check_tag_name(const char *name, uint32_t elementid)
2170 {
2171
2/2
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 6 times.
367 return av_strcasecmp(name, "title") &&
2172
2/2
✓ Branch 1 taken 161 times.
✓ Branch 2 taken 12 times.
352 av_strcasecmp(name, "stereo_mode") &&
2173
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
334 av_strcasecmp(name, "creation_time") &&
2174
2/2
✓ Branch 1 taken 156 times.
✓ Branch 2 taken 5 times.
322 av_strcasecmp(name, "encoding_tool") &&
2175
2/2
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 63 times.
317 av_strcasecmp(name, "duration") &&
2176
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 33 times.
93 (elementid != MATROSKA_ID_TAGTARGETS_TRACKUID ||
2177
4/4
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 9 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 121 times.
462 av_strcasecmp(name, "language")) &&
2178
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 (elementid != MATROSKA_ID_TAGTARGETS_ATTACHUID ||
2179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
3 (av_strcasecmp(name, "filename") &&
2180 1 av_strcasecmp(name, "mimetype")));
2181 }
2182
2183 115 static int mkv_write_tag(MatroskaMuxContext *mkv, const AVDictionary *m,
2184 AVIOContext **pb, unsigned reserved_size,
2185 uint32_t elementid, uint64_t uid)
2186 {
2187 115 const AVDictionaryEntry *t = NULL;
2188 115 AVIOContext *const tmp_bc = mkv->tmp_bc;
2189 uint8_t *buf;
2190 115 int ret = 0, size, tag_written = 0;
2191
2192 115 mkv_write_tag_targets(mkv, tmp_bc, elementid, uid);
2193
2194
2/2
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 115 times.
303 while ((t = av_dict_iterate(m, t))) {
2195
2/2
✓ Branch 1 taken 121 times.
✓ Branch 2 taken 67 times.
188 if (mkv_check_tag_name(t->key, elementid)) {
2196 121 ret = mkv_write_simpletag(tmp_bc, t);
2197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 121 times.
121 if (ret < 0)
2198 goto end;
2199 121 tag_written = 1;
2200 }
2201 }
2202
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 51 times.
115 if (reserved_size)
2203 64 put_ebml_void(tmp_bc, reserved_size);
2204
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 14 times.
51 else if (!tag_written)
2205 37 goto end;
2206
2207 78 size = avio_get_dyn_buf(tmp_bc, &buf);
2208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
78 if (tmp_bc->error) {
2209 ret = tmp_bc->error;
2210 goto end;
2211 }
2212
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 40 times.
78 if (!*pb) {
2213 38 ret = start_ebml_master_crc32(pb, mkv);
2214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0)
2215 goto end;
2216 }
2217 78 put_ebml_binary(*pb, MATROSKA_ID_TAG, buf, size);
2218
2219 115 end:
2220 115 ffio_reset_dyn_buf(tmp_bc);
2221 115 return ret;
2222 }
2223
2224 42 static int mkv_write_tags(AVFormatContext *s)
2225 {
2226 42 MatroskaMuxContext *mkv = s->priv_data;
2227
4/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 3 times.