Write aspect ratio in recorded MKV files
This commit is contained in:
parent
9b8dd5dafa
commit
ec7978e6b2
7 changed files with 101 additions and 10 deletions
|
@ -269,6 +269,13 @@ mk_build_tracks(mk_mux_t *mkm, const struct streaming_start *ss)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@ typedef struct th_pkt {
|
|||
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;
|
||||
|
||||
|
|
|
@ -99,6 +99,8 @@ typedef struct h264_private {
|
|||
char fixed_rate;
|
||||
int units_in_tick;
|
||||
int time_scale;
|
||||
uint16_t aspect_num;
|
||||
uint16_t aspect_den;
|
||||
} sps[256];
|
||||
|
||||
struct {
|
||||
|
@ -109,14 +111,44 @@ typedef struct h264_private {
|
|||
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,5 +389,9 @@ h264_decode_slice_header(th_stream_t *st, bitstream_t *bs, int *pkttype,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -757,6 +757,26 @@ parser_set_stream_vsize(th_stream_t *st, int width, int height)
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -764,14 +784,18 @@ static int
|
|||
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;
|
||||
|
@ -1143,6 +1167,9 @@ parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt)
|
|||
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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,6 +67,13 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
|
|||
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;
|
||||
|
||||
|
@ -82,6 +89,7 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
|
|||
|
||||
case SCT_H264:
|
||||
case SCT_MPEG2VIDEO:
|
||||
|
||||
if(pkt->pkt_header != NULL) {
|
||||
ssc->ssc_gh = pkt->pkt_header;
|
||||
pktbuf_ref_inc(ssc->ssc_gh);
|
||||
|
@ -95,12 +103,17 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
|
|||
*
|
||||
*/
|
||||
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;
|
||||
|
@ -121,16 +134,16 @@ headers_complete(globalheaders_t *gh, int64_t qd)
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -33,10 +33,12 @@ typedef struct streaming_start_component {
|
|||
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;
|
||||
|
|
|
@ -380,6 +380,9 @@ typedef struct th_stream {
|
|||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue