H264: move avc parsing from globalheaders to mkv mux
This commit is contained in:
parent
b70fa32a71
commit
bf1c902fbf
4 changed files with 46 additions and 63 deletions
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue