if(ssc->ssc_type == SCT_MPEG2VIDEO || ssc->ssc_type == SCT_H264) {
if(ssc->ssc_width)
- htsmsg_add_u32(c, "width", ssc->ssc_width);
+ htsmsg_add_u32(c, "width", ssc->ssc_width);
if(ssc->ssc_height)
- htsmsg_add_u32(c, "height", ssc->ssc_height);
+ htsmsg_add_u32(c, "height", ssc->ssc_height);
+ if(ssc->ssc_frameduration)
+ htsmsg_add_u32(c, "duration", hs->hs_90khz ? ssc->ssc_frameduration :
+ ts_rescale(ssc->ssc_frameduration, 1000000));
if (ssc->ssc_aspect_num)
htsmsg_add_u32(c, "aspect_num", ssc->ssc_aspect_num);
if (ssc->ssc_aspect_den)
int
h264_decode_slice_header(elementary_stream_t *st, bitstream_t *bs, int *pkttype,
- int *duration, int *isfield)
+ int *isfield)
{
h264_private_t *p;
int slice_type, pps_id, sps_id;
*isfield = field;
- if(p->sps[sps_id].time_scale != 0) {
- int d = timebase * p->sps[sps_id].units_in_tick / p->sps[sps_id].time_scale;
- *duration = d;
- } else {
- *duration = 0;
- }
+ int d = 0;
+ if(p->sps[sps_id].time_scale != 0)
+ d = timebase * p->sps[sps_id].units_in_tick / p->sps[sps_id].time_scale;
if(p->sps[sps_id].cbpsize != 0)
st->es_vbv_size = p->sps[sps_id].cbpsize;
st->es_vbv_delay = -1;
- if(p->sps[sps_id].width && p->sps[sps_id].height && !st->es_buf.sb_err)
- parser_set_stream_vsize(st, p->sps[sps_id].width,
- p->sps[sps_id].height *
- (2 - p->sps[sps_id].mbs_only_flag));
+ if(p->sps[sps_id].width && p->sps[sps_id].height && d && !st->es_buf.sb_err)
+ parser_set_stream_vparam(st, p->sps[sps_id].width,
+ p->sps[sps_id].height *
+ (2 - p->sps[sps_id].mbs_only_flag),
+ d);
if(p->sps[sps_id].aspect_num && p->sps[sps_id].aspect_den) {
int h264_decode_pic_parameter_set(struct elementary_stream *st, bitstream_t *bs);
int h264_decode_slice_header(struct elementary_stream *st, bitstream_t *bs,
- int *pkttype, int *duration, int *isfield);
+ int *pkttype, int *isfield);
#endif /* PARSER_H264_H_ */
*
*/
void
-parser_set_stream_vsize(elementary_stream_t *st, int width, int height)
+parser_set_stream_vparam(elementary_stream_t *st, int width, int height,
+ int duration)
{
int need_save = 0;
- if(st->es_width == 0 && st->es_height == 0) {
+ if(st->es_width == 0 && st->es_height == 0 && st->es_frame_duration == 0) {
need_save = 1;
st->es_meta_change = 0;
- } else if(st->es_width != width || st->es_height != height) {
-
+ } else if(st->es_width != width || st->es_height != height ||
+ st->es_frame_duration != duration) {
+
st->es_meta_change++;
if(st->es_meta_change == 2)
need_save = 1;
if(need_save) {
st->es_width = width;
st->es_height = height;
+ st->es_frame_duration = duration;
service_request_save(st->es_service, 1);
}
}
st->es_aspect_num = mpeg2_aspect[aspect][0];
st->es_aspect_den = mpeg2_aspect[aspect][1];
- st->es_frame_duration = mpeg2video_framedurations[read_bits(bs, 4)];
+ int duration = mpeg2video_framedurations[read_bits(bs, 4)];
v = read_bits(bs, 18) * 400;
skip_bits(bs, 1);
v = read_bits(bs, 10) * 16 * 1024 / 8;
st->es_vbv_size = v;
- parser_set_stream_vsize(st, width, height);
+ parser_set_stream_vparam(st, width, height, duration);
return 0;
}
{
const uint8_t *buf = st->es_buf.sb_data + sc_offset;
uint32_t sc = st->es_startcode;
- int64_t d;
- int l2, pkttype, duration, isfield;
+ int l2, pkttype, isfield;
bitstream_t bs;
int ret = 0;
if(plen >= 0xffe9) st->es_incomplete =1;
parse_pes_header(t, st, buf + 6, len - 6);
}
- if(st->es_prevdts != PTS_UNSET && st->es_curdts != PTS_UNSET) {
- d = (st->es_curdts - st->es_prevdts) & 0x1ffffffffLL;
-
- if(d < 90000)
- st->es_frame_duration = d;
- }
st->es_prevdts = st->es_curdts;
return 1;
}
case 5: /* IDR+SLICE */
case 1:
- if(st->es_curpkt != NULL || st->es_frame_duration == 0)
- break;
-
l2 = len - 3 > 64 ? 64 : len - 3;
void *f = h264_nal_deescape(&bs, buf + 3, l2);
/* we just want the first stuff */
- if(h264_decode_slice_header(st, &bs, &pkttype, &duration, &isfield)) {
+ if(h264_decode_slice_header(st, &bs, &pkttype, &isfield)) {
free(f);
return 1;
}
free(f);
+ if(st->es_curpkt != NULL || st->es_frame_duration == 0)
+ break;
+
st->es_curpkt = pkt_alloc(NULL, 0, st->es_curpts, st->es_curdts);
st->es_curpkt->pkt_frametype = pkttype;
st->es_curpkt->pkt_field = isfield;
- st->es_curpkt->pkt_duration = duration ?: st->es_frame_duration;
+ st->es_curpkt->pkt_duration = st->es_frame_duration;
st->es_curpkt->pkt_commercial = t->s_tt_commercial_advice;
break;
void parser_enqueue_packet(struct service *t, struct elementary_stream *st,
th_pkt_t *pkt);
-void parser_set_stream_vsize(struct elementary_stream *st, int width, int height);
+void parser_set_stream_vparam(struct elementary_stream *st, int width, int height,
+ int duration);
extern const unsigned int mpeg2video_framedurations[16];
htsmsg_add_u32(sub, "width", st->es_width);
htsmsg_add_u32(sub, "height", st->es_height);
}
+ if(st->es_frame_duration)
+ htsmsg_add_u32(sub, "duration", st->es_frame_duration);
}
htsmsg_add_msg(m, "stream", sub);
if(!htsmsg_get_u32(c, "height", &u32))
st->es_height = u32;
+
+ if(!htsmsg_get_u32(c, "duration", &u32))
+ st->es_frame_duration = u32;
}
}
ssc->ssc_pid = st->es_pid;
ssc->ssc_width = st->es_width;
ssc->ssc_height = st->es_height;
+ ssc->ssc_frameduration = st->es_frame_duration;
}
t->s_setsourceinfo(t, &ss->ss_si);