muxer: added initial support for the webm container
This commit is contained in:
parent
08bd137d6f
commit
2f3e37232d
5 changed files with 29 additions and 12 deletions
|
@ -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 },
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef enum {
|
|||
MC_MPEGPS = 3,
|
||||
MC_PASS = 4,
|
||||
MC_RAW = 5,
|
||||
MC_WEBM = 6,
|
||||
} muxer_container_type_t;
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue