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