From: Jaroslav Kysela Date: Mon, 3 Apr 2017 16:33:03 +0000 (+0200) Subject: packet: separate audio/video members using union X-Git-Tag: v4.2.1~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=340fd4de96fc06f8dd79b41ac41df77e39e9460e;p=thirdparty%2Ftvheadend.git packet: separate audio/video members using union --- diff --git a/src/htsp_server.c b/src/htsp_server.c index 138533634..ea786f02f 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -3829,6 +3829,7 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_connection_t *htsp = hs->hs_htsp; int64_t ts; int qlen = hs->hs_q.hmq_payload; + int video = SCT_ISVIDEO(pkt->pkt_type); size_t payloadlen; if (pkt->pkt_err) @@ -3842,11 +3843,12 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) return; } - if((qlen > hs->hs_queue_depth && pkt->pkt_frametype == PKT_B_FRAME) || - (qlen > hs->hs_queue_depth * 2 && pkt->pkt_frametype == PKT_P_FRAME) || - (qlen > hs->hs_queue_depth * 3)) { + if(video && + ((qlen > hs->hs_queue_depth && pkt->v.pkt_frametype == PKT_B_FRAME) || + (qlen > hs->hs_queue_depth * 2 && pkt->v.pkt_frametype == PKT_P_FRAME) || + (qlen > hs->hs_queue_depth * 3))) { - hs->hs_dropstats[pkt->pkt_frametype]++; + hs->hs_dropstats[pkt->v.pkt_frametype]++; /* Queue size protection */ pkt_ref_dec(pkt); @@ -3857,7 +3859,8 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsmsg_add_str(m, "method", "muxpkt"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); - htsmsg_add_u32(m, "frametype", frametypearray[pkt->pkt_frametype]); + if (video) + htsmsg_add_u32(m, "frametype", frametypearray[pkt->v.pkt_frametype]); htsmsg_add_u32(m, "stream", pkt->pkt_componentindex); htsmsg_add_u32(m, "com", pkt->pkt_commercial); diff --git a/src/muxer/muxer_libav.c b/src/muxer/muxer_libav.c index 3219fddad..e62fbcdff 100644 --- a/src/muxer/muxer_libav.c +++ b/src/muxer/muxer_libav.c @@ -474,7 +474,7 @@ lav_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) &packet.size, pktbuf_ptr(pkt->pkt_payload), pktbuf_len(pkt->pkt_payload), - pkt->pkt_frametype < PKT_P_FRAME) < 0) { + SCT_ISVIDEO(pkt->pkt_type) ? pkt->v.pkt_frametype < PKT_P_FRAME : 1) < 0) { tvhwarn(LS_LIBAV, "Failed to filter bitstream"); if (packet.data != pktbuf_ptr(pkt->pkt_payload)) av_free(packet.data); @@ -503,7 +503,7 @@ lav_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) packet.dts = av_rescale_q(pkt->pkt_dts , mpeg_tc, st->time_base); packet.duration = av_rescale_q(pkt->pkt_duration, mpeg_tc, st->time_base); - if(pkt->pkt_frametype < PKT_P_FRAME) + if(!SCT_ISVIDEO(pkt->pkt_type) || pkt->v.pkt_frametype < PKT_P_FRAME) packet.flags |= AV_PKT_FLAG_KEY; if((rc = av_interleaved_write_frame(oc, &packet))) diff --git a/src/muxer/muxer_mkv.c b/src/muxer/muxer_mkv.c index b44e1430d..40105e978 100644 --- a/src/muxer/muxer_mkv.c +++ b/src/muxer/muxer_mkv.c @@ -958,10 +958,13 @@ mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) { int64_t pts = pkt->pkt_pts, delta, nxt; unsigned char c_delta_flags[3]; + int video = SCT_ISVIDEO(pkt->pkt_type); + int keyframe = 0, skippable = 0; - int keyframe = pkt->pkt_frametype < PKT_P_FRAME; - int skippable = pkt->pkt_frametype == PKT_B_FRAME; - int vkeyframe = SCT_ISVIDEO(t->type) && keyframe; + if (video) { + keyframe = pkt->v.pkt_frametype < PKT_P_FRAME; + skippable = pkt->v.pkt_frametype == PKT_B_FRAME; + } uint8_t *data = pktbuf_ptr(pkt->pkt_payload); size_t len = pktbuf_len(pkt->pkt_payload); @@ -974,7 +977,7 @@ mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) pts = t->nextpts; if(pts != PTS_UNSET) { - t->nextpts = pts + (pkt->pkt_duration >> pkt->pkt_field); + t->nextpts = pts + (pkt->pkt_duration >> (video ? pkt->v.pkt_field : 0)); nxt = ts_rescale(t->nextpts, 1000000000 / MATROSKA_TIMESCALE); pts = ts_rescale(pts, 1000000000 / MATROSKA_TIMESCALE); @@ -983,7 +986,7 @@ mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) mk->totduration = nxt; delta = pts - mk->cluster_tc; - if((vkeyframe || !mk->has_video) && (delta > 30000ll || delta < -30000ll)) + if((keyframe || !mk->has_video) && (delta > 30000ll || delta < -30000ll)) mk_close_cluster(mk); } else { @@ -992,7 +995,7 @@ mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) if(mk->cluster) { - if(vkeyframe && + if(keyframe && (mk->cluster->hq_size > mk->cluster_maxsize || mk->cluster_last_close + sec2mono(1) < mclk())) mk_close_cluster(mk); @@ -1018,7 +1021,7 @@ mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) delta = 0; } - if(mk->addcue && vkeyframe) { + if(mk->addcue && keyframe) { mk->addcue = 0; addcue(mk, pts, t->tracknum); } @@ -1101,26 +1104,29 @@ mk_mux_write_pkt(mk_muxer_t *mk, th_pkt_t *pkt) } mark = 0; - if(pkt->pkt_channels != t->channels && - pkt->pkt_channels) { - mark = 1; - t->channels = pkt->pkt_channels; - } - if(pkt->pkt_aspect_num != t->aspect_num && - pkt->pkt_aspect_num) { - mark = 1; - t->aspect_num = pkt->pkt_aspect_num; - } - if(pkt->pkt_aspect_den != t->aspect_den && - pkt->pkt_aspect_den) { - mark = 1; - t->aspect_den = pkt->pkt_aspect_den; - } - if(pkt->pkt_sri != t->sri && - pkt->pkt_sri) { - mark = 1; - t->sri = pkt->pkt_sri; - t->ext_sri = pkt->pkt_ext_sri; + if(SCT_ISAUDIO(pkt->pkt_type)) { + if(pkt->a.pkt_channels != t->channels && + pkt->a.pkt_channels) { + mark = 1; + t->channels = pkt->a.pkt_channels; + } + if(pkt->a.pkt_sri != t->sri && + pkt->a.pkt_sri) { + mark = 1; + t->sri = pkt->a.pkt_sri; + t->ext_sri = pkt->a.pkt_ext_sri; + } + } else if (SCT_ISVIDEO(pkt->pkt_type)) { + if(pkt->v.pkt_aspect_num != t->aspect_num && + pkt->v.pkt_aspect_num) { + mark = 1; + t->aspect_num = pkt->v.pkt_aspect_num; + } + if(pkt->v.pkt_aspect_den != t->aspect_den && + pkt->v.pkt_aspect_den) { + mark = 1; + t->aspect_den = pkt->v.pkt_aspect_den; + } } if(pkt->pkt_commercial != t->commercial && pkt->pkt_commercial != COMMERCIAL_UNKNOWN) { diff --git a/src/packet.c b/src/packet.c index 919989d1e..9c548eaea 100644 --- a/src/packet.c +++ b/src/packet.c @@ -156,8 +156,8 @@ pkt_trace_(const char *file, int line, int subsys, th_pkt_t *pkt, va_list args; va_start(args, fmt); - if (pkt->pkt_frametype) { - _type[0] = pkt_frametype_to_char(pkt->pkt_frametype); + if (SCT_ISVIDEO(pkt->pkt_type) && pkt->v.pkt_frametype) { + _type[0] = pkt_frametype_to_char(pkt->v.pkt_frametype); _type[1] = '\0'; } else { _type[0] = '\0'; diff --git a/src/packet.h b/src/packet.h index 14b07af90..feb33c21e 100644 --- a/src/packet.h +++ b/src/packet.h @@ -59,15 +59,20 @@ typedef struct th_pkt { uint8_t pkt_componentindex; uint8_t pkt_commercial; - uint8_t pkt_frametype; - uint8_t pkt_field; // Set if packet is only a half frame (a field) - - uint8_t pkt_channels; - uint8_t pkt_sri; - uint8_t pkt_ext_sri; - - uint16_t pkt_aspect_num; - uint16_t pkt_aspect_den; + union { + struct { + uint8_t pkt_frametype; + uint8_t pkt_field; // Set if packet is only a half frame (a field) + + uint16_t pkt_aspect_num; + uint16_t pkt_aspect_den; + } v; + struct { + uint8_t pkt_channels; + uint8_t pkt_sri; + uint8_t pkt_ext_sri; + } a; + }; pktbuf_t *pkt_meta; pktbuf_t *pkt_payload; diff --git a/src/parsers/parser_latm.c b/src/parsers/parser_latm.c index add36a7d2..52727d3fc 100644 --- a/src/parsers/parser_latm.c +++ b/src/parsers/parser_latm.c @@ -264,9 +264,9 @@ parse_latm_audio_mux_element(service_t *t, elementary_stream_t *st, pkt->pkt_commercial = t->s_tt_commercial_advice; pkt->pkt_duration = st->es_frame_duration; - pkt->pkt_sri = latm->sri; - pkt->pkt_ext_sri = latm->ext_sri; - pkt->pkt_channels = latm->channel_config == 7 ? 8 : latm->channel_config; + pkt->a.pkt_sri = latm->sri; + pkt->a.pkt_ext_sri = latm->ext_sri; + pkt->a.pkt_channels = latm->channel_config == 7 ? 8 : latm->channel_config; /* 7 bytes of ADTS header */ init_wbits(&out, pktbuf_ptr(pkt->pkt_payload), 7 * 8); diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 79555129d..e567391e1 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -536,8 +536,8 @@ makeapkt(service_t *t, elementary_stream_t *st, const void *buf, pkt->pkt_commercial = t->s_tt_commercial_advice; pkt->pkt_duration = duration; - pkt->pkt_channels = channels; - pkt->pkt_sri = sri; + pkt->a.pkt_channels = channels; + pkt->a.pkt_sri = sri; pkt->pkt_err = errors; parser_deliver(t, st, pkt); @@ -1197,7 +1197,7 @@ parse_mpeg2video(service_t *t, elementary_stream_t *st, size_t len, pkt_ref_dec(st->es_curpkt); pkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts); - pkt->pkt_frametype = frametype; + pkt->v.pkt_frametype = frametype; pkt->pkt_duration = st->es_frame_duration; pkt->pkt_commercial = t->s_tt_commercial_advice; @@ -1348,22 +1348,22 @@ parse_h264_backlog(service_t *t, elementary_stream_t *st, th_pkt_t *pkt) nal_start = nal_end; } - pkt->pkt_frametype = pkttype; - pkt->pkt_field = isfield; + pkt->v.pkt_frametype = pkttype; + pkt->v.pkt_field = isfield; pkt->pkt_duration = st->es_frame_duration; } static void parse_h264_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt) { - if (pkt->pkt_frametype > 0) { + if (pkt->v.pkt_frametype > 0) { if (TAILQ_EMPTY(&st->es_backlog)) { - if (pkt->pkt_frametype > 0) { + if (pkt->v.pkt_frametype > 0) { deliver: parser_deliver(t, st, pkt); return; } - } else if (pkt->pkt_frametype > 0 && + } else if (pkt->v.pkt_frametype > 0 && (st->es_curdts != PTS_UNSET && (st->es_curdts & PTS_BACKLOG) == 0) && (st->es_curpts != PTS_UNSET && (st->es_curpts & PTS_BACKLOG) == 0) && st->es_frame_duration > 1) { @@ -1488,8 +1488,8 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len, st->es_frame_duration = 1; pkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts); - pkt->pkt_frametype = pkttype; - pkt->pkt_field = isfield; + pkt->v.pkt_frametype = pkttype; + pkt->v.pkt_field = isfield; pkt->pkt_duration = st->es_frame_duration; pkt->pkt_commercial = t->s_tt_commercial_advice; st->es_curpkt = pkt; @@ -1613,8 +1613,8 @@ parse_hevc(service_t *t, elementary_stream_t *st, size_t len, return PARSER_APPEND; st->es_curpkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts); - st->es_curpkt->pkt_frametype = pkttype; - st->es_curpkt->pkt_field = 0; + st->es_curpkt->v.pkt_frametype = pkttype; + st->es_curpkt->v.pkt_field = 0; st->es_curpkt->pkt_duration = st->es_frame_duration; st->es_curpkt->pkt_commercial = t->s_tt_commercial_advice; break; @@ -1830,12 +1830,16 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt) t->s_current_pts = (pkt->pkt_pts + (int64_t)t->s_pts_shift * 900) % PTS_MASK; } + assert(pkt->pkt_type == st->es_type); + pkt->pkt_componentindex = st->es_index; pkt_trace(LS_PARSER, pkt, "deliver"); - pkt->pkt_aspect_num = st->es_aspect_num; - pkt->pkt_aspect_den = st->es_aspect_den; + if (SCT_ISVIDEO(pkt->pkt_type)) { + pkt->v.pkt_aspect_num = st->es_aspect_num; + pkt->v.pkt_aspect_den = st->es_aspect_den; + } /** * Input is ok diff --git a/src/plumbing/globalheaders.c b/src/plumbing/globalheaders.c index 203387f44..28cf0ff7f 100644 --- a/src/plumbing/globalheaders.c +++ b/src/plumbing/globalheaders.c @@ -85,15 +85,15 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt) ssc->ssc_frameduration = pkt->pkt_duration; if(SCT_ISAUDIO(ssc->ssc_type) && !ssc->ssc_channels && !ssc->ssc_sri) { - ssc->ssc_channels = pkt->pkt_channels; - ssc->ssc_sri = pkt->pkt_sri; - ssc->ssc_ext_sri = pkt->pkt_ext_sri; + ssc->ssc_channels = pkt->a.pkt_channels; + ssc->ssc_sri = pkt->a.pkt_sri; + ssc->ssc_ext_sri = pkt->a.pkt_ext_sri; } if(SCT_ISVIDEO(ssc->ssc_type)) { - if(pkt->pkt_aspect_num && pkt->pkt_aspect_den) { - ssc->ssc_aspect_num = pkt->pkt_aspect_num; - ssc->ssc_aspect_den = pkt->pkt_aspect_den; + if(pkt->v.pkt_aspect_num && pkt->v.pkt_aspect_den) { + ssc->ssc_aspect_num = pkt->v.pkt_aspect_num; + ssc->ssc_aspect_den = pkt->v.pkt_aspect_den; } } @@ -107,16 +107,16 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt) } if (ssc->ssc_type == SCT_MP4A || ssc->ssc_type == SCT_AAC) { - ssc->ssc_gh = pktbuf_alloc(NULL, pkt->pkt_ext_sri ? 5 : 2); + ssc->ssc_gh = pktbuf_alloc(NULL, pkt->a.pkt_ext_sri ? 5 : 2); uint8_t *d = pktbuf_ptr(ssc->ssc_gh); const int profile = 2; /* AAC LC */ - d[0] = (profile << 3) | ((pkt->pkt_sri & 0xe) >> 1); - d[1] = ((pkt->pkt_sri & 0x1) << 7) | (pkt->pkt_channels << 3); - if (pkt->pkt_ext_sri) { /* SBR extension */ + d[0] = (profile << 3) | ((pkt->a.pkt_sri & 0xe) >> 1); + d[1] = ((pkt->a.pkt_sri & 0x1) << 7) | (pkt->a.pkt_channels << 3); + if (pkt->a.pkt_ext_sri) { /* SBR extension */ d[2] = 0x56; d[3] = 0xe5; - d[4] = 0x80 | ((pkt->pkt_ext_sri - 1) << 3); + d[4] = 0x80 | ((pkt->a.pkt_ext_sri - 1) << 3); } } } diff --git a/src/plumbing/transcoding.c b/src/plumbing/transcoding.c index 7383447b2..4fc05feab 100644 --- a/src/plumbing/transcoding.c +++ b/src/plumbing/transcoding.c @@ -854,12 +854,12 @@ scleanup: memcpy(pktbuf_ptr(n->pkt_payload) + extra_size, packet.data, packet.size); n->pkt_componentindex = ts->ts_index; - n->pkt_channels = octx->channels; - n->pkt_sri = rate_to_sri(octx->sample_rate); + n->a.pkt_channels = octx->channels; + n->a.pkt_sri = rate_to_sri(octx->sample_rate); n->pkt_duration = packet.duration; if (extra_size && ts->ts_type == SCT_AAC) - create_adts_header(n->pkt_payload, n->pkt_sri, octx->channels); + create_adts_header(n->pkt_payload, n->a.pkt_sri, octx->channels); if (octx->extradata_size) n->pkt_meta = pktbuf_alloc(octx->extradata, octx->extradata_size); @@ -979,15 +979,15 @@ send_video_packet(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt, switch (octx->coded_frame->pict_type) { case AV_PICTURE_TYPE_I: - n->pkt_frametype = PKT_I_FRAME; + n->v.pkt_frametype = PKT_I_FRAME; break; case AV_PICTURE_TYPE_P: - n->pkt_frametype = PKT_P_FRAME; + n->v.pkt_frametype = PKT_P_FRAME; break; case AV_PICTURE_TYPE_B: - n->pkt_frametype = PKT_B_FRAME; + n->v.pkt_frametype = PKT_B_FRAME; break; default: @@ -997,9 +997,9 @@ send_video_packet(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt, n->pkt_duration = pkt->pkt_duration; n->pkt_commercial = pkt->pkt_commercial; n->pkt_componentindex = pkt->pkt_componentindex; - n->pkt_field = pkt->pkt_field; - n->pkt_aspect_num = pkt->pkt_aspect_num; - n->pkt_aspect_den = pkt->pkt_aspect_den; + n->v.pkt_field = pkt->v.pkt_field; + n->v.pkt_aspect_num = pkt->v.pkt_aspect_num; + n->v.pkt_aspect_den = pkt->v.pkt_aspect_den; if(octx->coded_frame && octx->coded_frame->pts != AV_NOPTS_VALUE) { if(n->pkt_dts != PTS_UNSET) diff --git a/src/plumbing/tsfix.c b/src/plumbing/tsfix.c index 1b69f897b..a6b15cb68 100644 --- a/src/plumbing/tsfix.c +++ b/src/plumbing/tsfix.c @@ -376,7 +376,7 @@ recover_pts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) case SCT_MPEG2VIDEO: - switch(pkt->pkt_frametype) { + switch(pkt->v.pkt_frametype) { case PKT_B_FRAME: if (pkt->pkt_pts == PTS_UNSET) { /* B-frames have same PTS as DTS, pass them on */ @@ -397,7 +397,7 @@ recover_pts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) if (pkt->pkt_componentindex != tfs->tfs_index) continue; total++; - if (srch->pr_pkt->pkt_frametype <= PKT_P_FRAME && + if (srch->pr_pkt->v.pkt_frametype <= PKT_P_FRAME && pts_is_greater_or_equal(pkt->pkt_dts, srch->pr_pkt->pkt_dts) > 0 && pts_diff(pkt->pkt_dts, srch->pr_pkt->pkt_dts) < 10 * 90000) { tvhtrace(LS_TSFIX, "%-12s PTS *-frame set to %"PRId64" (old %"PRId64"), DTS %"PRId64, @@ -469,7 +469,7 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) if(pkt->pkt_dts != PTS_UNSET && tf->tf_tsref == PTS_UNSET && ((!tf->tf_hasvideo && tfs->tfs_audio) || - (tfs->tfs_video && pkt->pkt_frametype == PKT_I_FRAME))) { + (tfs->tfs_video && pkt->v.pkt_frametype == PKT_I_FRAME))) { if (pkt->pkt_err) { tsfix_packet_drop(tfs, pkt, "ref1"); return; @@ -534,7 +534,7 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) } } - int pdur = pkt->pkt_duration >> pkt->pkt_field; + int pdur = pkt->pkt_duration >> pkt->v.pkt_field; if(pkt->pkt_dts == PTS_UNSET) { if(tfs->tfs_last_dts_in == PTS_UNSET) { diff --git a/src/timeshift.c b/src/timeshift.c index 4c91fd211..2358a68b1 100644 --- a/src/timeshift.c +++ b/src/timeshift.c @@ -54,7 +54,7 @@ timeshift_packet_log0 " dts %10"PRId64" dur %10d len %6zu time %14"PRId64, ts->id, source, pkt->pkt_componentindex, - pkt_frametype_to_char(pkt->pkt_frametype), + SCT_ISVIDEO(pkt->pkt_type) ? pkt_frametype_to_char(pkt->v.pkt_frametype) : '-', ts_rescale(pkt->pkt_pts, 1000000), ts_rescale(pkt->pkt_dts, 1000000), pkt->pkt_duration, diff --git a/src/timeshift/timeshift_writer.c b/src/timeshift/timeshift_writer.c index 8a2a11b7f..da7ee3522 100644 --- a/src/timeshift/timeshift_writer.c +++ b/src/timeshift/timeshift_writer.c @@ -285,7 +285,7 @@ static inline ssize_t _process_msg0 /* Index video iframes */ if (pkt->pkt_componentindex == ts->vididx && - pkt->pkt_frametype == PKT_I_FRAME) { + pkt->v.pkt_frametype == PKT_I_FRAME) { timeshift_index_iframe_t *ti = calloc(1, sizeof(timeshift_index_iframe_t)); memoryinfo_alloc(×hift_memoryinfo, sizeof(*ti)); ti->pos = tsf->size;