diff --git a/src/muxer/tvh/mkmux.c b/src/muxer/tvh/mkmux.c index 0e21ed6e..9b8e0fb9 100644 --- a/src/muxer/tvh/mkmux.c +++ b/src/muxer/tvh/mkmux.c @@ -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); diff --git a/src/parsers/parser_avc.c b/src/parsers/parser_avc.c index 46831484..b04b0563 100644 --- a/src/parsers/parser_avc.c +++ b/src/parsers/parser_avc.c @@ -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) { diff --git a/src/parsers/parser_avc.h b/src/parsers/parser_avc.h index 631d0d4c..75d74b67 100644 --- a/src/parsers/parser_avc.h +++ b/src/parsers/parser_avc.h @@ -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 diff --git a/src/plumbing/globalheaders.c b/src/plumbing/globalheaders.c index 6994b650..a79383ac 100644 --- a/src/plumbing/globalheaders.c +++ b/src/plumbing/globalheaders.c @@ -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; } }