00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "riff.h"
00024 #include "isom.h"
00025 #include "matroska.h"
00026 #include "avc.h"
00027 #include "flacenc.h"
00028 #include "avlanguage.h"
00029 #include "libavutil/samplefmt.h"
00030 #include "libavutil/intreadwrite.h"
00031 #include "libavutil/random_seed.h"
00032 #include "libavutil/lfg.h"
00033 #include "libavcodec/xiph.h"
00034 #include "libavcodec/mpeg4audio.h"
00035 #include <strings.h>
00036
00037 typedef struct ebml_master {
00038 int64_t pos;
00039 int sizebytes;
00040 } ebml_master;
00041
00042 typedef struct mkv_seekhead_entry {
00043 unsigned int elementid;
00044 uint64_t segmentpos;
00045 } mkv_seekhead_entry;
00046
00047 typedef struct mkv_seekhead {
00048 int64_t filepos;
00049 int64_t segment_offset;
00050 int reserved_size;
00051 int max_entries;
00052 mkv_seekhead_entry *entries;
00053 int num_entries;
00054 } mkv_seekhead;
00055
00056 typedef struct {
00057 uint64_t pts;
00058 int tracknum;
00059 int64_t cluster_pos;
00060 } mkv_cuepoint;
00061
00062 typedef struct {
00063 int64_t segment_offset;
00064 mkv_cuepoint *entries;
00065 int num_entries;
00066 } mkv_cues;
00067
00068 typedef struct {
00069 int write_dts;
00070 } mkv_track;
00071
00072 #define MODE_MATROSKAv2 0x01
00073 #define MODE_WEBM 0x02
00074
00075 typedef struct MatroskaMuxContext {
00076 int mode;
00077 AVIOContext *dyn_bc;
00078 ebml_master segment;
00079 int64_t segment_offset;
00080 ebml_master cluster;
00081 int64_t cluster_pos;
00082 int64_t cluster_pts;
00083 int64_t duration_offset;
00084 int64_t duration;
00085 mkv_seekhead *main_seekhead;
00086 mkv_cues *cues;
00087 mkv_track *tracks;
00088
00089 unsigned int audio_buffer_size;
00090 AVPacket cur_audio_pkt;
00091 } MatroskaMuxContext;
00092
00093
00096 #define MAX_SEEKENTRY_SIZE 21
00097
00100 #define MAX_CUETRACKPOS_SIZE 22
00101
00103 #define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks
00104
00105
00106 static int ebml_id_size(unsigned int id)
00107 {
00108 return (av_log2(id+1)-1)/7+1;
00109 }
00110
00111 static void put_ebml_id(AVIOContext *pb, unsigned int id)
00112 {
00113 int i = ebml_id_size(id);
00114 while (i--)
00115 avio_w8(pb, id >> (i*8));
00116 }
00117
00123 static void put_ebml_size_unknown(AVIOContext *pb, int bytes)
00124 {
00125 assert(bytes <= 8);
00126 avio_w8(pb, 0x1ff >> bytes);
00127 while (--bytes)
00128 avio_w8(pb, 0xff);
00129 }
00130
00134 static int ebml_num_size(uint64_t num)
00135 {
00136 int bytes = 1;
00137 while ((num+1) >> bytes*7) bytes++;
00138 return bytes;
00139 }
00140
00147 static void put_ebml_num(AVIOContext *pb, uint64_t num, int bytes)
00148 {
00149 int i, needed_bytes = ebml_num_size(num);
00150
00151
00152 assert(num < (1ULL<<56)-1);
00153
00154 if (bytes == 0)
00155
00156 bytes = needed_bytes;
00157
00158
00159 assert(bytes >= needed_bytes);
00160
00161 num |= 1ULL << bytes*7;
00162 for (i = bytes - 1; i >= 0; i--)
00163 avio_w8(pb, num >> i*8);
00164 }
00165
00166 static void put_ebml_uint(AVIOContext *pb, unsigned int elementid, uint64_t val)
00167 {
00168 int i, bytes = 1;
00169 uint64_t tmp = val;
00170 while (tmp>>=8) bytes++;
00171
00172 put_ebml_id(pb, elementid);
00173 put_ebml_num(pb, bytes, 0);
00174 for (i = bytes - 1; i >= 0; i--)
00175 avio_w8(pb, val >> i*8);
00176 }
00177
00178 static void put_ebml_float(AVIOContext *pb, unsigned int elementid, double val)
00179 {
00180 put_ebml_id(pb, elementid);
00181 put_ebml_num(pb, 8, 0);
00182 avio_wb64(pb, av_dbl2int(val));
00183 }
00184
00185 static void put_ebml_binary(AVIOContext *pb, unsigned int elementid,
00186 const void *buf, int size)
00187 {
00188 put_ebml_id(pb, elementid);
00189 put_ebml_num(pb, size, 0);
00190 avio_write(pb, buf, size);
00191 }
00192
00193 static void put_ebml_string(AVIOContext *pb, unsigned int elementid, const char *str)
00194 {
00195 put_ebml_binary(pb, elementid, str, strlen(str));
00196 }
00197
00204 static void put_ebml_void(AVIOContext *pb, uint64_t size)
00205 {
00206 int64_t currentpos = avio_tell(pb);
00207
00208 assert(size >= 2);
00209
00210 put_ebml_id(pb, EBML_ID_VOID);
00211
00212
00213
00214 if (size < 10)
00215 put_ebml_num(pb, size-1, 0);
00216 else
00217 put_ebml_num(pb, size-9, 8);
00218 while(avio_tell(pb) < currentpos + size)
00219 avio_w8(pb, 0);
00220 }
00221
00222 static ebml_master start_ebml_master(AVIOContext *pb, unsigned int elementid, uint64_t expectedsize)
00223 {
00224 int bytes = expectedsize ? ebml_num_size(expectedsize) : 8;
00225 put_ebml_id(pb, elementid);
00226 put_ebml_size_unknown(pb, bytes);
00227 return (ebml_master){ avio_tell(pb), bytes };
00228 }
00229
00230 static void end_ebml_master(AVIOContext *pb, ebml_master master)
00231 {
00232 int64_t pos = avio_tell(pb);
00233
00234 if (avio_seek(pb, master.pos - master.sizebytes, SEEK_SET) < 0)
00235 return;
00236 put_ebml_num(pb, pos - master.pos, master.sizebytes);
00237 avio_seek(pb, pos, SEEK_SET);
00238 }
00239
00240 static void put_xiph_size(AVIOContext *pb, int size)
00241 {
00242 int i;
00243 for (i = 0; i < size / 255; i++)
00244 avio_w8(pb, 255);
00245 avio_w8(pb, size % 255);
00246 }
00247
00259 static mkv_seekhead * mkv_start_seekhead(AVIOContext *pb, int64_t segment_offset, int numelements)
00260 {
00261 mkv_seekhead *new_seekhead = av_mallocz(sizeof(mkv_seekhead));
00262 if (new_seekhead == NULL)
00263 return NULL;
00264
00265 new_seekhead->segment_offset = segment_offset;
00266
00267 if (numelements > 0) {
00268 new_seekhead->filepos = avio_tell(pb);
00269
00270
00271
00272 new_seekhead->reserved_size = numelements * MAX_SEEKENTRY_SIZE + 13;
00273 new_seekhead->max_entries = numelements;
00274 put_ebml_void(pb, new_seekhead->reserved_size);
00275 }
00276 return new_seekhead;
00277 }
00278
00279 static int mkv_add_seekhead_entry(mkv_seekhead *seekhead, unsigned int elementid, uint64_t filepos)
00280 {
00281 mkv_seekhead_entry *entries = seekhead->entries;
00282
00283
00284 if (seekhead->max_entries > 0 && seekhead->max_entries <= seekhead->num_entries)
00285 return -1;
00286
00287 entries = av_realloc(entries, (seekhead->num_entries + 1) * sizeof(mkv_seekhead_entry));
00288 if (entries == NULL)
00289 return AVERROR(ENOMEM);
00290
00291 entries[seekhead->num_entries ].elementid = elementid;
00292 entries[seekhead->num_entries++].segmentpos = filepos - seekhead->segment_offset;
00293
00294 seekhead->entries = entries;
00295 return 0;
00296 }
00297
00307 static int64_t mkv_write_seekhead(AVIOContext *pb, mkv_seekhead *seekhead)
00308 {
00309 ebml_master metaseek, seekentry;
00310 int64_t currentpos;
00311 int i;
00312
00313 currentpos = avio_tell(pb);
00314
00315 if (seekhead->reserved_size > 0)
00316 if (avio_seek(pb, seekhead->filepos, SEEK_SET) < 0)
00317 return -1;
00318
00319 metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_size);
00320 for (i = 0; i < seekhead->num_entries; i++) {
00321 mkv_seekhead_entry *entry = &seekhead->entries[i];
00322
00323 seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_SIZE);
00324
00325 put_ebml_id(pb, MATROSKA_ID_SEEKID);
00326 put_ebml_num(pb, ebml_id_size(entry->elementid), 0);
00327 put_ebml_id(pb, entry->elementid);
00328
00329 put_ebml_uint(pb, MATROSKA_ID_SEEKPOSITION, entry->segmentpos);
00330 end_ebml_master(pb, seekentry);
00331 }
00332 end_ebml_master(pb, metaseek);
00333
00334 if (seekhead->reserved_size > 0) {
00335 uint64_t remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
00336 put_ebml_void(pb, remaining);
00337 avio_seek(pb, currentpos, SEEK_SET);
00338
00339 currentpos = seekhead->filepos;
00340 }
00341 av_free(seekhead->entries);
00342 av_free(seekhead);
00343
00344 return currentpos;
00345 }
00346
00347 static mkv_cues * mkv_start_cues(int64_t segment_offset)
00348 {
00349 mkv_cues *cues = av_mallocz(sizeof(mkv_cues));
00350 if (cues == NULL)
00351 return NULL;
00352
00353 cues->segment_offset = segment_offset;
00354 return cues;
00355 }
00356
00357 static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos)
00358 {
00359 mkv_cuepoint *entries = cues->entries;
00360
00361 entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint));
00362 if (entries == NULL)
00363 return AVERROR(ENOMEM);
00364
00365 if (ts < 0)
00366 return 0;
00367
00368 entries[cues->num_entries ].pts = ts;
00369 entries[cues->num_entries ].tracknum = stream + 1;
00370 entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset;
00371
00372 cues->entries = entries;
00373 return 0;
00374 }
00375
00376 static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, int num_tracks)
00377 {
00378 ebml_master cues_element;
00379 int64_t currentpos;
00380 int i, j;
00381
00382 currentpos = avio_tell(pb);
00383 cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0);
00384
00385 for (i = 0; i < cues->num_entries; i++) {
00386 ebml_master cuepoint, track_positions;
00387 mkv_cuepoint *entry = &cues->entries[i];
00388 uint64_t pts = entry->pts;
00389
00390 cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks));
00391 put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts);
00392
00393
00394
00395 for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {
00396 track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);
00397 put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum );
00398 put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos);
00399 end_ebml_master(pb, track_positions);
00400 }
00401 i += j - 1;
00402 end_ebml_master(pb, cuepoint);
00403 }
00404 end_ebml_master(pb, cues_element);
00405
00406 av_free(cues->entries);
00407 av_free(cues);
00408 return currentpos;
00409 }
00410
00411 static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec)
00412 {
00413 uint8_t *header_start[3];
00414 int header_len[3];
00415 int first_header_size;
00416 int j;
00417
00418 if (codec->codec_id == CODEC_ID_VORBIS)
00419 first_header_size = 30;
00420 else
00421 first_header_size = 42;
00422
00423 if (ff_split_xiph_headers(codec->extradata, codec->extradata_size,
00424 first_header_size, header_start, header_len) < 0) {
00425 av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
00426 return -1;
00427 }
00428
00429 avio_w8(pb, 2);
00430 for (j = 0; j < 2; j++) {
00431 put_xiph_size(pb, header_len[j]);
00432 }
00433 for (j = 0; j < 3; j++)
00434 avio_write(pb, header_start[j], header_len[j]);
00435
00436 return 0;
00437 }
00438
00439 static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate)
00440 {
00441 int sri;
00442
00443 if (codec->extradata_size < 2) {
00444 av_log(s, AV_LOG_WARNING, "No AAC extradata, unable to determine samplerate.\n");
00445 return;
00446 }
00447
00448 sri = ((codec->extradata[0] << 1) & 0xE) | (codec->extradata[1] >> 7);
00449 if (sri > 12) {
00450 av_log(s, AV_LOG_WARNING, "AAC samplerate index out of bounds\n");
00451 return;
00452 }
00453 *sample_rate = ff_mpeg4audio_sample_rates[sri];
00454
00455
00456 if (codec->extradata_size == 5) {
00457 sri = (codec->extradata[4] >> 3) & 0xF;
00458 if (sri > 12) {
00459 av_log(s, AV_LOG_WARNING, "AAC output samplerate index out of bounds\n");
00460 return;
00461 }
00462 *output_sample_rate = ff_mpeg4audio_sample_rates[sri];
00463 }
00464 }
00465
00466 static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec, int native_id, int qt_id)
00467 {
00468 AVIOContext *dyn_cp;
00469 uint8_t *codecpriv;
00470 int ret, codecpriv_size;
00471
00472 ret = url_open_dyn_buf(&dyn_cp);
00473 if(ret < 0)
00474 return ret;
00475
00476 if (native_id) {
00477 if (codec->codec_id == CODEC_ID_VORBIS || codec->codec_id == CODEC_ID_THEORA)
00478 ret = put_xiph_codecpriv(s, dyn_cp, codec);
00479 else if (codec->codec_id == CODEC_ID_FLAC)
00480 ret = ff_flac_write_header(dyn_cp, codec, 1);
00481 else if (codec->codec_id == CODEC_ID_H264)
00482 ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
00483 else if (codec->extradata_size)
00484 avio_write(dyn_cp, codec->extradata, codec->extradata_size);
00485 } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00486 if (qt_id) {
00487 if (!codec->codec_tag)
00488 codec->codec_tag = ff_codec_get_tag(codec_movvideo_tags, codec->codec_id);
00489 if (codec->extradata_size)
00490 avio_write(dyn_cp, codec->extradata, codec->extradata_size);
00491 } else {
00492 if (!codec->codec_tag)
00493 codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id);
00494 if (!codec->codec_tag) {
00495 av_log(s, AV_LOG_ERROR, "No bmp codec ID found.\n");
00496 ret = -1;
00497 }
00498
00499 ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0);
00500 }
00501
00502 } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00503 unsigned int tag;
00504 tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id);
00505 if (!tag) {
00506 av_log(s, AV_LOG_ERROR, "No wav codec ID found.\n");
00507 ret = -1;
00508 }
00509 if (!codec->codec_tag)
00510 codec->codec_tag = tag;
00511
00512 ff_put_wav_header(dyn_cp, codec);
00513 }
00514
00515 codecpriv_size = url_close_dyn_buf(dyn_cp, &codecpriv);
00516 if (codecpriv_size)
00517 put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv, codecpriv_size);
00518 av_free(codecpriv);
00519 return ret;
00520 }
00521
00522 static int mkv_write_tracks(AVFormatContext *s)
00523 {
00524 MatroskaMuxContext *mkv = s->priv_data;
00525 AVIOContext *pb = s->pb;
00526 ebml_master tracks;
00527 int i, j, ret;
00528
00529 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, avio_tell(pb));
00530 if (ret < 0) return ret;
00531
00532 tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS, 0);
00533 for (i = 0; i < s->nb_streams; i++) {
00534 AVStream *st = s->streams[i];
00535 AVCodecContext *codec = st->codec;
00536 ebml_master subinfo, track;
00537 int native_id = 0;
00538 int qt_id = 0;
00539 int bit_depth = av_get_bits_per_sample(codec->codec_id);
00540 int sample_rate = codec->sample_rate;
00541 int output_sample_rate = 0;
00542 AVMetadataTag *tag;
00543
00544 if (!bit_depth)
00545 bit_depth = av_get_bits_per_sample_fmt(codec->sample_fmt);
00546
00547 if (codec->codec_id == CODEC_ID_AAC)
00548 get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate);
00549
00550 track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0);
00551 put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1);
00552 put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1);
00553 put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0);
00554
00555 if ((tag = av_metadata_get(st->metadata, "title", NULL, 0)))
00556 put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
00557 tag = av_metadata_get(st->metadata, "language", NULL, 0);
00558 put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
00559
00560 if (st->disposition)
00561 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
00562
00563
00564
00565 for (j = 0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++) {
00566 if (ff_mkv_codec_tags[j].id == codec->codec_id) {
00567 put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str);
00568 native_id = 1;
00569 break;
00570 }
00571 }
00572
00573 if (mkv->mode == MODE_WEBM && !(codec->codec_id == CODEC_ID_VP8 ||
00574 codec->codec_id == CODEC_ID_VORBIS)) {
00575 av_log(s, AV_LOG_ERROR,
00576 "Only VP8 video and Vorbis audio are supported for WebM.\n");
00577 return AVERROR(EINVAL);
00578 }
00579
00580 switch (codec->codec_type) {
00581 case AVMEDIA_TYPE_VIDEO:
00582 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
00583 put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9);
00584
00585 if (!native_id &&
00586 ff_codec_get_tag(codec_movvideo_tags, codec->codec_id) &&
00587 (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id)
00588 || codec->codec_id == CODEC_ID_SVQ1
00589 || codec->codec_id == CODEC_ID_SVQ3
00590 || codec->codec_id == CODEC_ID_CINEPAK))
00591 qt_id = 1;
00592
00593 if (qt_id)
00594 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME");
00595 else if (!native_id) {
00596
00597 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC");
00598 mkv->tracks[i].write_dts = 1;
00599 }
00600
00601 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0);
00602
00603 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
00604 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
00605 if (st->sample_aspect_ratio.num) {
00606 int d_width = codec->width*av_q2d(st->sample_aspect_ratio);
00607 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
00608 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height);
00609 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYUNIT, 3);
00610 }
00611 end_ebml_master(pb, subinfo);
00612 break;
00613
00614 case AVMEDIA_TYPE_AUDIO:
00615 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO);
00616
00617 if (!native_id)
00618
00619 put_ebml_string(pb, MATROSKA_ID_CODECID, "A_MS/ACM");
00620
00621 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 0);
00622 put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , codec->channels);
00623 put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate);
00624 if (output_sample_rate)
00625 put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate);
00626 if (bit_depth)
00627 put_ebml_uint(pb, MATROSKA_ID_AUDIOBITDEPTH, bit_depth);
00628 end_ebml_master(pb, subinfo);
00629 break;
00630
00631 case AVMEDIA_TYPE_SUBTITLE:
00632 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_SUBTITLE);
00633 break;
00634 default:
00635 av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska.");
00636 break;
00637 }
00638 ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id);
00639 if (ret < 0) return ret;
00640
00641 end_ebml_master(pb, track);
00642
00643
00644 av_set_pts_info(st, 64, 1, 1000);
00645 }
00646 end_ebml_master(pb, tracks);
00647 return 0;
00648 }
00649
00650 static int mkv_write_chapters(AVFormatContext *s)
00651 {
00652 MatroskaMuxContext *mkv = s->priv_data;
00653 AVIOContext *pb = s->pb;
00654 ebml_master chapters, editionentry;
00655 AVRational scale = {1, 1E9};
00656 int i, ret;
00657
00658 if (!s->nb_chapters)
00659 return 0;
00660
00661 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, avio_tell(pb));
00662 if (ret < 0) return ret;
00663
00664 chapters = start_ebml_master(pb, MATROSKA_ID_CHAPTERS , 0);
00665 editionentry = start_ebml_master(pb, MATROSKA_ID_EDITIONENTRY, 0);
00666 put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGDEFAULT, 1);
00667 put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGHIDDEN , 0);
00668 for (i = 0; i < s->nb_chapters; i++) {
00669 ebml_master chapteratom, chapterdisplay;
00670 AVChapter *c = s->chapters[i];
00671 AVMetadataTag *t = NULL;
00672
00673 chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0);
00674 put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id);
00675 put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART,
00676 av_rescale_q(c->start, c->time_base, scale));
00677 put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND,
00678 av_rescale_q(c->end, c->time_base, scale));
00679 put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGHIDDEN , 0);
00680 put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGENABLED, 1);
00681 if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) {
00682 chapterdisplay = start_ebml_master(pb, MATROSKA_ID_CHAPTERDISPLAY, 0);
00683 put_ebml_string(pb, MATROSKA_ID_CHAPSTRING, t->value);
00684 put_ebml_string(pb, MATROSKA_ID_CHAPLANG , "und");
00685 end_ebml_master(pb, chapterdisplay);
00686 }
00687 end_ebml_master(pb, chapteratom);
00688 }
00689 end_ebml_master(pb, editionentry);
00690 end_ebml_master(pb, chapters);
00691 return 0;
00692 }
00693
00694 static void mkv_write_simpletag(AVIOContext *pb, AVMetadataTag *t)
00695 {
00696 uint8_t *key = av_strdup(t->key);
00697 uint8_t *p = key;
00698 const uint8_t *lang = NULL;
00699 ebml_master tag;
00700
00701 if ((p = strrchr(p, '-')) &&
00702 (lang = av_convert_lang_to(p + 1, AV_LANG_ISO639_2_BIBL)))
00703 *p = 0;
00704
00705 p = key;
00706 while (*p) {
00707 if (*p == ' ')
00708 *p = '_';
00709 else if (*p >= 'a' && *p <= 'z')
00710 *p -= 'a' - 'A';
00711 p++;
00712 }
00713
00714 tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0);
00715 put_ebml_string(pb, MATROSKA_ID_TAGNAME, key);
00716 if (lang)
00717 put_ebml_string(pb, MATROSKA_ID_TAGLANG, lang);
00718 put_ebml_string(pb, MATROSKA_ID_TAGSTRING, t->value);
00719 end_ebml_master(pb, tag);
00720
00721 av_freep(&key);
00722 }
00723
00724 static int mkv_write_tag(AVFormatContext *s, AVMetadata *m, unsigned int elementid,
00725 unsigned int uid, ebml_master *tags)
00726 {
00727 MatroskaMuxContext *mkv = s->priv_data;
00728 ebml_master tag, targets;
00729 AVMetadataTag *t = NULL;
00730 int ret;
00731
00732 if (!tags->pos) {
00733 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, avio_tell(s->pb));
00734 if (ret < 0) return ret;
00735
00736 *tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0);
00737 }
00738
00739 tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0);
00740 targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0);
00741 if (elementid)
00742 put_ebml_uint(s->pb, elementid, uid);
00743 end_ebml_master(s->pb, targets);
00744
00745 while ((t = av_metadata_get(m, "", t, AV_METADATA_IGNORE_SUFFIX)))
00746 if (strcasecmp(t->key, "title"))
00747 mkv_write_simpletag(s->pb, t);
00748
00749 end_ebml_master(s->pb, tag);
00750 return 0;
00751 }
00752
00753 static int mkv_write_tags(AVFormatContext *s)
00754 {
00755 ebml_master tags = {0};
00756 int i, ret;
00757
00758 ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
00759
00760 if (av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) {
00761 ret = mkv_write_tag(s, s->metadata, 0, 0, &tags);
00762 if (ret < 0) return ret;
00763 }
00764
00765 for (i = 0; i < s->nb_streams; i++) {
00766 AVStream *st = s->streams[i];
00767
00768 if (!av_metadata_get(st->metadata, "", 0, AV_METADATA_IGNORE_SUFFIX))
00769 continue;
00770
00771 ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags);
00772 if (ret < 0) return ret;
00773 }
00774
00775 for (i = 0; i < s->nb_chapters; i++) {
00776 AVChapter *ch = s->chapters[i];
00777
00778 if (!av_metadata_get(ch->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
00779 continue;
00780
00781 ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags);
00782 if (ret < 0) return ret;
00783 }
00784
00785 if (tags.pos)
00786 end_ebml_master(s->pb, tags);
00787 return 0;
00788 }
00789
00790 static int mkv_write_header(AVFormatContext *s)
00791 {
00792 MatroskaMuxContext *mkv = s->priv_data;
00793 AVIOContext *pb = s->pb;
00794 ebml_master ebml_header, segment_info;
00795 AVMetadataTag *tag;
00796 int ret, i;
00797
00798 if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM;
00799 else mkv->mode = MODE_MATROSKAv2;
00800
00801 mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks));
00802 if (!mkv->tracks)
00803 return AVERROR(ENOMEM);
00804
00805 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0);
00806 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1);
00807 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1);
00808 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4);
00809 put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8);
00810 put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name);
00811 put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2);
00812 put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2);
00813 end_ebml_master(pb, ebml_header);
00814
00815 mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT, 0);
00816 mkv->segment_offset = avio_tell(pb);
00817
00818
00819
00820
00821
00822
00823 mkv->main_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 10);
00824 if (!mkv->main_seekhead)
00825 return AVERROR(ENOMEM);
00826
00827 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, avio_tell(pb));
00828 if (ret < 0) return ret;
00829
00830 segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0);
00831 put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
00832 if ((tag = av_metadata_get(s->metadata, "title", NULL, 0)))
00833 put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value);
00834 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
00835 uint32_t segment_uid[4];
00836 AVLFG lfg;
00837
00838 av_lfg_init(&lfg, av_get_random_seed());
00839
00840 for (i = 0; i < 4; i++)
00841 segment_uid[i] = av_lfg_get(&lfg);
00842
00843 put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT);
00844 put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT);
00845 put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16);
00846 }
00847
00848
00849 mkv->duration = 0;
00850 mkv->duration_offset = avio_tell(pb);
00851 put_ebml_void(pb, 11);
00852 end_ebml_master(pb, segment_info);
00853
00854 ret = mkv_write_tracks(s);
00855 if (ret < 0) return ret;
00856
00857 if (mkv->mode != MODE_WEBM) {
00858 ret = mkv_write_chapters(s);
00859 if (ret < 0) return ret;
00860
00861 ret = mkv_write_tags(s);
00862 if (ret < 0) return ret;
00863 }
00864
00865 if (url_is_streamed(s->pb))
00866 mkv_write_seekhead(pb, mkv->main_seekhead);
00867
00868 mkv->cues = mkv_start_cues(mkv->segment_offset);
00869 if (mkv->cues == NULL)
00870 return AVERROR(ENOMEM);
00871
00872 av_init_packet(&mkv->cur_audio_pkt);
00873 mkv->cur_audio_pkt.size = 0;
00874 mkv->audio_buffer_size = 0;
00875
00876 put_flush_packet(pb);
00877 return 0;
00878 }
00879
00880 static int mkv_blockgroup_size(int pkt_size)
00881 {
00882 int size = pkt_size + 4;
00883 size += ebml_num_size(size);
00884 size += 2;
00885 size += 8;
00886 size += ebml_num_size(size);
00887 size += 1;
00888 return size;
00889 }
00890
00891 static int ass_get_duration(const uint8_t *p)
00892 {
00893 int sh, sm, ss, sc, eh, em, es, ec;
00894 uint64_t start, end;
00895
00896 if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d",
00897 &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8)
00898 return 0;
00899 start = 3600000*sh + 60000*sm + 1000*ss + 10*sc;
00900 end = 3600000*eh + 60000*em + 1000*es + 10*ec;
00901 return end - start;
00902 }
00903
00904 static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
00905 {
00906 MatroskaMuxContext *mkv = s->priv_data;
00907 int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size;
00908 uint8_t *start, *end, *data = pkt->data;
00909 ebml_master blockgroup;
00910 char buffer[2048];
00911
00912 while (data_size) {
00913 int duration = ass_get_duration(data);
00914 max_duration = FFMAX(duration, max_duration);
00915 end = memchr(data, '\n', data_size);
00916 size = line_size = end ? end-data+1 : data_size;
00917 size -= end ? (end[-1]=='\r')+1 : 0;
00918 start = data;
00919 for (i=0; i<3; i++, start++)
00920 if (!(start = memchr(start, ',', size-(start-data))))
00921 return max_duration;
00922 size -= start - data;
00923 sscanf(data, "Dialogue: %d,", &layer);
00924 i = snprintf(buffer, sizeof(buffer), "%"PRId64",%d,",
00925 s->streams[pkt->stream_index]->nb_frames++, layer);
00926 size = FFMIN(i+size, sizeof(buffer));
00927 memcpy(buffer+i, start, size-i);
00928
00929 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
00930 "pts %" PRId64 ", duration %d\n",
00931 avio_tell(pb), size, pkt->pts, duration);
00932 blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size));
00933 put_ebml_id(pb, MATROSKA_ID_BLOCK);
00934 put_ebml_num(pb, size+4, 0);
00935 avio_w8(pb, 0x80 | (pkt->stream_index + 1));
00936 avio_wb16(pb, pkt->pts - mkv->cluster_pts);
00937 avio_w8(pb, 0);
00938 avio_write(pb, buffer, size);
00939 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
00940 end_ebml_master(pb, blockgroup);
00941
00942 data += line_size;
00943 data_size -= line_size;
00944 }
00945
00946 return max_duration;
00947 }
00948
00949 static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
00950 unsigned int blockid, AVPacket *pkt, int flags)
00951 {
00952 MatroskaMuxContext *mkv = s->priv_data;
00953 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
00954 uint8_t *data = NULL;
00955 int size = pkt->size;
00956 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
00957
00958 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
00959 "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
00960 avio_tell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags);
00961 if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 &&
00962 (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1))
00963 ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
00964 else
00965 data = pkt->data;
00966 put_ebml_id(pb, blockid);
00967 put_ebml_num(pb, size+4, 0);
00968 avio_w8(pb, 0x80 | (pkt->stream_index + 1));
00969 avio_wb16(pb, ts - mkv->cluster_pts);
00970 avio_w8(pb, flags);
00971 avio_write(pb, data, size);
00972 if (data != pkt->data)
00973 av_free(data);
00974 }
00975
00976 static int srt_get_duration(uint8_t **buf)
00977 {
00978 int i, duration = 0;
00979
00980 for (i=0; i<2 && !duration; i++) {
00981 int s_hour, s_min, s_sec, s_hsec, e_hour, e_min, e_sec, e_hsec;
00982 if (sscanf(*buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d",
00983 &s_hour, &s_min, &s_sec, &s_hsec,
00984 &e_hour, &e_min, &e_sec, &e_hsec) == 8) {
00985 s_min += 60*s_hour; e_min += 60*e_hour;
00986 s_sec += 60*s_min; e_sec += 60*e_min;
00987 s_hsec += 1000*s_sec; e_hsec += 1000*e_sec;
00988 duration = e_hsec - s_hsec;
00989 }
00990 *buf += strcspn(*buf, "\n") + 1;
00991 }
00992 return duration;
00993 }
00994
00995 static int mkv_write_srt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
00996 {
00997 ebml_master blockgroup;
00998 AVPacket pkt2 = *pkt;
00999 int64_t duration = srt_get_duration(&pkt2.data);
01000 pkt2.size -= pkt2.data - pkt->data;
01001
01002 blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
01003 mkv_blockgroup_size(pkt2.size));
01004 mkv_write_block(s, pb, MATROSKA_ID_BLOCK, &pkt2, 0);
01005 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
01006 end_ebml_master(pb, blockgroup);
01007
01008 return duration;
01009 }
01010
01011 static void mkv_flush_dynbuf(AVFormatContext *s)
01012 {
01013 MatroskaMuxContext *mkv = s->priv_data;
01014 int bufsize;
01015 uint8_t *dyn_buf;
01016
01017 if (!mkv->dyn_bc)
01018 return;
01019
01020 bufsize = url_close_dyn_buf(mkv->dyn_bc, &dyn_buf);
01021 avio_write(s->pb, dyn_buf, bufsize);
01022 av_free(dyn_buf);
01023 mkv->dyn_bc = NULL;
01024 }
01025
01026 static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
01027 {
01028 MatroskaMuxContext *mkv = s->priv_data;
01029 AVIOContext *pb = s->pb;
01030 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
01031 int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
01032 int duration = pkt->duration;
01033 int ret;
01034 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
01035
01036 if (ts == AV_NOPTS_VALUE) {
01037 av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n");
01038 return AVERROR(EINVAL);
01039 }
01040
01041 if (url_is_streamed(s->pb)) {
01042 if (!mkv->dyn_bc)
01043 url_open_dyn_buf(&mkv->dyn_bc);
01044 pb = mkv->dyn_bc;
01045 }
01046
01047 if (!mkv->cluster_pos) {
01048 mkv->cluster_pos = avio_tell(s->pb);
01049 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
01050 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts));
01051 mkv->cluster_pts = FFMAX(0, ts);
01052 }
01053
01054 if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
01055 mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7);
01056 } else if (codec->codec_id == CODEC_ID_SSA) {
01057 duration = mkv_write_ass_blocks(s, pb, pkt);
01058 } else if (codec->codec_id == CODEC_ID_SRT) {
01059 duration = mkv_write_srt_blocks(s, pb, pkt);
01060 } else {
01061 ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size));
01062 duration = pkt->convergence_duration;
01063 mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0);
01064 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
01065 end_ebml_master(pb, blockgroup);
01066 }
01067
01068 if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) {
01069 ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos);
01070 if (ret < 0) return ret;
01071 }
01072
01073 mkv->duration = FFMAX(mkv->duration, ts + duration);
01074 return 0;
01075 }
01076
01077 static int mkv_copy_packet(MatroskaMuxContext *mkv, const AVPacket *pkt)
01078 {
01079 uint8_t *data = mkv->cur_audio_pkt.data;
01080 mkv->cur_audio_pkt = *pkt;
01081 mkv->cur_audio_pkt.data = av_fast_realloc(data, &mkv->audio_buffer_size, pkt->size);
01082 if (!mkv->cur_audio_pkt.data)
01083 return AVERROR(ENOMEM);
01084
01085 memcpy(mkv->cur_audio_pkt.data, pkt->data, pkt->size);
01086 mkv->cur_audio_pkt.size = pkt->size;
01087 return 0;
01088 }
01089
01090 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
01091 {
01092 MatroskaMuxContext *mkv = s->priv_data;
01093 AVIOContext *pb = url_is_streamed(s->pb) ? mkv->dyn_bc : s->pb;
01094 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
01095 int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
01096 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
01097 int cluster_size = avio_tell(pb) - (url_is_streamed(s->pb) ? 0 : mkv->cluster_pos);
01098
01099
01100
01101 if (mkv->cluster_pos &&
01102 ((url_is_streamed(s->pb) && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
01103 || cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000
01104 || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) {
01105 av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
01106 " bytes, pts %" PRIu64 "\n", avio_tell(pb), ts);
01107 end_ebml_master(pb, mkv->cluster);
01108 mkv->cluster_pos = 0;
01109 if (mkv->dyn_bc)
01110 mkv_flush_dynbuf(s);
01111 }
01112
01113
01114 if (mkv->cur_audio_pkt.size > 0) {
01115 ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt);
01116 mkv->cur_audio_pkt.size = 0;
01117 if (ret < 0) {
01118 av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret);
01119 return ret;
01120 }
01121 }
01122
01123
01124
01125 if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
01126 ret = mkv_copy_packet(mkv, pkt);
01127 else
01128 ret = mkv_write_packet_internal(s, pkt);
01129 return ret;
01130 }
01131
01132 static int mkv_write_trailer(AVFormatContext *s)
01133 {
01134 MatroskaMuxContext *mkv = s->priv_data;
01135 AVIOContext *pb = s->pb;
01136 int64_t currentpos, cuespos;
01137 int ret;
01138
01139
01140 if (mkv->cur_audio_pkt.size > 0) {
01141 ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt);
01142 mkv->cur_audio_pkt.size = 0;
01143 if (ret < 0) {
01144 av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret);
01145 return ret;
01146 }
01147 }
01148
01149 if (mkv->dyn_bc) {
01150 end_ebml_master(mkv->dyn_bc, mkv->cluster);
01151 mkv_flush_dynbuf(s);
01152 } else if (mkv->cluster_pos) {
01153 end_ebml_master(pb, mkv->cluster);
01154 }
01155
01156 if (!url_is_streamed(pb)) {
01157 cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
01158
01159 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , cuespos);
01160 if (ret < 0) return ret;
01161 mkv_write_seekhead(pb, mkv->main_seekhead);
01162
01163
01164 av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
01165 currentpos = avio_tell(pb);
01166 avio_seek(pb, mkv->duration_offset, SEEK_SET);
01167 put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);
01168
01169 avio_seek(pb, currentpos, SEEK_SET);
01170 }
01171
01172 end_ebml_master(pb, mkv->segment);
01173 av_free(mkv->tracks);
01174 av_destruct_packet(&mkv->cur_audio_pkt);
01175 put_flush_packet(pb);
01176 return 0;
01177 }
01178
01179 #if CONFIG_MATROSKA_MUXER
01180 AVOutputFormat ff_matroska_muxer = {
01181 "matroska",
01182 NULL_IF_CONFIG_SMALL("Matroska file format"),
01183 "video/x-matroska",
01184 "mkv",
01185 sizeof(MatroskaMuxContext),
01186 CODEC_ID_MP2,
01187 CODEC_ID_MPEG4,
01188 mkv_write_header,
01189 mkv_write_packet,
01190 mkv_write_trailer,
01191 .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
01192 .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
01193 .subtitle_codec = CODEC_ID_TEXT,
01194 };
01195 #endif
01196
01197 #if CONFIG_WEBM_MUXER
01198 AVOutputFormat ff_webm_muxer = {
01199 "webm",
01200 NULL_IF_CONFIG_SMALL("WebM file format"),
01201 "video/webm",
01202 "webm",
01203 sizeof(MatroskaMuxContext),
01204 CODEC_ID_VORBIS,
01205 CODEC_ID_VP8,
01206 mkv_write_header,
01207 mkv_write_packet,
01208 mkv_write_trailer,
01209 .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
01210 };
01211 #endif
01212
01213 #if CONFIG_MATROSKA_AUDIO_MUXER
01214 AVOutputFormat ff_matroska_audio_muxer = {
01215 "matroska",
01216 NULL_IF_CONFIG_SMALL("Matroska file format"),
01217 "audio/x-matroska",
01218 "mka",
01219 sizeof(MatroskaMuxContext),
01220 CODEC_ID_MP2,
01221 CODEC_ID_NONE,
01222 mkv_write_header,
01223 mkv_write_packet,
01224 mkv_write_trailer,
01225 .flags = AVFMT_GLOBALHEADER,
01226 .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
01227 };
01228 #endif