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:
John Törblom 2013-07-17 16:26:48 +02:00
parent e4b9f5960d
commit 08bd137d6f
8 changed files with 102 additions and 4 deletions

View file

@ -77,6 +77,9 @@ streaming_component_type2codec_id(streaming_component_type_t type)
case SCT_MPEG2AUDIO:
codec_id = CODEC_ID_MP2;
break;
case SCT_VORBIS:
codec_id = CODEC_ID_VORBIS;
break;
case SCT_DVBSUB:
codec_id = CODEC_ID_DVB_SUBTITLE;
break;
@ -125,6 +128,9 @@ codec_id2streaming_component_type(enum CodecID id)
case CODEC_ID_MP2:
type = SCT_MPEG2AUDIO;
break;
case CODEC_ID_VORBIS:
type = SCT_VORBIS;
break;
case CODEC_ID_DVB_SUBTITLE:
type = SCT_DVBSUB;
break;

View file

@ -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
ebml_append_bin(htsbuf_queue_t *q, unsigned id, const void *data, size_t len)
{

View file

@ -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_xiph_size(htsbuf_queue_t *q, int size);
void ebml_append_bin(htsbuf_queue_t *q, unsigned id,
const void *data, size_t len);

View file

@ -25,6 +25,7 @@
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
#include "tvheadend.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";
break;
case SCT_VORBIS:
tracktype = 2;
codec_id = "A_VORBIS";
break;
case SCT_DVBSUB:
tracktype = 0x11;
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));
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:
buf4[0] = ssc->ssc_composition_id >> 8;
buf4[1] = ssc->ssc_composition_id;

View file

@ -91,6 +91,7 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
case SCT_H264:
case SCT_MPEG2VIDEO:
case SCT_VORBIS:
if(pkt->pkt_header != NULL) {
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_MPEG2VIDEO ||
ssc->ssc_type == SCT_MP4A ||
ssc->ssc_type == SCT_AAC))
ssc->ssc_type == SCT_AAC ||
ssc->ssc_type == SCT_VORBIS))
return 0;
return 1;
}

View file

@ -108,7 +108,7 @@ typedef struct transcoder {
#define WORKING_ENCODER(x) (x == CODEC_ID_H264 || x == CODEC_ID_MPEG2VIDEO || \
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;
@ -375,6 +375,13 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
octx->flags |= CODEC_FLAG_QSCALE;
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:
break;
}

View file

@ -946,6 +946,7 @@ static struct strtab streamtypetab[] = {
{ "EAC3", SCT_EAC3 },
{ "AAC", SCT_MP4A },
{ "VP8", SCT_VP8 },
{ "VORBIS", SCT_VORBIS },
};

View file

@ -200,14 +200,16 @@ typedef enum {
SCT_EAC3,
SCT_MP4A,
SCT_VP8,
SCT_VORBIS,
} streaming_component_type_t;
#define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264 || \
(t) == SCT_VP8)
#define SCT_ISAUDIO(t) ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || \
(t) == SCT_AAC || (t) == SCT_MP4A || \
(t) == SCT_EAC3)
(t) == SCT_AAC || (t) == SCT_MP4A || \
(t) == SCT_EAC3 || (t) == SCT_VORBIS)
#define SCT_ISSUBTITLE(t) ((t) == SCT_TEXTSUB || (t) == SCT_DVBSUB)
/**