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)
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);
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);
&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);
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)))
{
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);
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);
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 {
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);
delta = 0;
}
- if(mk->addcue && vkeyframe) {
+ if(mk->addcue && keyframe) {
mk->addcue = 0;
addcue(mk, pts, t->tracknum);
}
}
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) {
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';
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;
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);
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);
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;
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) {
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;
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;
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
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;
}
}
}
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);
}
}
}
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);
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:
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)
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 */
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,
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;
}
}
- 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) {
" 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,
/* 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;