From 2f3e37232d25d7b30c9ce6adcf4dd91006e26c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20T=C3=B6rblom?= Date: Wed, 17 Jul 2013 16:45:00 +0200 Subject: [PATCH] muxer: added initial support for the webm container --- src/muxer.c | 5 +++++ src/muxer.h | 1 + src/muxer/muxer_tvh.c | 4 ++-- src/muxer/tvh/mkmux.c | 29 ++++++++++++++++++++--------- src/muxer/tvh/mkmux.h | 2 +- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/muxer.c b/src/muxer.c index e252a53b..e65154ae 100644 --- a/src/muxer.c +++ b/src/muxer.c @@ -33,6 +33,7 @@ static struct strtab container_audio_mime[] = { { "application/octet-stream", MC_UNKNOWN }, { "audio/x-matroska", MC_MATROSKA }, + { "audio/webm", MC_WEBM }, { "audio/x-mpegts", MC_MPEGTS }, { "audio/mpeg", MC_MPEGPS }, { "application/octet-stream", MC_PASS }, @@ -46,6 +47,7 @@ static struct strtab container_audio_mime[] = { static struct strtab container_video_mime[] = { { "application/octet-stream", MC_UNKNOWN }, { "video/x-matroska", MC_MATROSKA }, + { "video/webm", MC_WEBM }, { "video/x-mpegts", MC_MPEGTS }, { "video/mpeg", MC_MPEGPS }, { "application/octet-stream", MC_PASS }, @@ -59,6 +61,7 @@ static struct strtab container_video_mime[] = { static struct strtab container_name[] = { { "unknown", MC_UNKNOWN }, { "matroska", MC_MATROSKA }, + { "webm", MC_WEBM }, { "mpegts", MC_MPEGTS }, { "mpegps", MC_MPEGPS }, { "pass", MC_PASS }, @@ -72,6 +75,7 @@ static struct strtab container_name[] = { static struct strtab container_audio_file_suffix[] = { { "bin", MC_UNKNOWN }, { "mka", MC_MATROSKA }, + { "webm", MC_WEBM }, { "ts", MC_MPEGTS }, { "mpeg", MC_MPEGPS }, { "bin", MC_PASS }, @@ -85,6 +89,7 @@ static struct strtab container_audio_file_suffix[] = { static struct strtab container_video_file_suffix[] = { { "bin", MC_UNKNOWN }, { "mkv", MC_MATROSKA }, + { "webm", MC_WEBM }, { "ts", MC_MPEGTS }, { "mpeg", MC_MPEGPS }, { "bin", MC_PASS }, diff --git a/src/muxer.h b/src/muxer.h index 1cfc947a..9ec0d788 100644 --- a/src/muxer.h +++ b/src/muxer.h @@ -28,6 +28,7 @@ typedef enum { MC_MPEGPS = 3, MC_PASS = 4, MC_RAW = 5, + MC_WEBM = 6, } muxer_container_type_t; diff --git a/src/muxer/muxer_tvh.c b/src/muxer/muxer_tvh.c index 6d46b912..2619d9a7 100644 --- a/src/muxer/muxer_tvh.c +++ b/src/muxer/muxer_tvh.c @@ -224,7 +224,7 @@ tvh_muxer_create(muxer_container_type_t mc) { tvh_muxer_t *tm; - if(mc != MC_MATROSKA) + if(mc != MC_MATROSKA && mc != MC_WEBM) return NULL; tm = calloc(1, sizeof(tvh_muxer_t)); @@ -239,7 +239,7 @@ tvh_muxer_create(muxer_container_type_t mc) tm->m_close = tvh_muxer_close; tm->m_destroy = tvh_muxer_destroy; tm->m_container = mc; - tm->tm_ref = mk_mux_create(); + tm->tm_ref = mk_mux_create(mc == MC_WEBM); return (muxer_t*)tm; } diff --git a/src/muxer/tvh/mkmux.c b/src/muxer/tvh/mkmux.c index 81b9804e..955f64ac 100644 --- a/src/muxer/tvh/mkmux.c +++ b/src/muxer/tvh/mkmux.c @@ -119,6 +119,8 @@ struct mk_mux { char uuid[16]; char *title; + + int webm; }; @@ -126,7 +128,7 @@ struct mk_mux { * */ static htsbuf_queue_t * -mk_build_ebmlheader(void) +mk_build_ebmlheader(mk_mux_t *mkm) { htsbuf_queue_t *q = htsbuf_queue_alloc(0); @@ -134,7 +136,7 @@ mk_build_ebmlheader(void) ebml_append_uint(q, 0x42f7, 1); ebml_append_uint(q, 0x42f2, 4); ebml_append_uint(q, 0x42f3, 8); - ebml_append_string(q, 0x4282, "matroska"); + ebml_append_string(q, 0x4282, mkm->webm ? "webm" : "matroska"); ebml_append_uint(q, 0x4287, 2); ebml_append_uint(q, 0x4285, 2); return q; @@ -202,8 +204,12 @@ mk_build_segment_info(mk_mux_t *mkm) snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version); - ebml_append_bin(q, 0x73a4, mkm->uuid, sizeof(mkm->uuid)); - ebml_append_string(q, 0x7ba9, mkm->title); + if(!mkm->webm) + ebml_append_bin(q, 0x73a4, mkm->uuid, sizeof(mkm->uuid)); + + if(!mkm->webm) + ebml_append_string(q, 0x7ba9, mkm->title); + ebml_append_string(q, 0x4d80, "Tvheadend Matroska muxer"); ebml_append_string(q, 0x5741, app); ebml_append_uint(q, 0x2ad7b1, MATROSKA_TIMESCALE); @@ -380,11 +386,15 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss) ebml_append_uint(vi, 0xb0, ssc->ssc_width); ebml_append_uint(vi, 0xba, ssc->ssc_height); - if(ssc->ssc_aspect_num && ssc->ssc_aspect_den) { + if(mkm->webm && ssc->ssc_aspect_num && ssc->ssc_aspect_den) { + // DAR is not supported by webm + ebml_append_uint(vi, 0x54b2, 1); + ebml_append_uint(vi, 0x54b0, (ssc->ssc_height * ssc->ssc_aspect_num) / ssc->ssc_aspect_den); + ebml_append_uint(vi, 0x54ba, ssc->ssc_height); + } else if(ssc->ssc_aspect_num && ssc->ssc_aspect_den) { ebml_append_uint(vi, 0x54b2, 3); // Display width/height is in DAR ebml_append_uint(vi, 0x54b0, ssc->ssc_aspect_num); ebml_append_uint(vi, 0x54ba, ssc->ssc_aspect_den); - } ebml_append_master(t, 0xe0, vi); @@ -997,11 +1007,12 @@ mk_write_cues(mk_mux_t *mkm) /** * */ -mk_mux_t *mk_mux_create(void) +mk_mux_t *mk_mux_create(int webm) { mk_mux_t *mkm = calloc(1, sizeof(mk_mux_t)); - mkm->fd = -1; + mkm->webm = webm; + mkm->fd = -1; return mkm; } @@ -1066,7 +1077,7 @@ mk_mux_init(mk_mux_t *mkm, const char *title, const streaming_start_t *ss) htsbuf_queue_init(&q, 0); - ebml_append_master(&q, 0x1a45dfa3, mk_build_ebmlheader()); + ebml_append_master(&q, 0x1a45dfa3, mk_build_ebmlheader(mkm)); mkm->segment_header_pos = q.hq_size; htsbuf_appendq(&q, mk_build_segment_header(0)); diff --git a/src/muxer/tvh/mkmux.h b/src/muxer/tvh/mkmux.h index 8b44145d..44a4de49 100644 --- a/src/muxer/tvh/mkmux.h +++ b/src/muxer/tvh/mkmux.h @@ -28,7 +28,7 @@ struct th_pkt; struct channel; struct event; -mk_mux_t *mk_mux_create(void); +mk_mux_t *mk_mux_create(int webm); int mk_mux_open_file (mk_mux_t *mkm, const char *filename); int mk_mux_open_stream(mk_mux_t *mkm, int fd);