ebml_append_uint(vi, 0xb0, ssc->ssc_width);
ebml_append_uint(vi, 0xba, ssc->ssc_height);
+ if(ssc->ssc_aspect_num && ssc->ssc_aspect_den) {
+ ebml_append_uint(vi, 0x54b2, 3); // Display width/height is in DAR
+ ebml_append_uint(vi, 0x54b0, ssc->ssc_aspect_num);
+ ebml_append_uint(vi, 0x54ba, ssc->ssc_aspect_den);
+
+ }
+
ebml_append_master(t, 0xe0, vi);
}
uint8_t pkt_channels;
uint8_t pkt_sri;
+ uint16_t pkt_aspect_num;
+ uint16_t pkt_aspect_den;
+
pktbuf_t *pkt_payload;
pktbuf_t *pkt_header;
char fixed_rate;
int units_in_tick;
int time_scale;
+ uint16_t aspect_num;
+ uint16_t aspect_den;
} sps[256];
struct {
+static const uint16_t h264_aspect[17][2] = {
+ {0, 1},
+ {1, 1},
+ {12, 11},
+ {10, 11},
+ {16, 11},
+ {40, 33},
+ {24, 11},
+ {20, 11},
+ {32, 11},
+ {80, 33},
+ {18, 11},
+ {15, 11},
+ {64, 33},
+ {160,99},
+ {4, 3},
+ {3, 2},
+ {2, 1},
+};
+
static int
decode_vui(h264_private_t *p, bitstream_t *bs, int sps_id)
{
+ p->sps[sps_id].aspect_num = 0;
+ p->sps[sps_id].aspect_den = 1;
+
if(read_bits1(bs)) {
- if(read_bits(bs, 8) == 255) {
- read_bits(bs, 16);
- read_bits(bs, 16);
+ int aspect = read_bits(bs, 8);
+
+ if(aspect == 255) {
+ uint16_t num = read_bits(bs, 16);
+ uint16_t den = read_bits(bs, 16);
+ p->sps[sps_id].aspect_num = num;
+ p->sps[sps_id].aspect_den = den;
+ } else if(aspect < 17) {
+ p->sps[sps_id].aspect_num = h264_aspect[aspect][0];
+ p->sps[sps_id].aspect_den = h264_aspect[aspect][1];
}
}
parser_set_stream_vsize(st, p->sps[sps_id].width,
p->sps[sps_id].height *
(2 - p->sps[sps_id].mbs_only_flag));
+
+ st->st_aspect_num = p->sps[sps_id].aspect_num;
+ st->st_aspect_den = p->sps[sps_id].aspect_den;
+
return 0;
}
}
+static const uint8_t mpeg2_aspect[16][2]={
+ {0,1},
+ {1,1},
+ {4,3},
+ {16,9},
+ {221,100},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+ {0,1},
+};
+
+
/**
* Parse mpeg2video sequence start
*/
parse_mpeg2video_seq_start(th_transport_t *t, th_stream_t *st,
bitstream_t *bs)
{
- int v, width, height;
+ int v, width, height, aspect;
if(bs->len < 61)
return 1;
width = read_bits(bs, 12);
height = read_bits(bs, 12);
- skip_bits(bs, 4);
+ aspect = read_bits(bs, 4);
+
+ st->st_aspect_num = mpeg2_aspect[aspect][0];
+ st->st_aspect_den = mpeg2_aspect[aspect][1];
+
st->st_frame_duration = mpeg2video_framedurations[read_bits(bs, 4)];
v = read_bits(bs, 18) * 400;
pktbuf_len(pkt->pkt_payload));
#endif
+ pkt->pkt_aspect_num = st->st_aspect_num;
+ pkt->pkt_aspect_den = st->st_aspect_den;
+
// avgstat_add(&st->st_rate, pkt->pkt_payloadlen, dispatch_clock);
/**
ssc->ssc_sri = pkt->pkt_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(ssc->ssc_gh != NULL)
return;
case SCT_H264:
case SCT_MPEG2VIDEO:
+
if(pkt->pkt_header != NULL) {
ssc->ssc_gh = pkt->pkt_header;
pktbuf_ref_inc(ssc->ssc_gh);
*
*/
static int
-header_complete(streaming_start_component_t *ssc)
+header_complete(streaming_start_component_t *ssc, int not_so_picky)
{
if((SCT_ISAUDIO(ssc->ssc_type) || SCT_ISVIDEO(ssc->ssc_type)) &&
ssc->ssc_frameduration == 0)
return 0;
+ if(SCT_ISVIDEO(ssc->ssc_type)) {
+ if(!not_so_picky && (ssc->ssc_aspect_num == 0 || ssc->ssc_aspect_den == 0))
+ return 0;
+ }
+
if(SCT_ISAUDIO(ssc->ssc_type) &&
(ssc->ssc_sri == 0 || ssc->ssc_channels == 0))
return 0;
{
streaming_start_t *ss = gh->gh_ss;
streaming_start_component_t *ssc;
- int i;
+ int i, threshold = qd > (MAX_SCAN_TIME * 90);
assert(ss != NULL);
for(i = 0; i < ss->ss_num_components; i++) {
ssc = &ss->ss_components[i];
- if(!header_complete(ssc)) {
+ if(!header_complete(ssc, threshold)) {
- if(qd > (MAX_SCAN_TIME * 90)) {
+ if(threshold) {
ssc->ssc_disabled = 1;
} else {
return 0;
uint16_t ssc_pid;
int16_t ssc_width;
int16_t ssc_height;
+ int16_t ssc_aspect_num;
+ int16_t ssc_aspect_den;
uint8_t ssc_sri;
uint8_t ssc_channels;
uint8_t ssc_disabled;
-
+
pktbuf_t *ssc_gh;
int ssc_frameduration;
streaming_component_type_t st_type;
int st_index;
+ uint16_t st_aspect_num;
+ uint16_t st_aspect_den;
+
char st_lang[4]; /* ISO 639 3-letter language code */
uint16_t st_composition_id;
uint16_t st_ancillary_id;