Commit 316d6c15 authored by James Zern's avatar James Zern Committed by David Conrad

Add WebM muxer

Patch by James Zern <jzern at google>

Originally committed as revision 23474 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent ac9baa71
...@@ -4,7 +4,7 @@ releases are sorted from youngest to oldest. ...@@ -4,7 +4,7 @@ releases are sorted from youngest to oldest.
version <next>: version <next>:
- WebM support in Matroska demuxer - WebM support in Matroska de/muxer
- low overhead Ogg muxing - low overhead Ogg muxing
- MMS-TCP support - MMS-TCP support
- VP8 de/encoding via libvpx - VP8 de/encoding via libvpx
......
...@@ -236,7 +236,7 @@ library: ...@@ -236,7 +236,7 @@ library:
@item VC-1 test bitstream @tab X @tab X @item VC-1 test bitstream @tab X @tab X
@item WAV @tab X @tab X @item WAV @tab X @tab X
@item WavPack @tab @tab X @item WavPack @tab @tab X
@item WebM @tab @tab X @item WebM @tab X @tab X
@item Wing Commander III movie @tab @tab X @item Wing Commander III movie @tab @tab X
@tab Multimedia format used in Origin's Wing Commander III computer game. @tab Multimedia format used in Origin's Wing Commander III computer game.
@item Westwood Studios audio @tab @tab X @item Westwood Studios audio @tab @tab X
......
...@@ -512,6 +512,8 @@ OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o \ ...@@ -512,6 +512,8 @@ OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o \
dirac.o mpeg12data.o dirac.o mpeg12data.o
OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o
OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o
OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \
flacdec.o flacdata.o flac.o
# external codec libraries # external codec libraries
OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o
......
...@@ -258,6 +258,9 @@ OBJS-$(CONFIG_W64_DEMUXER) += wav.o riff.o raw.o ...@@ -258,6 +258,9 @@ OBJS-$(CONFIG_W64_DEMUXER) += wav.o riff.o raw.o
OBJS-$(CONFIG_WAV_DEMUXER) += wav.o riff.o raw.o OBJS-$(CONFIG_WAV_DEMUXER) += wav.o riff.o raw.o
OBJS-$(CONFIG_WAV_MUXER) += wav.o riff.o OBJS-$(CONFIG_WAV_MUXER) += wav.o riff.o
OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o
OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \
riff.o isom.o avc.o \
flacenc_header.o
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood.o OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood.o
OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood.o OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood.o
OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o id3v1.o OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o id3v1.o
......
...@@ -206,6 +206,7 @@ void av_register_all(void) ...@@ -206,6 +206,7 @@ void av_register_all(void)
REGISTER_DEMUXER (W64, w64); REGISTER_DEMUXER (W64, w64);
REGISTER_MUXDEMUX (WAV, wav); REGISTER_MUXDEMUX (WAV, wav);
REGISTER_DEMUXER (WC3, wc3); REGISTER_DEMUXER (WC3, wc3);
REGISTER_MUXER (WEBM, webm);
REGISTER_DEMUXER (WSAUD, wsaud); REGISTER_DEMUXER (WSAUD, wsaud);
REGISTER_DEMUXER (WSVQA, wsvqa); REGISTER_DEMUXER (WSVQA, wsvqa);
REGISTER_DEMUXER (WV, wv); REGISTER_DEMUXER (WV, wv);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define AVFORMAT_AVFORMAT_H #define AVFORMAT_AVFORMAT_H
#define LIBAVFORMAT_VERSION_MAJOR 52 #define LIBAVFORMAT_VERSION_MAJOR 52
#define LIBAVFORMAT_VERSION_MINOR 67 #define LIBAVFORMAT_VERSION_MINOR 68
#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
......
...@@ -65,7 +65,11 @@ typedef struct { ...@@ -65,7 +65,11 @@ typedef struct {
int write_dts; int write_dts;
} mkv_track; } mkv_track;
#define MODE_MATROSKAv2 0x01
#define MODE_WEBM 0x02
typedef struct MatroskaMuxContext { typedef struct MatroskaMuxContext {
int mode;
ByteIOContext *dyn_bc; ByteIOContext *dyn_bc;
ebml_master segment; ebml_master segment;
int64_t segment_offset; int64_t segment_offset;
...@@ -565,6 +569,13 @@ static int mkv_write_tracks(AVFormatContext *s) ...@@ -565,6 +569,13 @@ static int mkv_write_tracks(AVFormatContext *s)
} }
} }
if (mkv->mode == MODE_WEBM && !(codec->codec_id == CODEC_ID_VP8 ||
codec->codec_id == CODEC_ID_VORBIS)) {
av_log(s, AV_LOG_ERROR,
"Only VP8 video and Vorbis audio are supported for WebM.\n");
return AVERROR(EINVAL);
}
switch (codec->codec_type) { switch (codec->codec_type) {
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
...@@ -686,6 +697,9 @@ static int mkv_write_header(AVFormatContext *s) ...@@ -686,6 +697,9 @@ static int mkv_write_header(AVFormatContext *s)
AVMetadataTag *tag; AVMetadataTag *tag;
int ret; int ret;
if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM;
else mkv->mode = MODE_MATROSKAv2;
mkv->md5_ctx = av_mallocz(av_md5_size); mkv->md5_ctx = av_mallocz(av_md5_size);
av_md5_init(mkv->md5_ctx); av_md5_init(mkv->md5_ctx);
mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks));
...@@ -695,7 +709,7 @@ static int mkv_write_header(AVFormatContext *s) ...@@ -695,7 +709,7 @@ static int mkv_write_header(AVFormatContext *s)
put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1);
put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4);
put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8);
put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska"); put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name);
put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2); put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2);
put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2);
end_ebml_master(pb, ebml_header); end_ebml_master(pb, ebml_header);
...@@ -738,8 +752,10 @@ static int mkv_write_header(AVFormatContext *s) ...@@ -738,8 +752,10 @@ static int mkv_write_header(AVFormatContext *s)
ret = mkv_write_tracks(s); ret = mkv_write_tracks(s);
if (ret < 0) return ret; if (ret < 0) return ret;
ret = mkv_write_chapters(s); if (mkv->mode != MODE_WEBM) {
if (ret < 0) return ret; ret = mkv_write_chapters(s);
if (ret < 0) return ret;
}
if (url_is_streamed(s->pb)) if (url_is_streamed(s->pb))
mkv_write_seekhead(pb, mkv->main_seekhead); mkv_write_seekhead(pb, mkv->main_seekhead);
...@@ -1035,6 +1051,7 @@ static int mkv_write_trailer(AVFormatContext *s) ...@@ -1035,6 +1051,7 @@ static int mkv_write_trailer(AVFormatContext *s)
return 0; return 0;
} }
#if CONFIG_MATROSKA_MUXER
AVOutputFormat matroska_muxer = { AVOutputFormat matroska_muxer = {
"matroska", "matroska",
NULL_IF_CONFIG_SMALL("Matroska file format"), NULL_IF_CONFIG_SMALL("Matroska file format"),
...@@ -1050,7 +1067,25 @@ AVOutputFormat matroska_muxer = { ...@@ -1050,7 +1067,25 @@ AVOutputFormat matroska_muxer = {
.codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
.subtitle_codec = CODEC_ID_TEXT, .subtitle_codec = CODEC_ID_TEXT,
}; };
#endif
#if CONFIG_WEBM_MUXER
AVOutputFormat webm_muxer = {
"webm",
NULL_IF_CONFIG_SMALL("WebM file format"),
"video/webm",
"webm",
sizeof(MatroskaMuxContext),
CODEC_ID_VORBIS,
CODEC_ID_VP8,
mkv_write_header,
mkv_write_packet,
mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
};
#endif
#if CONFIG_MATROSKA_AUDIO_MUXER
AVOutputFormat matroska_audio_muxer = { AVOutputFormat matroska_audio_muxer = {
"matroska", "matroska",
NULL_IF_CONFIG_SMALL("Matroska file format"), NULL_IF_CONFIG_SMALL("Matroska file format"),
...@@ -1065,3 +1100,4 @@ AVOutputFormat matroska_audio_muxer = { ...@@ -1065,3 +1100,4 @@ AVOutputFormat matroska_audio_muxer = {
.flags = AVFMT_GLOBALHEADER, .flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
}; };
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment