int h264_decode_pic_parameter_set(elementary_stream_t *st, bitstream_t *bs) { h264_private_t *p; uint32_t pps_id, sps_id; if((p = st->es_priv) == NULL) { p = st->es_priv = calloc(1, sizeof(h264_private_t)); p->start = dispatch_clock; } pps_id = read_golomb_ue(bs); if(pps_id >= MAX_PPS_COUNT) return 0; sps_id = read_golomb_ue(bs); if(sps_id >= MAX_SPS_COUNT) return -1; if (!p->sps[sps_id].valid) return -1; p->pps[pps_id].sps_id = sps_id; p->pps[pps_id].valid = 1; return 0; }
int h264_decode_pic_parameter_set(elementary_stream_t *st, bitstream_t *bs) { h264_private_t *p; int pps_id, sps_id; if((p = st->es_priv) == NULL) p = st->es_priv = calloc(1, sizeof(h264_private_t)); pps_id = read_golomb_ue(bs); sps_id = read_golomb_ue(bs); p->pps[pps_id].sps = sps_id; return 0; }
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)) { 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]; } } if(read_bits1(bs)){ /* overscan_info_present_flag */ read_bits1(bs); /* overscan_appropriate_flag */ } if(read_bits1(bs)){ /* video_signal_type_present_flag */ read_bits(bs, 3); /* video_format */ read_bits1(bs); /* video_full_range_flag */ if(read_bits1(bs)){ /* colour_description_present_flag */ read_bits(bs, 8); /* colour_primaries */ read_bits(bs, 8); /* transfer_characteristics */ read_bits(bs, 8); /* matrix_coefficients */ } } if(read_bits1(bs)){ /* chroma_location_info_present_flag */ read_golomb_ue(bs); /* chroma_sample_location_type_top_field */ read_golomb_ue(bs); /* chroma_sample_location_type_bottom_field */ } if(!read_bits1(bs)) /* We need timing info */ return 0; p->sps[sps_id].units_in_tick = read_bits(bs, 32); p->sps[sps_id].time_scale = read_bits(bs, 32); p->sps[sps_id].fixed_rate = read_bits1(bs); return 0; }
static int decode_vui(h264_sps_t *sps, bitstream_t *bs) { sps->aspect_num = 1; sps->aspect_den = 1; if (read_bits1(bs)) { uint32_t aspect = read_bits(bs, 8); if(aspect == 255) { sps->aspect_num = read_bits(bs, 16); sps->aspect_den = read_bits(bs, 16); } else if(aspect < ARRAY_SIZE(h264_aspect)) { sps->aspect_num = h264_aspect[aspect][0]; sps->aspect_den = h264_aspect[aspect][1]; } } if (read_bits1(bs)) /* overscan_info_present_flag */ skip_bits1(bs); /* overscan_appropriate_flag */ if (read_bits1(bs)) { /* video_signal_type_present_flag */ skip_bits(bs, 3); /* video_format */ skip_bits1(bs); /* video_full_range_flag */ if(read_bits1(bs)){ /* colour_description_present_flag */ skip_bits(bs, 8); /* colour_primaries */ skip_bits(bs, 8); /* transfer_characteristics */ skip_bits(bs, 8); /* matrix_coefficients */ } } if (read_bits1(bs)) { /* chroma_location_info_present_flag */ read_golomb_ue(bs); /* chroma_sample_location_type_top_field */ read_golomb_ue(bs); /* chroma_sample_location_type_bottom_field */ } if (!read_bits1(bs)) /* We need timing info */ return 0; if (remaining_bits(bs) < 65) return 0; sps->units_in_tick = read_bits(bs, 32); sps->time_scale = read_bits(bs, 32); sps->fixed_rate = read_bits1(bs); return 0; }
signed int read_golomb_se(bitstream_t *bs) { int v, pos; v = read_golomb_ue(bs); if(v == 0) return 0; pos = v & 1; v = (v + 1) >> 1; return pos ? v : -v; }
int h264_decode_slice_header(elementary_stream_t *st, bitstream_t *bs, int *pkttype, int *duration, int *isfield) { h264_private_t *p; int slice_type, pps_id, sps_id, fnum; if((p = st->es_priv) == NULL) return -1; read_golomb_ue(bs); /* first_mb_in_slice */ slice_type = read_golomb_ue(bs); if(slice_type > 4) slice_type -= 5; /* Fixed slice type per frame */ switch(slice_type) { case 0: *pkttype = PKT_P_FRAME; break; case 1: *pkttype = PKT_B_FRAME; break; case 2: *pkttype = PKT_I_FRAME; break; default: return -1; } pps_id = read_golomb_ue(bs); sps_id = p->pps[pps_id].sps; if(p->sps[sps_id].max_frame_num_bits == 0) return -1; fnum = read_bits(bs, p->sps[sps_id].max_frame_num_bits); int field = 0; int timebase = 180000; if(!p->sps[sps_id].mbs_only_flag) { if(read_bits1(bs)) { read_bits1(bs); // bottom field field = 1; } } *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; } 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].aspect_num && p->sps[sps_id].aspect_den) { int w = p->sps[sps_id].aspect_num * st->es_width; int h = p->sps[sps_id].aspect_den * st->es_height; if(w && h) { int d = gcd(w, h); st->es_aspect_num = w / d; st->es_aspect_den = h / d; } } else { st->es_aspect_num = 0; st->es_aspect_den = 1; } return 0; }
int h264_decode_seq_parameter_set(elementary_stream_t *st, bitstream_t *bs) { int profile_idc, level_idc, poc_type; unsigned int sps_id, tmp, i, width, height; int cbpsize = -1; h264_private_t *p; if((p = st->es_priv) == NULL) p = st->es_priv = calloc(1, sizeof(h264_private_t)); profile_idc= read_bits(bs, 8); read_bits1(bs); //constraint_set0_flag read_bits1(bs); //constraint_set1_flag read_bits1(bs); //constraint_set2_flag read_bits1(bs); //constraint_set3_flag read_bits(bs, 4); // reserved level_idc= read_bits(bs, 8); sps_id= read_golomb_ue(bs); i = 0; while(h264_lev2cpbsize[i][0] != -1) { if(h264_lev2cpbsize[i][0] >= level_idc) { cbpsize = h264_lev2cpbsize[i][1]; break; } i++; } if(cbpsize < 0) return -1; p->sps[sps_id].cbpsize = cbpsize * 125; /* Convert from kbit to bytes */ if(profile_idc >= 100){ //high profile if(read_golomb_ue(bs) == 3) //chroma_format_idc read_bits1(bs); //residual_color_transform_flag read_golomb_ue(bs); //bit_depth_luma_minus8 read_golomb_ue(bs); //bit_depth_chroma_minus8 read_bits1(bs); if(read_bits1(bs)) { /* Scaling matrices */ decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 64); decode_scaling_list(bs, 64); } } p->sps[sps_id].max_frame_num_bits = read_golomb_ue(bs) + 4; poc_type= read_golomb_ue(bs); if(poc_type == 0){ //FIXME #define read_golomb_ue(bs); } else if(poc_type == 1){//FIXME #define read_bits1(bs); read_golomb_se(bs); read_golomb_se(bs); tmp = read_golomb_ue(bs); /* poc_cycle_length */ for(i = 0; i < tmp; i++) read_golomb_se(bs); }else if(poc_type != 2){ /* Illegal poc */ return -1; } tmp = read_golomb_ue(bs); read_bits1(bs); width = read_golomb_ue(bs) + 1; /* mb width */ height = read_golomb_ue(bs) + 1; /* mb height */ p->sps[sps_id].width = width * 16; p->sps[sps_id].height = height * 16; p->sps[sps_id].mbs_only_flag = read_bits1(bs); if(!p->sps[sps_id].mbs_only_flag) p->sps[sps_id].aff = read_bits1(bs); read_bits1(bs); /* CROP */ if(read_bits1(bs)){ tmp = read_golomb_ue(bs); tmp = read_golomb_ue(bs); tmp = read_golomb_ue(bs); tmp = read_golomb_ue(bs); } if(read_bits1(bs)) { decode_vui(p, bs, sps_id); return 0; } else { return -1; } }
int h264_decode_slice_header(elementary_stream_t *st, bitstream_t *bs, int *pkttype, int *isfield) { h264_private_t *p; h264_pps_t *pps; h264_sps_t *sps; uint32_t slice_type, pps_id, width, height, v; uint64_t d; *pkttype = 0; *isfield = 0; if ((p = st->es_priv) == NULL) return -1; read_golomb_ue(bs); /* first_mb_in_slice */ slice_type = read_golomb_ue(bs); if (slice_type > 4) slice_type -= 5; /* Fixed slice type per frame */ pps_id = read_golomb_ue(bs); if (pps_id >= MAX_PPS_COUNT) return -1; pps = &p->pps[pps_id]; if (!pps->valid) return -1; sps = &p->sps[pps->sps_id]; if (!sps->valid) return -1; if (!sps->max_frame_num_bits) return -1; switch(slice_type) { case 0: *pkttype = PKT_P_FRAME; break; case 1: *pkttype = PKT_B_FRAME; break; case 2: *pkttype = PKT_I_FRAME; break; default: return -1; } skip_bits(bs, sps->max_frame_num_bits); if (!sps->mbs_only_flag) if (read_bits1(bs)) { skip_bits1(bs); // bottom field *isfield = 1; } d = 0; if (sps->time_scale) d = 180000 * (uint64_t)sps->units_in_tick / (uint64_t)sps->time_scale; if (d == 0 && st->es_frame_duration == 0 && p->start + 4 < dispatch_clock) { tvhwarn("parser", "H264 stream has not timing information, using 30fps"); d = 3000; /* 90000/30 = 3000 : 30fps */ } if (sps->cbpsize) st->es_vbv_size = sps->cbpsize; st->es_vbv_delay = -1; width = sps->width; height = sps->height * (2 - sps->mbs_only_flag); if (width && height && d) parser_set_stream_vparam(st, width, height, d); if (sps->aspect_num && sps->aspect_den) { width *= sps->aspect_num; height *= sps->aspect_den; if (width && height) { v = gcdU32(width, height); st->es_aspect_num = width / v; st->es_aspect_den = height / v; } } else { st->es_aspect_num = 0; st->es_aspect_den = 1; } return 0; }
int h264_decode_seq_parameter_set(elementary_stream_t *st, bitstream_t *bs) { uint32_t profile_idc, level_idc, poc_type; uint32_t sps_id, tmp, i, width, height; uint32_t cbpsize, mbs_only_flag, aff; uint32_t max_frame_num_bits; uint32_t crop_left, crop_right, crop_top, crop_bottom; h264_private_t *p; h264_sps_t *sps; if ((p = st->es_priv) == NULL) { p = st->es_priv = calloc(1, sizeof(h264_private_t)); p->start = dispatch_clock; } profile_idc = read_bits(bs, 8); skip_bits1(bs); //constraint_set0_flag skip_bits1(bs); //constraint_set1_flag skip_bits1(bs); //constraint_set2_flag skip_bits1(bs); //constraint_set3_flag skip_bits(bs, 4); // reserved level_idc = read_bits(bs, 8); sps_id = read_golomb_ue(bs); if(sps_id >= MAX_SPS_COUNT) return -1; sps = &p->sps[sps_id]; i = 0; cbpsize = -1; while (h264_lev2cpbsize[i][0] != -1) { if (h264_lev2cpbsize[i][0] >= level_idc) { cbpsize = h264_lev2cpbsize[i][1]; break; } i++; } if (cbpsize == -1) return -1; if (profile_idc >= 100){ //high profile tmp = read_golomb_ue(bs); if (tmp == 3) //chroma_format_idc read_bits1(bs); //residual_color_transform_flag read_golomb_ue(bs); //bit_depth_luma_minus8 read_golomb_ue(bs); //bit_depth_chroma_minus8 read_bits1(bs); //transform_bypass if(read_bits1(bs)) { /* Scaling matrices */ decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); decode_scaling_list(bs, 64); decode_scaling_list(bs, 64); } } max_frame_num_bits = read_golomb_ue(bs) + 4; poc_type = read_golomb_ue(bs); // pic_order_cnt_type if(poc_type == 0){ read_golomb_ue(bs); } else if(poc_type == 1){ skip_bits1(bs); read_golomb_se(bs); read_golomb_se(bs); tmp = read_golomb_ue(bs); /* poc_cycle_length */ for(i = 0; i < tmp; i++) read_golomb_se(bs); }else if(poc_type != 2){ /* Illegal poc */ return -1; } tmp = read_golomb_ue(bs); read_bits1(bs); width = read_golomb_ue(bs) + 1; /* mb width */ height = read_golomb_ue(bs) + 1; /* mb height */ mbs_only_flag = read_bits1(bs); aff = 0; if(!mbs_only_flag) aff = read_bits1(bs); read_bits1(bs); /* CROP */ crop_left = crop_right = crop_top = crop_bottom = 0; if (read_bits1(bs)){ crop_left = read_golomb_ue(bs) * 2; crop_right = read_golomb_ue(bs) * 2; crop_top = read_golomb_ue(bs) * 2; crop_bottom = read_golomb_ue(bs) * 2; } if (read_bits1(bs)) /* vui present */ if (decode_vui(sps, bs)) return -1; sps->max_frame_num_bits = max_frame_num_bits; sps->mbs_only_flag = mbs_only_flag; sps->aff = aff; sps->cbpsize = cbpsize * 125; /* Convert from kbit to bytes */ sps->width = width * 16 - crop_left - crop_right; sps->height = height * 16 - crop_top - crop_bottom; sps->valid = 1; return 0; }