H264: move avc parsing from globalheaders to mkv mux

This commit is contained in:
Jaroslav Kysela 2014-11-19 17:29:16 +01:00
parent b70fa32a71
commit bf1c902fbf
4 changed files with 46 additions and 63 deletions

View file

@ -32,6 +32,7 @@
#include "dvr/dvr.h"
#include "mkmux.h"
#include "ebml.h"
#include "parsers/parser_avc.h"
extern int dvr_iov_max;
@ -47,6 +48,7 @@ TAILQ_HEAD(mk_chapter_queue, mk_chapter);
typedef struct mk_track {
int index;
int enabled;
int avc;
int type;
int tracknum;
int disabled;
@ -236,26 +238,28 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
int tracknum = 0;
uint8_t buf4[4];
uint32_t bit_depth = 0;
mk_track_t *tr;
mkm->tracks = calloc(1, sizeof(mk_track_t) * ss->ss_num_components);
mkm->ntracks = ss->ss_num_components;
for(i = 0; i < ss->ss_num_components; i++) {
ssc = &ss->ss_components[i];
tr = &mkm->tracks[i];
mkm->tracks[i].disabled = ssc->ssc_disabled;
tr->disabled = ssc->ssc_disabled;
if(ssc->ssc_disabled)
continue;
mkm->tracks[i].index = ssc->ssc_index;
mkm->tracks[i].type = ssc->ssc_type;
mkm->tracks[i].channels = ssc->ssc_channels;
mkm->tracks[i].aspect_num = ssc->ssc_aspect_num;
mkm->tracks[i].aspect_den = ssc->ssc_aspect_den;
mkm->tracks[i].commercial = COMMERCIAL_UNKNOWN;
mkm->tracks[i].sri = ssc->ssc_sri;
mkm->tracks[i].nextpts = PTS_UNSET;
tr->index = ssc->ssc_index;
tr->type = ssc->ssc_type;
tr->channels = ssc->ssc_channels;
tr->aspect_num = ssc->ssc_aspect_num;
tr->aspect_den = ssc->ssc_aspect_den;
tr->commercial = COMMERCIAL_UNKNOWN;
tr->sri = ssc->ssc_sri;
tr->nextpts = PTS_UNSET;
if (mkm->webm && ssc->ssc_type != SCT_VP8 && ssc->ssc_type != SCT_VORBIS)
tvhwarn("mkv", "WEBM format supports only VP8+VORBIS streams (detected %s)",
@ -270,6 +274,7 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
case SCT_H264:
tracktype = 1;
codec_id = "V_MPEG4/ISO/AVC";
tr->avc = 1;
break;
case SCT_VP8:
@ -327,15 +332,14 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
continue;
}
mkm->tracks[i].enabled = 1;
tracknum++;
mkm->tracks[i].tracknum = tracknum;
tr->enabled = 1;
tr->tracknum = ++tracknum;
mkm->has_video |= (tracktype == 1);
t = htsbuf_queue_alloc(0);
ebml_append_uint(t, 0xd7, mkm->tracks[i].tracknum);
ebml_append_uint(t, 0x73c5, mkm->tracks[i].tracknum);
ebml_append_uint(t, 0xd7, tr->tracknum);
ebml_append_uint(t, 0x73c5, tr->tracknum);
ebml_append_uint(t, 0x83, tracktype);
ebml_append_uint(t, 0x9c, 0); // Lacing
ebml_append_string(t, 0x86, codec_id);
@ -348,10 +352,19 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
case SCT_MPEG2VIDEO:
case SCT_MP4A:
case SCT_AAC:
if(ssc->ssc_gh)
ebml_append_bin(t, 0x63a2,
pktbuf_ptr(ssc->ssc_gh),
pktbuf_len(ssc->ssc_gh));
if(ssc->ssc_gh) {
sbuf_t hdr;
sbuf_init(&hdr);
if (tr->avc) {
isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh),
pktbuf_len(ssc->ssc_gh));
} else {
sbuf_append(&hdr, pktbuf_ptr(ssc->ssc_gh),
pktbuf_len(ssc->ssc_gh));
}
ebml_append_bin(t, 0x63a2, hdr.sb_data, hdr.sb_ptr);
sbuf_free(&hdr);
}
break;
case SCT_VORBIS:
@ -1138,12 +1151,12 @@ mk_mux_write_pkt(mk_mux_t *mkm, th_pkt_t *pkt)
{
int i, mark;
mk_track_t *t = NULL;
for(i = 0; i < mkm->ntracks;i++) {
if(mkm->tracks[i].index == pkt->pkt_componentindex &&
mkm->tracks[i].enabled) {
t = &mkm->tracks[i];
th_pkt_t *opkt;
for (i = 0; i < mkm->ntracks; i++) {
t = &mkm->tracks[i];
if (t->index == pkt->pkt_componentindex && t->enabled)
break;
}
}
if(t == NULL || t->disabled) {
@ -1181,6 +1194,11 @@ mk_mux_write_pkt(mk_mux_t *mkm, th_pkt_t *pkt)
if(mark)
mk_mux_insert_chapter(mkm);
if(t->avc) {
pkt = avc_convert_pkt(opkt = pkt);
pkt_ref_dec(opkt);
}
mk_write_frame_i(mkm, t, pkt);
pkt_ref_dec(pkt);

View file

@ -120,7 +120,7 @@ RB24(const uint8_t *d)
#define FFMIN(a, b) ((a) > (b) ? (b) : (a))
static int
int
isom_write_avcc(sbuf_t *sb, const uint8_t *data, int len)
{
if (len > 6) {

View file

@ -25,6 +25,8 @@
#include "tvheadend.h"
#include "packet.h"
int isom_write_avcc(sbuf_t *sb, const uint8_t *src, int len);
th_pkt_t *avc_convert_pkt(th_pkt_t *src);
#endif

View file

@ -20,7 +20,6 @@
#include "tvheadend.h"
#include "streaming.h"
#include "globalheaders.h"
#include "parsers/parser_avc.h"
typedef struct globalheaders {
streaming_target_t gh_input;
@ -152,32 +151,6 @@ headers_complete(globalheaders_t *gh, int64_t qd)
}
/**
*
*/
static th_pkt_t *
convertpkt(streaming_start_component_t *ssc, th_pkt_t *pkt, int hold)
{
th_pkt_t *r;
switch(ssc->ssc_type) {
case SCT_H264:
r = avc_convert_pkt(pkt);
if (!hold)
pkt_ref_dec(pkt);
break;
default:
r = pkt;
if (hold)
pkt_ref_inc(r);
break;
}
return r;
}
/**
*
*/
@ -214,7 +187,7 @@ gh_hold(globalheaders_t *gh, streaming_message_t *sm)
break;
}
pkt = convertpkt(ssc, pkt, 1);
pkt_ref_inc(pkt);
apply_header(ssc, pkt);
@ -273,9 +246,6 @@ gh_hold(globalheaders_t *gh, streaming_message_t *sm)
static void
gh_pass(globalheaders_t *gh, streaming_message_t *sm)
{
th_pkt_t *pkt;
streaming_start_component_t *ssc;
switch(sm->sm_type) {
case SMT_START:
/* stop */
@ -295,20 +265,13 @@ gh_pass(globalheaders_t *gh, streaming_message_t *sm)
case SMT_SERVICE_STATUS:
case SMT_SIGNAL_STATUS:
case SMT_NOSTART:
case SMT_PACKET:
case SMT_MPEGTS:
case SMT_SKIP:
case SMT_SPEED:
case SMT_TIMESHIFT_STATUS:
streaming_target_deliver2(gh->gh_output, sm);
break;
case SMT_PACKET:
pkt = sm->sm_data;
ssc = streaming_start_component_find_by_index(gh->gh_ss,
pkt->pkt_componentindex);
sm->sm_data = convertpkt(ssc, pkt, 0);
streaming_target_deliver2(gh->gh_output, sm);
break;
}
}