]> git.sesse.net Git - ffmpeg/blob - libavformat/matroskaenc.c
91da9079f4e2b1d08bfbca2a9653c2b6e2cb0ab8
[ffmpeg] / libavformat / matroskaenc.c
1 /*
2  * Matroska file muxer
3  * Copyright (c) 2007 David Conrad
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "avformat.h"
23 #include "riff.h"
24 #include "matroska.h"
25
26 typedef struct MatroskaMuxContext {
27     offset_t    segment;
28     offset_t    cluster;
29 } MatroskaMuxContext;
30
31 static void put_ebml_id(ByteIOContext *pb, unsigned int id)
32 {
33     if (id >= 0x3fffff)
34         put_byte(pb, id >> 24);
35     if (id >= 0x7fff)
36         put_byte(pb, id >> 16);
37     if (id >= 0xff)
38         put_byte(pb, id >> 8);
39     put_byte(pb, id);
40 }
41
42 // XXX: test this thoroughly and get rid of minbytes hack (currently needed to
43 // use up all of the space reserved in start_ebml_master)
44 static void put_ebml_size(ByteIOContext *pb, uint64_t size, int minbytes)
45 {
46     int bytes = minbytes;
47     while (size >> (bytes*7 + 7)) bytes++;
48
49     // sizes larger than this are currently undefined in EBML
50     // XXX: error condition?
51     if (size > (1ULL<<56)-1) return;
52
53     put_byte(pb, (0x80 >> bytes) | (size >> bytes*8));
54     for (bytes -= 1; bytes >= 0; bytes--)
55         put_byte(pb, size >> bytes*8);
56 }
57
58 static void put_ebml_uint(ByteIOContext *pb, unsigned int elementid, uint64_t val)
59 {
60     int bytes = 1;
61     while (val >> bytes*8) bytes++;
62
63     put_ebml_id(pb, elementid);
64     put_ebml_size(pb, bytes, 0);
65     for (bytes -= 1; bytes >= 0; bytes--)
66         put_byte(pb, val >> bytes*8);
67 }
68
69 //static void put_ebml_sint(ByteIOContext *pb, unsigned int elementid, int64_t val)
70
71 static void put_ebml_float(ByteIOContext *pb, unsigned int elementid, double val)
72 {
73     // XXX: single-precision floats?
74     put_ebml_id(pb, elementid);
75     put_ebml_size(pb, 8, 0);
76     put_be64(pb, av_dbl2int(val));
77 }
78
79 static void put_ebml_binary(ByteIOContext *pb, unsigned int elementid,
80                             const uint8_t *buf, int size)
81 {
82     put_ebml_id(pb, elementid);
83     put_ebml_size(pb, size, 0);
84     put_buffer(pb, buf, size);
85 }
86
87 static void put_ebml_string(ByteIOContext *pb, unsigned int elementid, const char *str)
88 {
89     put_ebml_binary(pb, elementid, str, strlen(str));
90 }
91
92 static offset_t start_ebml_master(ByteIOContext *pb, unsigned int elementid)
93 {
94     put_ebml_id(pb, elementid);
95     // XXX: this always reserves the maximum needed space to store any size value
96     // we should be smarter (additional parameter for expected size?)
97     put_ebml_size(pb, (1ULL<<56)-1, 0);     // largest unknown size
98     return url_ftell(pb);
99 }
100
101 static void end_ebml_master(ByteIOContext *pb, offset_t start)
102 {
103     offset_t pos = url_ftell(pb);
104
105     url_fseek(pb, start - 8, SEEK_SET);
106     put_ebml_size(pb, pos - start, 7);
107     url_fseek(pb, pos, SEEK_SET);
108 }
109
110
111 static int mkv_write_header(AVFormatContext *s)
112 {
113     MatroskaMuxContext *mkv = s->priv_data;
114     ByteIOContext *pb = &s->pb;
115     offset_t ebml_header, segment_info, tracks;
116     int i, j;
117
118     ebml_header = start_ebml_master(pb, EBML_ID_HEADER);
119     put_ebml_uint   (pb, EBML_ID_EBMLVERSION        ,           1);
120     put_ebml_uint   (pb, EBML_ID_EBMLREADVERSION    ,           1);
121     put_ebml_uint   (pb, EBML_ID_EBMLMAXIDLENGTH    ,           4);
122     put_ebml_uint   (pb, EBML_ID_EBMLMAXSIZELENGTH  ,           8);
123     put_ebml_string (pb, EBML_ID_DOCTYPE            ,  "matroska");
124     put_ebml_uint   (pb, EBML_ID_DOCTYPEVERSION     ,           1);
125     put_ebml_uint   (pb, EBML_ID_DOCTYPEREADVERSION ,           1);
126     end_ebml_master(pb, ebml_header);
127
128     mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT);
129
130     segment_info = start_ebml_master(pb, MATROSKA_ID_INFO);
131     put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
132     if (strlen(s->title))
133         put_ebml_string(pb, MATROSKA_ID_TITLE, s->title);
134     if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
135         put_ebml_string(pb, MATROSKA_ID_MUXINGAPP, LIBAVFORMAT_IDENT);
136         // XXX: both are required; something better for writing app?
137         put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT);
138     }
139     // XXX: segment UID and duration
140     end_ebml_master(pb, segment_info);
141
142     tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS);
143     for (i = 0; i < s->nb_streams; i++) {
144         AVStream *st = s->streams[i];
145         AVCodecContext *codec = st->codec;
146         offset_t subinfo, track;
147         int native_id = 0;
148
149         track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY);
150         put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER     , i);
151         // XXX: random number for UID? and can we use the same UID when copying
152         // from another MKV as the specs recommend?
153         put_ebml_uint (pb, MATROSKA_ID_TRACKUID        , i);
154         put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0);    // no lacing (yet)
155
156         if (st->language[0])
157             put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, st->language);
158
159         // look for a codec id string specific to mkv to use, if none are found, use AVI codes
160         for (j = 0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++) {
161             if (ff_mkv_codec_tags[j].id == codec->codec_id) {
162                 put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
163                 native_id = 1;
164                 break;
165             }
166         }
167
168         // XXX: CodecPrivate for vorbis, theora, aac, native mpeg4, ...
169         if (native_id) {
170             put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codec->extradata, codec->extradata_size);
171         }
172
173         switch (codec->codec_type) {
174             case CODEC_TYPE_VIDEO:
175                 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
176
177                 if (!native_id) {
178                     offset_t bmp_header;
179                     // if there is no mkv-specific codec id, use VFW mode
180                     if (!codec->codec_tag)
181                         codec->codec_tag = codec_get_tag(codec_bmp_tags, codec->codec_id);
182
183                     put_ebml_string(pb, MATROSKA_ID_CODECID, MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
184                     // XXX: codec private isn't a master; is there a better way to re-use put_bmp_header?
185                     bmp_header = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE);
186                     put_bmp_header(pb, codec, codec_bmp_tags, 0);
187                     end_ebml_master(pb, bmp_header);
188                 }
189                 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO);
190                 // XXX: interlace flag?
191                 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
192                 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
193                 // XXX: display width/height
194                 end_ebml_master(pb, subinfo);
195                 break;
196
197             case CODEC_TYPE_AUDIO:
198                 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO);
199
200                 // XXX: A_MS/ACM
201                 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO);
202                 put_ebml_uint  (pb, MATROSKA_ID_AUDIOCHANNELS    , codec->channels);
203                 put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, codec->sample_rate);
204                 // XXX: output sample freq (for sbr) and bitdepth (for pcm)
205                 end_ebml_master(pb, subinfo);
206                 break;
207
208             default:
209                 av_log(s, AV_LOG_ERROR, "Only audio and video are supported for Matroska.");
210                 break;
211         }
212         end_ebml_master(pb, track);
213
214         // ms precision is the de-facto standard timescale for mkv files
215         av_set_pts_info(st, 64, 1, 1000);
216     }
217     end_ebml_master(pb, tracks);
218
219     mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER);
220     put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, 0);
221
222     return 0;
223 }
224
225 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
226 {
227     ByteIOContext *pb = &s->pb;
228
229     block = start_ebml_master(pb, MATROSKA_ID_SIMPLEBLOCK);
230     put_byte(pb, 0x80 | pkt->stream_index);     // this assumes stream_index is less than 127
231     put_be16(pb, pkt->pts);
232     put_byte(pb, !!(pkt->flags & PKT_FLAG_KEY));
233     put_buffer(pb, pkt->data, pkt->size);
234     end_ebml_master(pb, block);
235     return 0;
236 }
237
238 static int mkv_write_trailer(AVFormatContext *s)
239 {
240     MatroskaMuxContext *mkv = s->priv_data;
241     ByteIOContext *pb = &s->pb;
242     end_ebml_master(pb, mkv->cluster);
243     end_ebml_master(pb, mkv->segment);
244     return 0;
245 }
246
247 AVOutputFormat matroska_muxer = {
248     "matroska",
249     "Matroska File Format",
250     "video/x-matroska",
251     "mkv",
252     sizeof(MatroskaMuxContext),
253     CODEC_ID_MP2,
254     CODEC_ID_MPEG4,
255     mkv_write_header,
256     mkv_write_packet,
257     mkv_write_trailer,
258     .codec_tag = (const AVCodecTag*[]){codec_bmp_tags, codec_wav_tags, 0},
259 };