transcoding: added initial support for vorbis. might suffer from sync problems when frames are dropped earlier in the pipe line
This commit is contained in:
parent
e4b9f5960d
commit
08bd137d6f
8 changed files with 102 additions and 4 deletions
|
@ -77,6 +77,9 @@ streaming_component_type2codec_id(streaming_component_type_t type)
|
||||||
case SCT_MPEG2AUDIO:
|
case SCT_MPEG2AUDIO:
|
||||||
codec_id = CODEC_ID_MP2;
|
codec_id = CODEC_ID_MP2;
|
||||||
break;
|
break;
|
||||||
|
case SCT_VORBIS:
|
||||||
|
codec_id = CODEC_ID_VORBIS;
|
||||||
|
break;
|
||||||
case SCT_DVBSUB:
|
case SCT_DVBSUB:
|
||||||
codec_id = CODEC_ID_DVB_SUBTITLE;
|
codec_id = CODEC_ID_DVB_SUBTITLE;
|
||||||
break;
|
break;
|
||||||
|
@ -125,6 +128,9 @@ codec_id2streaming_component_type(enum CodecID id)
|
||||||
case CODEC_ID_MP2:
|
case CODEC_ID_MP2:
|
||||||
type = SCT_MPEG2AUDIO;
|
type = SCT_MPEG2AUDIO;
|
||||||
break;
|
break;
|
||||||
|
case CODEC_ID_VORBIS:
|
||||||
|
type = SCT_VORBIS;
|
||||||
|
break;
|
||||||
case CODEC_ID_DVB_SUBTITLE:
|
case CODEC_ID_DVB_SUBTITLE:
|
||||||
type = SCT_DVBSUB;
|
type = SCT_DVBSUB;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,6 +65,19 @@ ebml_append_size(htsbuf_queue_t *q, uint32_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ebml_append_xiph_size(htsbuf_queue_t *q, int size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t u8[4] = {0xff, size % 0xff};
|
||||||
|
|
||||||
|
for(i=0; i<size/0xff; i++)
|
||||||
|
htsbuf_append(q, u8, 1);
|
||||||
|
|
||||||
|
return htsbuf_append(q, u8+1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ebml_append_bin(htsbuf_queue_t *q, unsigned id, const void *data, size_t len)
|
ebml_append_bin(htsbuf_queue_t *q, unsigned id, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,8 @@ void ebml_append_id(htsbuf_queue_t *q, uint32_t id);
|
||||||
|
|
||||||
void ebml_append_size(htsbuf_queue_t *q, uint32_t size);
|
void ebml_append_size(htsbuf_queue_t *q, uint32_t size);
|
||||||
|
|
||||||
|
void ebml_append_xiph_size(htsbuf_queue_t *q, int size);
|
||||||
|
|
||||||
void ebml_append_bin(htsbuf_queue_t *q, unsigned id,
|
void ebml_append_bin(htsbuf_queue_t *q, unsigned id,
|
||||||
const void *data, size_t len);
|
const void *data, size_t len);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "tvheadend.h"
|
#include "tvheadend.h"
|
||||||
#include "streaming.h"
|
#include "streaming.h"
|
||||||
|
@ -157,6 +158,39 @@ getuuid(char *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mk_split_vorbis_headers(uint8_t *extradata, int extradata_size,
|
||||||
|
uint8_t *header_start[3], int header_len[3])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (extradata_size >= 3 && extradata_size < INT_MAX - 0x1ff && extradata[0] == 2) {
|
||||||
|
int overall_len = 3;
|
||||||
|
extradata++;
|
||||||
|
for (i=0; i<2; i++, extradata++) {
|
||||||
|
header_len[i] = 0;
|
||||||
|
for (; overall_len < extradata_size && *extradata==0xff; extradata++) {
|
||||||
|
header_len[i] += 0xff;
|
||||||
|
overall_len += 0xff + 1;
|
||||||
|
}
|
||||||
|
header_len[i] += *extradata;
|
||||||
|
overall_len += *extradata;
|
||||||
|
if (overall_len > extradata_size)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
header_len[2] = extradata_size - overall_len;
|
||||||
|
header_start[0] = extradata;
|
||||||
|
header_start[1] = header_start[0] + header_len[0];
|
||||||
|
header_start[2] = header_start[1] + header_len[1];
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -253,6 +287,11 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
|
||||||
codec_id = "A_AAC";
|
codec_id = "A_AAC";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCT_VORBIS:
|
||||||
|
tracktype = 2;
|
||||||
|
codec_id = "A_VORBIS";
|
||||||
|
break;
|
||||||
|
|
||||||
case SCT_DVBSUB:
|
case SCT_DVBSUB:
|
||||||
tracktype = 0x11;
|
tracktype = 0x11;
|
||||||
codec_id = "S_DVBSUB";
|
codec_id = "S_DVBSUB";
|
||||||
|
@ -294,6 +333,32 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
|
||||||
pktbuf_len(ssc->ssc_gh));
|
pktbuf_len(ssc->ssc_gh));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCT_VORBIS:
|
||||||
|
if(ssc->ssc_gh) {
|
||||||
|
htsbuf_queue_t *cp;
|
||||||
|
uint8_t *header_start[3];
|
||||||
|
int header_len[3];
|
||||||
|
int j;
|
||||||
|
if(mk_split_vorbis_headers(pktbuf_ptr(ssc->ssc_gh),
|
||||||
|
pktbuf_len(ssc->ssc_gh),
|
||||||
|
header_start,
|
||||||
|
header_len) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cp = htsbuf_queue_alloc(0);
|
||||||
|
|
||||||
|
ebml_append_xiph_size(cp, 2);
|
||||||
|
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
ebml_append_xiph_size(cp, header_len[j]);
|
||||||
|
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
htsbuf_append(cp, header_start[j], header_len[j]);
|
||||||
|
|
||||||
|
ebml_append_master(t, 0x63a2, cp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SCT_DVBSUB:
|
case SCT_DVBSUB:
|
||||||
buf4[0] = ssc->ssc_composition_id >> 8;
|
buf4[0] = ssc->ssc_composition_id >> 8;
|
||||||
buf4[1] = ssc->ssc_composition_id;
|
buf4[1] = ssc->ssc_composition_id;
|
||||||
|
|
|
@ -91,6 +91,7 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
|
||||||
|
|
||||||
case SCT_H264:
|
case SCT_H264:
|
||||||
case SCT_MPEG2VIDEO:
|
case SCT_MPEG2VIDEO:
|
||||||
|
case SCT_VORBIS:
|
||||||
|
|
||||||
if(pkt->pkt_header != NULL) {
|
if(pkt->pkt_header != NULL) {
|
||||||
ssc->ssc_gh = pkt->pkt_header;
|
ssc->ssc_gh = pkt->pkt_header;
|
||||||
|
@ -124,7 +125,8 @@ header_complete(streaming_start_component_t *ssc, int not_so_picky)
|
||||||
(ssc->ssc_type == SCT_H264 ||
|
(ssc->ssc_type == SCT_H264 ||
|
||||||
ssc->ssc_type == SCT_MPEG2VIDEO ||
|
ssc->ssc_type == SCT_MPEG2VIDEO ||
|
||||||
ssc->ssc_type == SCT_MP4A ||
|
ssc->ssc_type == SCT_MP4A ||
|
||||||
ssc->ssc_type == SCT_AAC))
|
ssc->ssc_type == SCT_AAC ||
|
||||||
|
ssc->ssc_type == SCT_VORBIS))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ typedef struct transcoder {
|
||||||
|
|
||||||
#define WORKING_ENCODER(x) (x == CODEC_ID_H264 || x == CODEC_ID_MPEG2VIDEO || \
|
#define WORKING_ENCODER(x) (x == CODEC_ID_H264 || x == CODEC_ID_MPEG2VIDEO || \
|
||||||
x == CODEC_ID_VP8 || x == CODEC_ID_AAC || \
|
x == CODEC_ID_VP8 || x == CODEC_ID_AAC || \
|
||||||
x == CODEC_ID_MP2)
|
x == CODEC_ID_MP2 || x == CODEC_ID_VORBIS)
|
||||||
|
|
||||||
|
|
||||||
uint32_t transcoding_enabled = 0;
|
uint32_t transcoding_enabled = 0;
|
||||||
|
@ -375,6 +375,13 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
|
||||||
octx->flags |= CODEC_FLAG_QSCALE;
|
octx->flags |= CODEC_FLAG_QSCALE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCT_VORBIS:
|
||||||
|
octx->flags |= CODEC_FLAG_QSCALE;
|
||||||
|
octx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
octx->channels = 2; // Only stereo suported by libavcodec
|
||||||
|
octx->global_quality = 4*FF_QP2LAMBDA;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -946,6 +946,7 @@ static struct strtab streamtypetab[] = {
|
||||||
{ "EAC3", SCT_EAC3 },
|
{ "EAC3", SCT_EAC3 },
|
||||||
{ "AAC", SCT_MP4A },
|
{ "AAC", SCT_MP4A },
|
||||||
{ "VP8", SCT_VP8 },
|
{ "VP8", SCT_VP8 },
|
||||||
|
{ "VORBIS", SCT_VORBIS },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -200,14 +200,16 @@ typedef enum {
|
||||||
SCT_EAC3,
|
SCT_EAC3,
|
||||||
SCT_MP4A,
|
SCT_MP4A,
|
||||||
SCT_VP8,
|
SCT_VP8,
|
||||||
|
SCT_VORBIS,
|
||||||
} streaming_component_type_t;
|
} streaming_component_type_t;
|
||||||
|
|
||||||
#define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264 || \
|
#define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264 || \
|
||||||
(t) == SCT_VP8)
|
(t) == SCT_VP8)
|
||||||
|
|
||||||
#define SCT_ISAUDIO(t) ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || \
|
#define SCT_ISAUDIO(t) ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || \
|
||||||
(t) == SCT_AAC || (t) == SCT_MP4A || \
|
(t) == SCT_AAC || (t) == SCT_MP4A || \
|
||||||
(t) == SCT_EAC3)
|
(t) == SCT_EAC3 || (t) == SCT_VORBIS)
|
||||||
|
|
||||||
#define SCT_ISSUBTITLE(t) ((t) == SCT_TEXTSUB || (t) == SCT_DVBSUB)
|
#define SCT_ISSUBTITLE(t) ((t) == SCT_TEXTSUB || (t) == SCT_DVBSUB)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue