Mercurial > libavformat.hg
annotate matroskaenc.c @ 6048:e507a21a9566 libavformat
matroskaenc: Write codec time base as default duration for video tracks.
This isn't exactly semantically equivalent, but the field has already been
long abused to mean this, and writing it helps in determining a decent cfr
time base when transcoding from a mkv where the video codec stores none (VP8).
author | conrad |
---|---|
date | Mon, 24 May 2010 08:58:19 +0000 |
parents | 02815f232ad3 |
children | 72c7c3d5c4e9 |
rev | line source |
---|---|
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
1 /* |
2495 | 2 * Matroska muxer |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
3 * Copyright (c) 2007 David Conrad |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
4 * |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
5 * This file is part of FFmpeg. |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
6 * |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
11 * |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
16 * |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
20 */ |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
21 |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
22 #include "avformat.h" |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
23 #include "riff.h" |
3601 | 24 #include "isom.h" |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
25 #include "matroska.h" |
2923
0fde8da65761
Use the isom avcc formatting for h264 extradata in matroska.
aurel
parents:
2771
diff
changeset
|
26 #include "avc.h" |
4581
c52d40f0a955
Share the function to write a raw FLAC header and use it in the Matroska
jbr
parents:
4578
diff
changeset
|
27 #include "flacenc.h" |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
4002
diff
changeset
|
28 #include "libavutil/intreadwrite.h" |
3286 | 29 #include "libavutil/md5.h" |
30 #include "libavcodec/xiph.h" | |
3201 | 31 #include "libavcodec/mpeg4audio.h" |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
32 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
33 typedef struct ebml_master { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
34 int64_t pos; ///< absolute offset in the file where the master's elements start |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
35 int sizebytes; ///< how many bytes were reserved for the size |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
36 } ebml_master; |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
37 |
2447 | 38 typedef struct mkv_seekhead_entry { |
39 unsigned int elementid; | |
40 uint64_t segmentpos; | |
41 } mkv_seekhead_entry; | |
42 | |
43 typedef struct mkv_seekhead { | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
44 int64_t filepos; |
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
45 int64_t segment_offset; ///< the file offset to the beginning of the segment |
2450 | 46 int reserved_size; ///< -1 if appending to file |
2447 | 47 int max_entries; |
48 mkv_seekhead_entry *entries; | |
49 int num_entries; | |
50 } mkv_seekhead; | |
51 | |
2451 | 52 typedef struct { |
53 uint64_t pts; | |
54 int tracknum; | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
55 int64_t cluster_pos; ///< file offset of the cluster containing the block |
2451 | 56 } mkv_cuepoint; |
57 | |
58 typedef struct { | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
59 int64_t segment_offset; |
2451 | 60 mkv_cuepoint *entries; |
61 int num_entries; | |
62 } mkv_cues; | |
63 | |
5793 | 64 typedef struct { |
65 int write_dts; | |
66 } mkv_track; | |
67 | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
68 typedef struct MatroskaMuxContext { |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
69 ByteIOContext *dyn_bc; |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
70 ebml_master segment; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
71 int64_t segment_offset; |
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
72 int64_t segment_uid; |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
73 ebml_master cluster; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
74 int64_t cluster_pos; ///< file offset of the current cluster |
5795 | 75 int64_t cluster_pts; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
76 int64_t duration_offset; |
5795 | 77 int64_t duration; |
2447 | 78 mkv_seekhead *main_seekhead; |
79 mkv_seekhead *cluster_seekhead; | |
2451 | 80 mkv_cues *cues; |
5793 | 81 mkv_track *tracks; |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
82 |
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
83 struct AVMD5 *md5_ctx; |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
84 } MatroskaMuxContext; |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
85 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
86 |
2506 | 87 /** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit |
88 * offset, 4 bytes for target EBML ID */ | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
89 #define MAX_SEEKENTRY_SIZE 21 |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
90 |
2506 | 91 /** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2 |
92 * 8-byte uint max */ | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
93 #define MAX_CUETRACKPOS_SIZE 22 |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
94 |
2506 | 95 /** per-cuepoint - 2 1-byte EBML IDs, 2 1-byte EBML sizes, 8-byte uint max */ |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
96 #define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
97 |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
98 |
2481 | 99 static int ebml_id_size(unsigned int id) |
100 { | |
101 return (av_log2(id+1)-1)/7+1; | |
102 } | |
103 | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
104 static void put_ebml_id(ByteIOContext *pb, unsigned int id) |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
105 { |
2482 | 106 int i = ebml_id_size(id); |
107 while (i--) | |
108 put_byte(pb, id >> (i*8)); | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
109 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
110 |
2480 | 111 /** |
2530 | 112 * Write an EBML size meaning "unknown size". |
2480 | 113 * |
2530 | 114 * @param bytes The number of bytes the size should occupy (maximum: 8). |
2480 | 115 */ |
116 static void put_ebml_size_unknown(ByteIOContext *pb, int bytes) | |
117 { | |
2497 | 118 assert(bytes <= 8); |
2496 | 119 put_byte(pb, 0x1ff >> bytes); |
120 while (--bytes) | |
121 put_byte(pb, 0xff); | |
2480 | 122 } |
123 | |
2484
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
124 /** |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
125 * Calculate how many bytes are needed to represent a given number in EBML. |
2484
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
126 */ |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
127 static int ebml_num_size(uint64_t num) |
2484
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
128 { |
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
129 int bytes = 1; |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
130 while ((num+1) >> bytes*7) bytes++; |
2484
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
131 return bytes; |
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
132 } |
60428e4e5242
Move calculating the bytes needed to represent a size in EBML to its own function
conrad
parents:
2483
diff
changeset
|
133 |
2487
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
134 /** |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
135 * Write a number in EBML variable length format. |
2487
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
136 * |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
137 * @param bytes The number of bytes that need to be used to write the number. |
2487
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
138 * If zero, any number of bytes can be used. |
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
139 */ |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
140 static void put_ebml_num(ByteIOContext *pb, uint64_t num, int bytes) |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
141 { |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
142 int i, needed_bytes = ebml_num_size(num); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
143 |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
144 // sizes larger than this are currently undefined in EBML |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
145 assert(num < (1ULL<<56)-1); |
2440
69e2592531b6
Write unknown size if the size given is too large for EBML (greater than 2^56-1)
conrad
parents:
2439
diff
changeset
|
146 |
2487
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
147 if (bytes == 0) |
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
148 // don't care how many bytes are used, so use the min |
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
149 bytes = needed_bytes; |
2498 | 150 // the bytes needed to write the given size would exceed the bytes |
151 // that we need to use, so write unknown size. This shouldn't happen. | |
2497 | 152 assert(bytes >= needed_bytes); |
2487
9a9c45b95c6f
Modify put_ebml_size() so that the bytes parameter is exact rather than minimum
conrad
parents:
2486
diff
changeset
|
153 |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
154 num |= 1ULL << bytes*7; |
2485 | 155 for (i = bytes - 1; i >= 0; i--) |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
156 put_byte(pb, num >> i*8); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
157 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
158 |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
159 static void put_ebml_uint(ByteIOContext *pb, unsigned int elementid, uint64_t val) |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
160 { |
2483 | 161 int i, bytes = 1; |
3097 | 162 uint64_t tmp = val; |
163 while (tmp>>=8) bytes++; | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
164 |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
165 put_ebml_id(pb, elementid); |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
166 put_ebml_num(pb, bytes, 0); |
2483 | 167 for (i = bytes - 1; i >= 0; i--) |
168 put_byte(pb, val >> i*8); | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
169 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
170 |
2430 | 171 static void put_ebml_float(ByteIOContext *pb, unsigned int elementid, double val) |
172 { | |
173 put_ebml_id(pb, elementid); | |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
174 put_ebml_num(pb, 8, 0); |
2430 | 175 put_be64(pb, av_dbl2int(val)); |
176 } | |
177 | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
178 static void put_ebml_binary(ByteIOContext *pb, unsigned int elementid, |
2429 | 179 const uint8_t *buf, int size) |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
180 { |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
181 put_ebml_id(pb, elementid); |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
182 put_ebml_num(pb, size, 0); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
183 put_buffer(pb, buf, size); |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
184 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
185 |
2429 | 186 static void put_ebml_string(ByteIOContext *pb, unsigned int elementid, const char *str) |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
187 { |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
188 put_ebml_binary(pb, elementid, str, strlen(str)); |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
189 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
190 |
2477 | 191 /** |
2494 | 192 * Writes a void element of a given size. Useful for reserving space in |
193 * the file to be written to later. | |
2477 | 194 * |
2491 | 195 * @param size The number of bytes to reserve, which must be at least 2. |
2477 | 196 */ |
2442 | 197 static void put_ebml_void(ByteIOContext *pb, uint64_t size) |
198 { | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
199 int64_t currentpos = url_ftell(pb); |
2442 | 200 |
2497 | 201 assert(size >= 2); |
2442 | 202 |
203 put_ebml_id(pb, EBML_ID_VOID); | |
2494 | 204 // we need to subtract the length needed to store the size from the |
205 // size we need to reserve so 2 cases, we use 8 bytes to store the | |
206 // size if possible, 1 byte otherwise | |
2442 | 207 if (size < 10) |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
208 put_ebml_num(pb, size-1, 0); |
2442 | 209 else |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
210 put_ebml_num(pb, size-9, 8); |
2928
bdc992cb8e46
Write 0 instead of seeking forward (and leaving bytes uninitalized),
michael
parents:
2927
diff
changeset
|
211 while(url_ftell(pb) < currentpos + size) |
bdc992cb8e46
Write 0 instead of seeking forward (and leaving bytes uninitalized),
michael
parents:
2927
diff
changeset
|
212 put_byte(pb, 0); |
2442 | 213 } |
214 | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
215 static ebml_master start_ebml_master(ByteIOContext *pb, unsigned int elementid, uint64_t expectedsize) |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
216 { |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
217 int bytes = expectedsize ? ebml_num_size(expectedsize) : 8; |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
218 put_ebml_id(pb, elementid); |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
219 put_ebml_size_unknown(pb, bytes); |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
220 return (ebml_master){ url_ftell(pb), bytes }; |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
221 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
222 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
223 static void end_ebml_master(ByteIOContext *pb, ebml_master master) |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
224 { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
225 int64_t pos = url_ftell(pb); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
226 |
5743
0c1e9df4e3cd
Attempt seeking to write EBML master sizes even if streamed
conrad
parents:
5742
diff
changeset
|
227 if (url_fseek(pb, master.pos - master.sizebytes, SEEK_SET) < 0) |
2514 | 228 return; |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
229 put_ebml_num(pb, pos - master.pos, master.sizebytes); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
230 url_fseek(pb, pos, SEEK_SET); |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
231 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
232 |
2469 | 233 static void put_xiph_size(ByteIOContext *pb, int size) |
234 { | |
235 int i; | |
236 for (i = 0; i < size / 255; i++) | |
237 put_byte(pb, 255); | |
238 put_byte(pb, size % 255); | |
239 } | |
240 | |
2477 | 241 /** |
2494 | 242 * Initialize a mkv_seekhead element to be ready to index level 1 Matroska |
243 * elements. If a maximum number of elements is specified, enough space | |
244 * will be reserved at the current file location to write a seek head of | |
245 * that size. | |
2477 | 246 * |
2494 | 247 * @param segment_offset The absolute offset to the position in the file |
2519 | 248 * where the segment begins. |
249 * @param numelements The maximum number of elements that will be indexed | |
2494 | 250 * by this seek head, 0 if unlimited. |
2477 | 251 */ |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
252 static mkv_seekhead * mkv_start_seekhead(ByteIOContext *pb, int64_t segment_offset, int numelements) |
2447 | 253 { |
254 mkv_seekhead *new_seekhead = av_mallocz(sizeof(mkv_seekhead)); | |
255 if (new_seekhead == NULL) | |
256 return NULL; | |
257 | |
258 new_seekhead->segment_offset = segment_offset; | |
259 | |
260 if (numelements > 0) { | |
261 new_seekhead->filepos = url_ftell(pb); | |
2494 | 262 // 21 bytes max for a seek entry, 10 bytes max for the SeekHead ID |
263 // and size, and 3 bytes to guarantee that an EBML void element | |
264 // will fit afterwards | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
265 new_seekhead->reserved_size = numelements * MAX_SEEKENTRY_SIZE + 13; |
2447 | 266 new_seekhead->max_entries = numelements; |
267 put_ebml_void(pb, new_seekhead->reserved_size); | |
268 } | |
269 return new_seekhead; | |
270 } | |
271 | |
272 static int mkv_add_seekhead_entry(mkv_seekhead *seekhead, unsigned int elementid, uint64_t filepos) | |
273 { | |
274 mkv_seekhead_entry *entries = seekhead->entries; | |
275 | |
276 // don't store more elements than we reserved space for | |
277 if (seekhead->max_entries > 0 && seekhead->max_entries <= seekhead->num_entries) | |
278 return -1; | |
279 | |
280 entries = av_realloc(entries, (seekhead->num_entries + 1) * sizeof(mkv_seekhead_entry)); | |
281 if (entries == NULL) | |
2499 | 282 return AVERROR(ENOMEM); |
2447 | 283 |
2507
048f4f45a84c
Use num_entries directly rather than mixing it with a local copy
conrad
parents:
2506
diff
changeset
|
284 entries[seekhead->num_entries ].elementid = elementid; |
048f4f45a84c
Use num_entries directly rather than mixing it with a local copy
conrad
parents:
2506
diff
changeset
|
285 entries[seekhead->num_entries++].segmentpos = filepos - seekhead->segment_offset; |
2447 | 286 |
287 seekhead->entries = entries; | |
288 return 0; | |
289 } | |
290 | |
2477 | 291 /** |
2494 | 292 * Write the seek head to the file and free it. If a maximum number of |
293 * elements was specified to mkv_start_seekhead(), the seek head will | |
294 * be written at the location reserved for it. Otherwise, it is written | |
295 * at the current location in the file. | |
2477 | 296 * |
5744
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
297 * @return The file offset where the seekhead was written, |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
298 * -1 if an error occurred. |
2477 | 299 */ |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
300 static int64_t mkv_write_seekhead(ByteIOContext *pb, mkv_seekhead *seekhead) |
2447 | 301 { |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
302 ebml_master metaseek, seekentry; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
303 int64_t currentpos; |
2447 | 304 int i; |
305 | |
306 currentpos = url_ftell(pb); | |
307 | |
308 if (seekhead->reserved_size > 0) | |
5744
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
309 if (url_fseek(pb, seekhead->filepos, SEEK_SET) < 0) |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
310 return -1; |
2447 | 311 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
312 metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_size); |
2447 | 313 for (i = 0; i < seekhead->num_entries; i++) { |
314 mkv_seekhead_entry *entry = &seekhead->entries[i]; | |
315 | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
316 seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_SIZE); |
2447 | 317 |
318 put_ebml_id(pb, MATROSKA_ID_SEEKID); | |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
319 put_ebml_num(pb, ebml_id_size(entry->elementid), 0); |
2447 | 320 put_ebml_id(pb, entry->elementid); |
321 | |
322 put_ebml_uint(pb, MATROSKA_ID_SEEKPOSITION, entry->segmentpos); | |
323 end_ebml_master(pb, seekentry); | |
324 } | |
325 end_ebml_master(pb, metaseek); | |
326 | |
327 if (seekhead->reserved_size > 0) { | |
328 uint64_t remaining = seekhead->filepos + seekhead->reserved_size - url_ftell(pb); | |
329 put_ebml_void(pb, remaining); | |
330 url_fseek(pb, currentpos, SEEK_SET); | |
331 | |
332 currentpos = seekhead->filepos; | |
333 } | |
334 av_free(seekhead->entries); | |
335 av_free(seekhead); | |
336 | |
337 return currentpos; | |
338 } | |
339 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
340 static mkv_cues * mkv_start_cues(int64_t segment_offset) |
2451 | 341 { |
342 mkv_cues *cues = av_mallocz(sizeof(mkv_cues)); | |
343 if (cues == NULL) | |
344 return NULL; | |
345 | |
346 cues->segment_offset = segment_offset; | |
347 return cues; | |
348 } | |
349 | |
5793 | 350 static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos) |
2451 | 351 { |
352 mkv_cuepoint *entries = cues->entries; | |
353 | |
354 entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint)); | |
355 if (entries == NULL) | |
2499 | 356 return AVERROR(ENOMEM); |
2451 | 357 |
5795 | 358 if (ts < 0) |
359 return 0; | |
360 | |
5793 | 361 entries[cues->num_entries ].pts = ts; |
362 entries[cues->num_entries ].tracknum = stream + 1; | |
2507
048f4f45a84c
Use num_entries directly rather than mixing it with a local copy
conrad
parents:
2506
diff
changeset
|
363 entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset; |
2451 | 364 |
365 cues->entries = entries; | |
366 return 0; | |
367 } | |
368 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
369 static int64_t mkv_write_cues(ByteIOContext *pb, mkv_cues *cues, int num_tracks) |
2451 | 370 { |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
371 ebml_master cues_element; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
372 int64_t currentpos; |
2451 | 373 int i, j; |
374 | |
375 currentpos = url_ftell(pb); | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
376 cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0); |
2451 | 377 |
378 for (i = 0; i < cues->num_entries; i++) { | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
379 ebml_master cuepoint, track_positions; |
2451 | 380 mkv_cuepoint *entry = &cues->entries[i]; |
381 uint64_t pts = entry->pts; | |
382 | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
383 cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks)); |
2451 | 384 put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts); |
385 | |
386 // put all the entries from different tracks that have the exact same | |
387 // timestamp into the same CuePoint | |
388 for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { | |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
389 track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE); |
2451 | 390 put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum ); |
391 put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos); | |
392 end_ebml_master(pb, track_positions); | |
393 } | |
394 i += j - 1; | |
395 end_ebml_master(pb, cuepoint); | |
396 } | |
397 end_ebml_master(pb, cues_element); | |
398 | |
399 av_free(cues->entries); | |
400 av_free(cues); | |
401 return currentpos; | |
402 } | |
403 | |
2518 | 404 static int put_xiph_codecpriv(AVFormatContext *s, ByteIOContext *pb, AVCodecContext *codec) |
2444
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
405 { |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
406 uint8_t *header_start[3]; |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
407 int header_len[3]; |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
408 int first_header_size; |
2469 | 409 int j; |
2444
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
410 |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
411 if (codec->codec_id == CODEC_ID_VORBIS) |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
412 first_header_size = 30; |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
413 else |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
414 first_header_size = 42; |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
415 |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
416 if (ff_split_xiph_headers(codec->extradata, codec->extradata_size, |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
417 first_header_size, header_start, header_len) < 0) { |
2518 | 418 av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); |
2444
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
419 return -1; |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
420 } |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
421 |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
422 put_byte(pb, 2); // number packets - 1 |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
423 for (j = 0; j < 2; j++) { |
2469 | 424 put_xiph_size(pb, header_len[j]); |
2444
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
425 } |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
426 for (j = 0; j < 3; j++) |
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
427 put_buffer(pb, header_start[j], header_len[j]); |
2446
b2f9523ee424
Make sure to return a value in functions that return a value
conrad
parents:
2445
diff
changeset
|
428 |
b2f9523ee424
Make sure to return a value in functions that return a value
conrad
parents:
2445
diff
changeset
|
429 return 0; |
2444
d954330691c5
Move Xiph's CodecPrivate writing code to its own function
conrad
parents:
2443
diff
changeset
|
430 } |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
431 |
2518 | 432 static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate) |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
433 { |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
434 int sri; |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
435 |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
436 if (codec->extradata_size < 2) { |
2519 | 437 av_log(s, AV_LOG_WARNING, "No AAC extradata, unable to determine samplerate.\n"); |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
438 return; |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
439 } |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
440 |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
441 sri = ((codec->extradata[0] << 1) & 0xE) | (codec->extradata[1] >> 7); |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
442 if (sri > 12) { |
2518 | 443 av_log(s, AV_LOG_WARNING, "AAC samplerate index out of bounds\n"); |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
444 return; |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
445 } |
3201 | 446 *sample_rate = ff_mpeg4audio_sample_rates[sri]; |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
447 |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
448 // if sbr, get output sample rate as well |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
449 if (codec->extradata_size == 5) { |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
450 sri = (codec->extradata[4] >> 3) & 0xF; |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
451 if (sri > 12) { |
2518 | 452 av_log(s, AV_LOG_WARNING, "AAC output samplerate index out of bounds\n"); |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
453 return; |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
454 } |
3201 | 455 *output_sample_rate = ff_mpeg4audio_sample_rates[sri]; |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
456 } |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
457 } |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
458 |
3601 | 459 static int mkv_write_codecprivate(AVFormatContext *s, ByteIOContext *pb, AVCodecContext *codec, int native_id, int qt_id) |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
460 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
461 ByteIOContext *dyn_cp; |
2510
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
462 uint8_t *codecpriv; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
463 int ret, codecpriv_size; |
2510
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
464 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
465 ret = url_open_dyn_buf(&dyn_cp); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
466 if(ret < 0) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
467 return ret; |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
468 |
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
469 if (native_id) { |
2513 | 470 if (codec->codec_id == CODEC_ID_VORBIS || codec->codec_id == CODEC_ID_THEORA) |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
471 ret = put_xiph_codecpriv(s, dyn_cp, codec); |
2513 | 472 else if (codec->codec_id == CODEC_ID_FLAC) |
5857 | 473 ret = ff_flac_write_header(dyn_cp, codec, 1); |
2923
0fde8da65761
Use the isom avcc formatting for h264 extradata in matroska.
aurel
parents:
2771
diff
changeset
|
474 else if (codec->codec_id == CODEC_ID_H264) |
2927
b75a49790f31
add a ff_ prefix to newly exported functions from avc.c
aurel
parents:
2926
diff
changeset
|
475 ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size); |
2513 | 476 else if (codec->extradata_size) |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
477 put_buffer(dyn_cp, codec->extradata, codec->extradata_size); |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
478 } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { |
3601 | 479 if (qt_id) { |
480 if (!codec->codec_tag) | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4581
diff
changeset
|
481 codec->codec_tag = ff_codec_get_tag(codec_movvideo_tags, codec->codec_id); |
3601 | 482 if (codec->extradata_size) |
483 put_buffer(dyn_cp, codec->extradata, codec->extradata_size); | |
484 } else { | |
5746 | 485 if (!codec->codec_tag) |
486 codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); | |
487 if (!codec->codec_tag) { | |
5848 | 488 av_log(s, AV_LOG_ERROR, "No bmp codec ID found.\n"); |
5746 | 489 ret = -1; |
490 } | |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
491 |
5746 | 492 ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0); |
3601 | 493 } |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
494 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
495 } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { |
5886
b8f2b5431f1e
Matroska muxer : Don't create audio tracks for unsupported audio codecs.
jai_menon
parents:
5875
diff
changeset
|
496 unsigned int tag; |
b8f2b5431f1e
Matroska muxer : Don't create audio tracks for unsupported audio codecs.
jai_menon
parents:
5875
diff
changeset
|
497 tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id); |
b8f2b5431f1e
Matroska muxer : Don't create audio tracks for unsupported audio codecs.
jai_menon
parents:
5875
diff
changeset
|
498 if (!tag) { |
5848 | 499 av_log(s, AV_LOG_ERROR, "No wav codec ID found.\n"); |
2510
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
500 ret = -1; |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
501 } |
5886
b8f2b5431f1e
Matroska muxer : Don't create audio tracks for unsupported audio codecs.
jai_menon
parents:
5875
diff
changeset
|
502 if (!codec->codec_tag) |
b8f2b5431f1e
Matroska muxer : Don't create audio tracks for unsupported audio codecs.
jai_menon
parents:
5875
diff
changeset
|
503 codec->codec_tag = tag; |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
504 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4581
diff
changeset
|
505 ff_put_wav_header(dyn_cp, codec); |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
506 } |
2510
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
507 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
508 codecpriv_size = url_close_dyn_buf(dyn_cp, &codecpriv); |
2510
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
509 if (codecpriv_size) |
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
510 put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv, codecpriv_size); |
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
511 av_free(codecpriv); |
4ba8d5f648a4
Write codecprivate to a dynamic buffer so that seeking isn't required
conrad
parents:
2509
diff
changeset
|
512 return ret; |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
513 } |
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
514 |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
515 static int mkv_write_tracks(AVFormatContext *s) |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
516 { |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
517 MatroskaMuxContext *mkv = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
518 ByteIOContext *pb = s->pb; |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
519 ebml_master tracks; |
2501 | 520 int i, j, ret; |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
521 |
2501 | 522 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, url_ftell(pb)); |
523 if (ret < 0) return ret; | |
2447 | 524 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
525 tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS, 0); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
526 for (i = 0; i < s->nb_streams; i++) { |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
527 AVStream *st = s->streams[i]; |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
528 AVCodecContext *codec = st->codec; |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
529 ebml_master subinfo, track; |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
530 int native_id = 0; |
3601 | 531 int qt_id = 0; |
2454 | 532 int bit_depth = av_get_bits_per_sample(codec->codec_id); |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
533 int sample_rate = codec->sample_rate; |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
534 int output_sample_rate = 0; |
4498 | 535 AVMetadataTag *tag; |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
536 |
2493
61bc7a789851
Use sample format for bit depth if av_get_bits_per_sample() doesn't give one
conrad
parents:
2492
diff
changeset
|
537 if (!bit_depth) |
61bc7a789851
Use sample format for bit depth if av_get_bits_per_sample() doesn't give one
conrad
parents:
2492
diff
changeset
|
538 bit_depth = av_get_bits_per_sample_format(codec->sample_fmt); |
61bc7a789851
Use sample format for bit depth if av_get_bits_per_sample() doesn't give one
conrad
parents:
2492
diff
changeset
|
539 |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
540 if (codec->codec_id == CODEC_ID_AAC) |
2518 | 541 get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate); |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
542 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
543 track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0); |
2439 | 544 put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1); |
545 put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1); | |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
546 put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet) |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
547 |
5742
f50c86f67772
matroskaenc: use "title" tag instead of "description" in track title.
conrad
parents:
5573
diff
changeset
|
548 if ((tag = av_metadata_get(st->metadata, "title", NULL, 0))) |
4498 | 549 put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value); |
550 tag = av_metadata_get(st->metadata, "language", NULL, 0); | |
551 put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und"); | |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
552 |
4240
dff232a64d7c
Treat disposition==0 as undefined and don't write the default flag
conrad
parents:
4239
diff
changeset
|
553 if (st->disposition) |
4241 | 554 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT)); |
3120
ea5623a8efde
Add 'disposition' bitfield to AVStream and use it for both muxing and demuxing
eugeni
parents:
3097
diff
changeset
|
555 |
2519 | 556 // look for a codec ID string specific to mkv to use, |
2494 | 557 // if none are found, use AVI codes |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
558 for (j = 0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++) { |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
559 if (ff_mkv_codec_tags[j].id == codec->codec_id) { |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
560 put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str); |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
561 native_id = 1; |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
562 break; |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
563 } |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
564 } |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
565 |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
566 switch (codec->codec_type) { |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
567 case AVMEDIA_TYPE_VIDEO: |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
568 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); |
6048
e507a21a9566
matroskaenc: Write codec time base as default duration for video tracks.
conrad
parents:
6031
diff
changeset
|
569 put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
570 |
3601 | 571 if (!native_id && |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4581
diff
changeset
|
572 ff_codec_get_tag(codec_movvideo_tags, codec->codec_id) && |
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4581
diff
changeset
|
573 (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id) |
3601 | 574 || codec->codec_id == CODEC_ID_SVQ1 |
575 || codec->codec_id == CODEC_ID_SVQ3 | |
576 || codec->codec_id == CODEC_ID_CINEPAK)) | |
577 qt_id = 1; | |
578 | |
579 if (qt_id) | |
580 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME"); | |
5793 | 581 else if (!native_id) { |
2519 | 582 // if there is no mkv-specific codec ID, use VFW mode |
3687
494a55f131f3
matroska: expand useless define for MS compat codec id strings
aurel
parents:
3601
diff
changeset
|
583 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); |
5793 | 584 mkv->tracks[i].write_dts = 1; |
585 } | |
2513 | 586 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
587 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
588 // XXX: interlace flag? |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
589 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
590 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3692
diff
changeset
|
591 if (st->sample_aspect_ratio.num) { |
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3692
diff
changeset
|
592 int d_width = codec->width*av_q2d(st->sample_aspect_ratio); |
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3692
diff
changeset
|
593 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width); |
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3692
diff
changeset
|
594 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height); |
2473 | 595 } |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
596 end_ebml_master(pb, subinfo); |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
597 break; |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
598 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
599 case AVMEDIA_TYPE_AUDIO: |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
600 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO); |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
601 |
2513 | 602 if (!native_id) |
2452
1b6ea48f7f24
Write wav header if there is no native audio codec ID
conrad
parents:
2451
diff
changeset
|
603 // no mkv-specific ID, use ACM mode |
3687
494a55f131f3
matroska: expand useless define for MS compat codec id strings
aurel
parents:
3601
diff
changeset
|
604 put_ebml_string(pb, MATROSKA_ID_CODECID, "A_MS/ACM"); |
2513 | 605 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
606 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 0); |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
607 put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , codec->channels); |
2458
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
608 put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate); |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
609 if (output_sample_rate) |
7286ab3bf026
Determine the output sample rate for SBR AAC and write it
conrad
parents:
2457
diff
changeset
|
610 put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate); |
2453 | 611 if (bit_depth) |
612 put_ebml_uint(pb, MATROSKA_ID_AUDIOBITDEPTH, bit_depth); | |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
613 end_ebml_master(pb, subinfo); |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
614 break; |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
615 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
616 case AVMEDIA_TYPE_SUBTITLE: |
2498 | 617 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_SUBTITLE); |
618 break; | |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
619 default: |
2503 | 620 av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska."); |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
621 break; |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
622 } |
3601 | 623 ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id); |
2509
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
624 if (ret < 0) return ret; |
5abcad2566b3
Move writing codec private element to its own function
conrad
parents:
2508
diff
changeset
|
625 |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
626 end_ebml_master(pb, track); |
2432
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
627 |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
628 // ms precision is the de-facto standard timescale for mkv files |
68743e7fa627
First stab at writing the tracks element, still needs some additional cases for certain codecs
conrad
parents:
2431
diff
changeset
|
629 av_set_pts_info(st, 64, 1, 1000); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
630 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
631 end_ebml_master(pb, tracks); |
2446
b2f9523ee424
Make sure to return a value in functions that return a value
conrad
parents:
2445
diff
changeset
|
632 return 0; |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
633 } |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
634 |
5299 | 635 static int mkv_write_chapters(AVFormatContext *s) |
636 { | |
637 MatroskaMuxContext *mkv = s->priv_data; | |
638 ByteIOContext *pb = s->pb; | |
639 ebml_master chapters, editionentry; | |
640 AVRational scale = {1, 1E9}; | |
641 int i, ret; | |
642 | |
643 if (!s->nb_chapters) | |
644 return 0; | |
645 | |
646 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, url_ftell(pb)); | |
647 if (ret < 0) return ret; | |
648 | |
649 chapters = start_ebml_master(pb, MATROSKA_ID_CHAPTERS , 0); | |
650 editionentry = start_ebml_master(pb, MATROSKA_ID_EDITIONENTRY, 0); | |
651 put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGDEFAULT, 1); | |
652 put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGHIDDEN , 0); | |
653 for (i = 0; i < s->nb_chapters; i++) { | |
654 ebml_master chapteratom, chapterdisplay; | |
655 AVChapter *c = s->chapters[i]; | |
656 AVMetadataTag *t = NULL; | |
657 | |
658 chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0); | |
659 put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id); | |
660 put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART, | |
661 av_rescale_q(c->start, c->time_base, scale)); | |
662 put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND, | |
663 av_rescale_q(c->end, c->time_base, scale)); | |
664 put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGHIDDEN , 0); | |
665 put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGENABLED, 1); | |
666 if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) { | |
667 chapterdisplay = start_ebml_master(pb, MATROSKA_ID_CHAPTERDISPLAY, 0); | |
668 put_ebml_string(pb, MATROSKA_ID_CHAPSTRING, t->value); | |
669 put_ebml_string(pb, MATROSKA_ID_CHAPLANG , "und"); | |
670 end_ebml_master(pb, chapterdisplay); | |
671 } | |
672 end_ebml_master(pb, chapteratom); | |
673 } | |
674 end_ebml_master(pb, editionentry); | |
675 end_ebml_master(pb, chapters); | |
676 return 0; | |
677 } | |
678 | |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
679 static int mkv_write_header(AVFormatContext *s) |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
680 { |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
681 MatroskaMuxContext *mkv = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
682 ByteIOContext *pb = s->pb; |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
683 ebml_master ebml_header, segment_info; |
4498 | 684 AVMetadataTag *tag; |
2501 | 685 int ret; |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
686 |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
687 mkv->md5_ctx = av_mallocz(av_md5_size); |
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
688 av_md5_init(mkv->md5_ctx); |
5793 | 689 mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
690 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
691 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0); |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
692 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
693 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
694 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
695 put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
696 put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska"); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
697 put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
698 put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
699 end_ebml_master(pb, ebml_header); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
700 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
701 mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT, 0); |
2447 | 702 mkv->segment_offset = url_ftell(pb); |
703 | |
2494 | 704 // we write 2 seek heads - one at the end of the file to point to each |
705 // cluster, and one at the beginning to point to all other level one | |
706 // elements (including the seek head at the end of the file), which | |
707 // isn't more than 10 elements if we only write one of each other | |
708 // currently defined level 1 element | |
2447 | 709 mkv->main_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 10); |
710 mkv->cluster_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 0); | |
2500 | 711 if (mkv->main_seekhead == NULL || mkv->cluster_seekhead == NULL) |
712 return AVERROR(ENOMEM); | |
2447 | 713 |
2501 | 714 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, url_ftell(pb)); |
715 if (ret < 0) return ret; | |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
716 |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
717 segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0); |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
718 put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); |
4498 | 719 if ((tag = av_metadata_get(s->metadata, "title", NULL, 0))) |
720 put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value); | |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
721 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { |
2466 | 722 put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
723 put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
724 |
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
725 // reserve space to write the segment UID later |
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
726 mkv->segment_uid = url_ftell(pb); |
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
727 put_ebml_void(pb, 19); |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
728 } |
2468 | 729 |
2445
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
730 // reserve space for the duration |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
731 mkv->duration = 0; |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
732 mkv->duration_offset = url_ftell(pb); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
733 put_ebml_void(pb, 11); // assumes double-precision float to be written |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
734 end_ebml_master(pb, segment_info); |
86466f60fc5d
Move writing the tracks element to its own function
conrad
parents:
2444
diff
changeset
|
735 |
2501 | 736 ret = mkv_write_tracks(s); |
737 if (ret < 0) return ret; | |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
738 |
5299 | 739 ret = mkv_write_chapters(s); |
740 if (ret < 0) return ret; | |
741 | |
5744
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
742 if (url_is_streamed(s->pb)) |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
743 mkv_write_seekhead(pb, mkv->main_seekhead); |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
744 |
2451 | 745 mkv->cues = mkv_start_cues(mkv->segment_offset); |
746 if (mkv->cues == NULL) | |
2499 | 747 return AVERROR(ENOMEM); |
2451 | 748 |
4239
5d0ac4d87ba1
Flush the buffer after writing the header and when done with writing the files
conrad
parents:
4223
diff
changeset
|
749 put_flush_packet(pb); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
750 return 0; |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
751 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
752 |
3986
2a7d8acde051
matroskaenc: pass the packet size directly as parameter of mkv_blockgroup_size()
aurel
parents:
3985
diff
changeset
|
753 static int mkv_blockgroup_size(int pkt_size) |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
754 { |
3986
2a7d8acde051
matroskaenc: pass the packet size directly as parameter of mkv_blockgroup_size()
aurel
parents:
3985
diff
changeset
|
755 int size = pkt_size + 4; |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
756 size += ebml_num_size(size); |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
757 size += 2; // EBML ID for block and block duration |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
758 size += 8; // max size of block duration |
2517
ac3e650ec92c
Rename ebml size functions to indicate that they can be used for more kinds of numbers
conrad
parents:
2516
diff
changeset
|
759 size += ebml_num_size(size); |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
760 size += 1; // blockgroup EBML ID |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
761 return size; |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
762 } |
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
763 |
3988 | 764 static int ass_get_duration(const uint8_t *p) |
765 { | |
766 int sh, sm, ss, sc, eh, em, es, ec; | |
767 uint64_t start, end; | |
768 | |
769 if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d", | |
770 &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8) | |
771 return 0; | |
772 start = 3600000*sh + 60000*sm + 1000*ss + 10*sc; | |
773 end = 3600000*eh + 60000*em + 1000*es + 10*ec; | |
774 return end - start; | |
775 } | |
776 | |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
777 static int mkv_write_ass_blocks(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt) |
3988 | 778 { |
779 MatroskaMuxContext *mkv = s->priv_data; | |
780 int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size; | |
781 uint8_t *start, *end, *data = pkt->data; | |
782 ebml_master blockgroup; | |
783 char buffer[2048]; | |
784 | |
785 while (data_size) { | |
786 int duration = ass_get_duration(data); | |
787 max_duration = FFMAX(duration, max_duration); | |
788 end = memchr(data, '\n', data_size); | |
789 size = line_size = end ? end-data+1 : data_size; | |
790 size -= end ? (end[-1]=='\r')+1 : 0; | |
791 start = data; | |
792 for (i=0; i<3; i++, start++) | |
793 if (!(start = memchr(start, ',', size-(start-data)))) | |
794 return max_duration; | |
795 size -= start - data; | |
796 sscanf(data, "Dialogue: %d,", &layer); | |
797 i = snprintf(buffer, sizeof(buffer), "%"PRId64",%d,", | |
798 s->streams[pkt->stream_index]->nb_frames++, layer); | |
799 size = FFMIN(i+size, sizeof(buffer)); | |
800 memcpy(buffer+i, start, size-i); | |
801 | |
802 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " | |
803 "pts %" PRId64 ", duration %d\n", | |
804 url_ftell(pb), size, pkt->pts, duration); | |
805 blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size)); | |
806 put_ebml_id(pb, MATROSKA_ID_BLOCK); | |
807 put_ebml_num(pb, size+4, 0); | |
808 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 | |
809 put_be16(pb, pkt->pts - mkv->cluster_pts); | |
810 put_byte(pb, 0); | |
811 put_buffer(pb, buffer, size); | |
812 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); | |
813 end_ebml_master(pb, blockgroup); | |
814 | |
815 data += line_size; | |
816 data_size -= line_size; | |
817 } | |
818 | |
819 return max_duration; | |
820 } | |
821 | |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
822 static void mkv_write_block(AVFormatContext *s, ByteIOContext *pb, |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
823 unsigned int blockid, AVPacket *pkt, int flags) |
2460 | 824 { |
825 MatroskaMuxContext *mkv = s->priv_data; | |
4222
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
826 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; |
4256
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
827 uint8_t *data = NULL; |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
828 int size = pkt->size; |
5793 | 829 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; |
2460 | 830 |
2504 | 831 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " |
832 "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", | |
2474 | 833 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); |
4256
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
834 if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 && |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
835 (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
836 ff_avc_parse_nal_units_buf(pkt->data, &data, &size); |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
837 else |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
838 data = pkt->data; |
2460 | 839 put_ebml_id(pb, blockid); |
4256
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
840 put_ebml_num(pb, size+4, 0); |
2460 | 841 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 |
5793 | 842 put_be16(pb, ts - mkv->cluster_pts); |
2460 | 843 put_byte(pb, flags); |
4256
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
844 put_buffer(pb, data, size); |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
845 if (data != pkt->data) |
3f5d00cb1f61
matroskaenc: correctly handle h264 streams with 3 bytes nal startcodes
aurel
parents:
4241
diff
changeset
|
846 av_free(data); |
2460 | 847 } |
848 | |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
849 static void mkv_flush_dynbuf(AVFormatContext *s) |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
850 { |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
851 MatroskaMuxContext *mkv = s->priv_data; |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
852 int bufsize; |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
853 uint8_t *dyn_buf; |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
854 |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
855 if (!mkv->dyn_bc) |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
856 return; |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
857 |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
858 bufsize = url_close_dyn_buf(mkv->dyn_bc, &dyn_buf); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
859 put_buffer(s->pb, dyn_buf, bufsize); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
860 av_free(dyn_buf); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
861 mkv->dyn_bc = NULL; |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
862 } |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
863 |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
864 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
865 { |
2437 | 866 MatroskaMuxContext *mkv = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
867 ByteIOContext *pb = s->pb; |
2463 | 868 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; |
5913
11bb10c37225
Replace all occurences of PKT_FLAG_KEY with AV_PKT_FLAG_KEY.
cehoyos
parents:
5910
diff
changeset
|
869 int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY); |
3892
8f1928b41f45
matroska: subtitle display duration must be stored in pkt->convergence_duration
aurel
parents:
3766
diff
changeset
|
870 int duration = pkt->duration; |
2501 | 871 int ret; |
5793 | 872 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; |
2433
0c047310f205
Write one cluster and SimpleBlocks for the frames. Should now create playable mkv files for some video codecs (H.264 and VP3 checked)
conrad
parents:
2432
diff
changeset
|
873 |
5794
31e8a43123c5
mkvenc: Don't try to write packets with unknown timestamps
conrad
parents:
5793
diff
changeset
|
874 if (ts == AV_NOPTS_VALUE) { |
31e8a43123c5
mkvenc: Don't try to write packets with unknown timestamps
conrad
parents:
5793
diff
changeset
|
875 av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); |
31e8a43123c5
mkvenc: Don't try to write packets with unknown timestamps
conrad
parents:
5793
diff
changeset
|
876 return AVERROR(EINVAL); |
31e8a43123c5
mkvenc: Don't try to write packets with unknown timestamps
conrad
parents:
5793
diff
changeset
|
877 } |
31e8a43123c5
mkvenc: Don't try to write packets with unknown timestamps
conrad
parents:
5793
diff
changeset
|
878 |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
879 if (url_is_streamed(s->pb)) { |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
880 if (!mkv->dyn_bc) |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
881 url_open_dyn_buf(&mkv->dyn_bc); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
882 pb = mkv->dyn_bc; |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
883 } |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
884 |
5745 | 885 if (!mkv->cluster_pos) { |
2501 | 886 ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)); |
887 if (ret < 0) return ret; | |
2447 | 888 |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
889 mkv->cluster_pos = url_ftell(s->pb); |
2489
3ef5728030da
Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
conrad
parents:
2488
diff
changeset
|
890 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0); |
5795 | 891 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); |
892 mkv->cluster_pts = FFMAX(0, ts); | |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
893 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); |
2437 | 894 } |
895 | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
896 if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) { |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
897 mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); |
3988 | 898 } else if (codec->codec_id == CODEC_ID_SSA) { |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
899 duration = mkv_write_ass_blocks(s, pb, pkt); |
2461 | 900 } else { |
3986
2a7d8acde051
matroskaenc: pass the packet size directly as parameter of mkv_blockgroup_size()
aurel
parents:
3985
diff
changeset
|
901 ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size)); |
3892
8f1928b41f45
matroska: subtitle display duration must be stored in pkt->convergence_duration
aurel
parents:
3766
diff
changeset
|
902 duration = pkt->convergence_duration; |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
903 mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0); |
3987 | 904 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); |
2461 | 905 end_ebml_master(pb, blockgroup); |
906 } | |
2443 | 907 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5886
diff
changeset
|
908 if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) { |
5793 | 909 ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos); |
2501 | 910 if (ret < 0) return ret; |
2451 | 911 } |
912 | |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
913 // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming |
5875 | 914 if ((url_is_streamed(s->pb) && (url_ftell(pb) > 32*1024 || ts > mkv->cluster_pts + 1000)) |
5793 | 915 || url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || ts > mkv->cluster_pts + 5000) { |
5745 | 916 av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64 |
5793 | 917 " bytes, pts %" PRIu64 "\n", url_ftell(pb), ts); |
5745 | 918 end_ebml_master(pb, mkv->cluster); |
919 mkv->cluster_pos = 0; | |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
920 if (mkv->dyn_bc) |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
921 mkv_flush_dynbuf(s); |
5745 | 922 } |
923 | |
5793 | 924 mkv->duration = FFMAX(mkv->duration, ts + duration); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
925 return 0; |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
926 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
927 |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
928 static int mkv_write_trailer(AVFormatContext *s) |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
929 { |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
930 MatroskaMuxContext *mkv = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2530
diff
changeset
|
931 ByteIOContext *pb = s->pb; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3892
diff
changeset
|
932 int64_t currentpos, second_seekhead, cuespos; |
2502 | 933 int ret; |
2443 | 934 |
5747
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
935 if (mkv->dyn_bc) { |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
936 end_ebml_master(mkv->dyn_bc, mkv->cluster); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
937 mkv_flush_dynbuf(s); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
938 } else if (mkv->cluster_pos) { |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
939 end_ebml_master(pb, mkv->cluster); |
551765b1772b
Ensure that we write clusters and blocks with known size when streaming
conrad
parents:
5746
diff
changeset
|
940 } |
2443 | 941 |
2514 | 942 if (!url_is_streamed(pb)) { |
2515 | 943 cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams); |
944 second_seekhead = mkv_write_seekhead(pb, mkv->cluster_seekhead); | |
2451 | 945 |
2515 | 946 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , cuespos); |
947 if (ret < 0) return ret; | |
5744
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
948 if (second_seekhead >= 0) { |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
949 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_SEEKHEAD, second_seekhead); |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
950 if (ret < 0) return ret; |
a656843c86aa
Write the first seekhead if writing to a stream, we won't be able to seek
conrad
parents:
5743
diff
changeset
|
951 } |
2515 | 952 mkv_write_seekhead(pb, mkv->main_seekhead); |
2447 | 953 |
2515 | 954 // update the duration |
955 av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); | |
956 currentpos = url_ftell(pb); | |
957 url_fseek(pb, mkv->duration_offset, SEEK_SET); | |
958 put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration); | |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
959 |
2515 | 960 // write the md5sum of some frames as the segment UID |
961 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { | |
962 uint8_t segment_uid[16]; | |
963 av_md5_final(mkv->md5_ctx, segment_uid); | |
964 url_fseek(pb, mkv->segment_uid, SEEK_SET); | |
965 put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); | |
966 } | |
967 url_fseek(pb, currentpos, SEEK_SET); | |
2514 | 968 } |
2443 | 969 |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
970 end_ebml_master(pb, mkv->segment); |
2479
139406606437
Use a MD5 hash of some frames to write the segment uid
conrad
parents:
2478
diff
changeset
|
971 av_free(mkv->md5_ctx); |
5793 | 972 av_free(mkv->tracks); |
4239
5d0ac4d87ba1
Flush the buffer after writing the header and when done with writing the files
conrad
parents:
4223
diff
changeset
|
973 put_flush_packet(pb); |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
974 return 0; |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
975 } |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
976 |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
977 AVOutputFormat matroska_muxer = { |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
978 "matroska", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
979 NULL_IF_CONFIG_SMALL("Matroska file format"), |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
980 "video/x-matroska", |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
981 "mkv", |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
982 sizeof(MatroskaMuxContext), |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
983 CODEC_ID_MP2, |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
984 CODEC_ID_MPEG4, |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
985 mkv_write_header, |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
986 mkv_write_packet, |
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
987 mkv_write_trailer, |
4567
963e3b76c7a6
Add AVFMT_VARIABLE_FPS to specify which muxers do not need duplicated frames.
michael
parents:
4498
diff
changeset
|
988 .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4581
diff
changeset
|
989 .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, |
2486 | 990 .subtitle_codec = CODEC_ID_TEXT, |
2425
8c51e92edd7d
Beginning of mkv muxer, only EBML head is written correctly
conrad
parents:
diff
changeset
|
991 }; |
2475 | 992 |
993 AVOutputFormat matroska_audio_muxer = { | |
994 "matroska", | |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
995 NULL_IF_CONFIG_SMALL("Matroska file format"), |
2475 | 996 "audio/x-matroska", |
997 "mka", | |
998 sizeof(MatroskaMuxContext), | |
999 CODEC_ID_MP2, | |
1000 CODEC_ID_NONE, | |
1001 mkv_write_header, | |
1002 mkv_write_packet, | |
1003 mkv_write_trailer, | |
4002 | 1004 .flags = AVFMT_GLOBALHEADER, |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4581
diff
changeset
|
1005 .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, |
2475 | 1006 }; |