📄 av_parsers.c
字号:
avc_get_ue(bs); /* chroma_sample_location_type_bottom_field */ } sps->timing_info_present_flag = gf_bs_read_int(bs, 1); if (sps->timing_info_present_flag) { sps->num_units_in_tick = gf_bs_read_int(bs, 32); sps->time_scale = gf_bs_read_int(bs, 32); sps->fixed_frame_rate_flag = gf_bs_read_int(bs, 1); } } return sps_id;}s32 AVC_ReadPictParamSet(GF_BitStream *bs, AVCState *avc){ s32 pps_id = avc_get_ue(bs); AVC_PPS *pps= &avc->pps[pps_id]; if (!pps->status) pps->status = 1; pps->sps_id= avc_get_ue(bs); /*pps->cabac = */gf_bs_read_int(bs, 1); /*pps->pic_order_present= */gf_bs_read_int(bs, 1); pps->slice_group_count= avc_get_ue(bs) + 1; if (pps->slice_group_count > 1 ) /*pps->mb_slice_group_map_type = */avc_get_ue(bs); /*pps->ref_count[0]= */avc_get_ue(bs) /*+ 1*/; /*pps->ref_count[1]= */avc_get_ue(bs) /*+ 1*/; /* if ((pps->ref_count[0] > 32) || (pps->ref_count[1] > 32)) return -1; */ /*pps->weighted_pred = */gf_bs_read_int(bs, 1); /*pps->weighted_bipred_idc = */gf_bs_read_int(bs, 2); /*pps->init_qp = */avc_get_se(bs) /*+ 26*/; /*pps->init_qs= */avc_get_se(bs) /*+ 26*/; /*pps->chroma_qp_index_offset = */avc_get_se(bs); /*pps->deblocking_filter_parameters_present = */gf_bs_read_int(bs, 1); /*pps->constrained_intra_pred = */gf_bs_read_int(bs, 1); pps->redundant_pic_cnt_present = gf_bs_read_int(bs, 1); return pps_id;}static s32 avc_parse_slice(GF_BitStream *bs, AVCState *avc, AVCSliceInfo *si) { s32 first_mb_in_slice, pps_id; /*s->current_picture.reference= h->nal_ref_idc != 0;*/ first_mb_in_slice = avc_get_ue(bs); si->slice_type = avc_get_ue(bs); if (si->slice_type > 9) return -1; pps_id = avc_get_ue(bs); if (pps_id>255) return -1; si->pps = &avc->pps[pps_id]; if (!si->pps->slice_group_count) return -2; si->sps = &avc->sps[si->pps->sps_id]; if (!si->sps->log2_max_frame_num) return -2; si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num); si->field_pic_flag = 0; if (si->sps->frame_mbs_only_flag) { /*s->picture_structure= PICT_FRAME;*/ } else { si->field_pic_flag = gf_bs_read_int(bs, 1); if (si->field_pic_flag) si->bottom_field_flag = gf_bs_read_int(bs, 1); } if (si->nal_unit_type==GF_AVC_NALU_IDR_SLICE) si->idr_pic_id = avc_get_ue(bs); if (si->sps->poc_type==0) { si->poc_lsb = gf_bs_read_int(bs, si->sps->log2_max_poc_lsb); if (si->pps->pic_order_present && !si->field_pic_flag) { si->delta_poc_bottom = avc_get_se(bs); } } else if ((si->sps->poc_type==1) && !si->sps->delta_pic_order_always_zero_flag) { si->delta_poc[0] = avc_get_se(bs); if ((si->pps->pic_order_present==1) && !si->field_pic_flag) si->delta_poc[1] = avc_get_se(bs); } if (si->pps->redundant_pic_cnt_present) { si->redundant_pic_cnt = avc_get_ue(bs); } return 0;}static s32 avc_parse_recovery_point_sei(GF_BitStream *bs, AVCState *avc) { AVCSeiRecoveryPoint *rp = &avc->sei.recovery_point; rp->frame_cnt = avc_get_ue(bs); rp->exact_match_flag = gf_bs_read_int(bs, 1); rp->broken_link_flag = gf_bs_read_int(bs, 1); rp->changing_slice_group_idc = gf_bs_read_int(bs, 2); rp->valid = 1; return 0;}static void avc_compute_poc(AVCSliceInfo *si){ enum { AVC_PIC_FRAME, AVC_PIC_FIELD_TOP, AVC_PIC_FIELD_BOTTOM, } pic_type; s32 field_poc[2] = {0,0}; s32 max_frame_num = 1 << (si->sps->log2_max_frame_num); /* picture type */ if (si->sps->frame_mbs_only_flag || !si->field_pic_flag) pic_type = AVC_PIC_FRAME; else if (si->bottom_field_flag) pic_type = AVC_PIC_FIELD_BOTTOM; else pic_type = AVC_PIC_FIELD_TOP; /* frame_num_offset */ if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) { si->poc_lsb_prev = 0; si->poc_msb_prev = 0; si->frame_num_offset = 0; } else { if (si->frame_num < si->frame_num_prev) si->frame_num_offset = si->frame_num_offset_prev + max_frame_num; else si->frame_num_offset = si->frame_num_offset_prev; } if (si->sps->poc_type==0) { const u32 max_poc_lsb = 1 << (si->sps->log2_max_poc_lsb); if ((si->poc_lsb < si->poc_lsb_prev) && (si->poc_lsb_prev - si->poc_lsb >= max_poc_lsb / 2) ) si->poc_msb = si->poc_msb_prev + max_poc_lsb; else if ((si->poc_lsb > si->poc_lsb_prev) && (si->poc_lsb - si->poc_lsb_prev > max_poc_lsb / 2)) si->poc_msb = si->poc_msb_prev - max_poc_lsb; else si->poc_msb = si->poc_msb_prev; field_poc[0] = field_poc[1] = si->poc_msb + si->poc_lsb; if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc_bottom; } else if (si->sps->poc_type==1) { u32 i; s32 abs_frame_num, expected_delta_per_poc_cycle, expected_poc; if (si->sps->poc_cycle_length) abs_frame_num = si->frame_num_offset + si->frame_num; else abs_frame_num = 0; if (!si->nal_ref_idc && (abs_frame_num > 0)) abs_frame_num--; expected_delta_per_poc_cycle = 0; for (i=0; i < si->sps->poc_cycle_length; i++) expected_delta_per_poc_cycle += si->sps->offset_for_ref_frame[i]; if (abs_frame_num > 0) { const u32 poc_cycle_cnt = ( abs_frame_num - 1 ) / si->sps->poc_cycle_length; const u32 frame_num_in_poc_cycle = ( abs_frame_num - 1 ) % si->sps->poc_cycle_length; expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle; for (i = 0; i<=frame_num_in_poc_cycle; i++) expected_poc += si->sps->offset_for_ref_frame[i]; } else { expected_poc = 0; } if (!si->nal_ref_idc) expected_poc += si->sps->offset_for_non_ref_pic; field_poc[0] = expected_poc + si->delta_poc[0]; field_poc[1] = field_poc[0] + si->sps->offset_for_top_to_bottom_field; if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc[1]; } else if (si->sps->poc_type== 2) { int poc; if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) { poc = 0; } else { const int abs_frame_num = si->frame_num_offset + si->frame_num; poc = 2 * abs_frame_num; if (!si->nal_ref_idc) poc -= 1; } field_poc[0] = poc; field_poc[1] = poc; } if (pic_type == AVC_PIC_FRAME) si->poc = MIN(field_poc[0], field_poc[1] ); else if (pic_type == AVC_PIC_FIELD_TOP) si->poc = field_poc[0]; else si->poc = field_poc[1];}s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc){ u8 temp; s32 slice, ret; AVCSliceInfo n_state; slice = 0; memcpy(&n_state, &avc->s_info, sizeof(AVCSliceInfo)); temp = n_state.nal_unit_type = nal_hdr & 0x1F; n_state.nal_ref_idc = (nal_hdr>>5) & 0x3; ret = 0; switch (temp) { case GF_AVC_NALU_ACCESS_UNIT: case GF_AVC_NALU_END_OF_SEQ: case GF_AVC_NALU_END_OF_STREAM: ret = 1; break; case GF_AVC_NALU_NON_IDR_SLICE: case GF_AVC_NALU_DP_A_SLICE: case GF_AVC_NALU_DP_B_SLICE: case GF_AVC_NALU_DP_C_SLICE: case GF_AVC_NALU_IDR_SLICE: slice = 1; /* slice buffer - read the info and compare.*/ ret = avc_parse_slice(bs, avc, &n_state); if (ret<0) return ret; ret = 0; if ((avc->s_info.nal_unit_type > GF_AVC_NALU_IDR_SLICE) || (avc->s_info.nal_unit_type < GF_AVC_NALU_NON_IDR_SLICE)) { break; } if (avc->s_info.frame_num != n_state.frame_num) { ret = 1; break; } if (avc->s_info.field_pic_flag != n_state.field_pic_flag) { ret = 1; break; } if ((avc->s_info.nal_ref_idc != n_state.nal_ref_idc) && (!avc->s_info.nal_ref_idc || !n_state.nal_ref_idc)) { ret = 1; break; } assert(avc->s_info.sps); if (avc->s_info.sps->poc_type == n_state.sps->poc_type) { if (!avc->s_info.sps->poc_type) { if (avc->s_info.poc_lsb != n_state.poc_lsb) { ret = 1; break; } if (avc->s_info.delta_poc_bottom != n_state.delta_poc_bottom) { ret = 1; break; } } else if (avc->s_info.sps->poc_type==1) { if (avc->s_info.delta_poc[0] != n_state.delta_poc[0]) { ret =1; break; } if (avc->s_info.delta_poc[1] != n_state.delta_poc[1]) { ret = 1; break; } } } if ((avc->s_info.nal_unit_type == GF_AVC_NALU_IDR_SLICE) && (n_state.nal_unit_type == GF_AVC_NALU_IDR_SLICE)) { if (avc->s_info.idr_pic_id != n_state.idr_pic_id) { ret = 1; break; } } break; default: if (avc->s_info.nal_unit_type <= GF_AVC_NALU_IDR_SLICE) ret = 1; else ret = 0; break; } /* save _prev values */ if (ret && avc->s_info.sps) { n_state.frame_num_offset_prev = avc->s_info.frame_num_offset; if ((avc->s_info.sps->poc_type != 2) || (avc->s_info.nal_ref_idc != 0)) n_state.frame_num_prev = avc->s_info.frame_num; if (avc->s_info.nal_ref_idc) { n_state.poc_lsb_prev = avc->s_info.poc_lsb; n_state.poc_msb_prev = avc->s_info.poc_msb; } } if (slice) avc_compute_poc(&n_state); memcpy(&avc->s_info, &n_state, sizeof(AVCSliceInfo)); return ret;}u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc){ u32 ptype, psize, hdr, written, start, var, num_zero, size_fix, i; char *new_buffer; GF_BitStream *bs; hdr = buffer[0]; if ((hdr & 0x1F) != GF_AVC_NALU_SEI) return 0; bs = gf_bs_new(buffer, nal_size, GF_BITSTREAM_READ); gf_bs_read_int(bs, 8); new_buffer = (char*)malloc(sizeof(char)*nal_size); new_buffer[0] = (char) hdr; written = 1; /*parse SEI*/ while (gf_bs_available(bs)) { Bool do_copy; ptype = 0; while (gf_bs_peek_bits(bs, 8, 0)==0xFF) { gf_bs_read_int(bs, 8); ptype += 255; } ptype += gf_bs_read_int(bs, 8); psize = 0; while (gf_bs_peek_bits(bs, 8, 0)==0xFF) { gf_bs_read_int(bs, 8); psize += 255; } psize += gf_bs_read_int(bs, 8); start = (u32) gf_bs_get_position(bs); do_copy = 1; switch (ptype) { /*remove SEI messages forbidden in MP4*/ case 3: /*filler data*/ case 10: /*sub_seq info*/ case 11: /*sub_seq_layer char*/ case 12: /*sub_seq char*/ do_copy = 0; break; case 5: /*user unregistered */ { u8 prev = buffer[start+2+psize]; buffer[start+2+psize] = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[avc-h264] SEI user message %s\n", buffer+start+2)); buffer[start+2+psize] = prev; } break; case 6: /*recovery point*/ { GF_BitStream *rp_bs = gf_bs_new(buffer + start, psize, GF_BITSTREAM_READ); avc_parse_recovery_point_sei(rp_bs, avc); gf_bs_del(rp_bs); } break; case 0: /*buffering period*/ case 1: /*pic_timing*/ case 2: /*pan scan rect*/ case 4: /*user registered ITU t35*/ case 7: /*def_rec_pic_marking_repetition*/ case 8: /*spare_pic*/ case 9: /*scene info*/ case 13: /*full frame freeze*/ case 14: /*full frame freeze release*/ case 15: /*full frame snapshot*/ case 16: /*progressive refinement segment start*/ case 17: /*progressive refinement segment end*/ case 18: /*motion constrained slice group*/ default:/*reserved*/ break; } /*fix payload size due to emulation prevention bytes*/ size_fix = 0; num_zero = 0; for (i = 0; i < psize + size_fix; i++) { if (!buffer[start + i]) num_zero++; else { if ((num_zero == 2) && (buffer[start + i] == 3)) size_fix++; num_zero = 0; } } if (do_copy) { var = ptype; while (var>=255) { new_buffer[written] = (char) 0xff; written++; var-=255;} new_buffer[written] = (char) var; written++; var = psize; while (var>=255) { new_buffer[written] = (char) 0xff; written++; var-=255;} new_buffer[written] = (char) var; written++; memcpy(new_buffer+written, buffer+start, sizeof(char)* (psize + size_fix)); written += psize; } gf_bs_skip_bytes(bs, (u64) (psize + size_fix)); gf_bs_align(bs); if (gf_bs_available(bs)<2) { if (gf_bs_peek_bits(bs, 8, 0)==0x80) { new_buffer[written] = (char) 0x80; written += 1; break; } } } gf_bs_del(bs); assert(written<=nal_size); if (written) memcpy(buffer, new_buffer, sizeof(char)*written); free(new_buffer); /*if only hdr written ignore*/ return (written>1) ? written : 0;}static u8 avc_get_sar_idx(u32 w, u32 h){ u32 i; for (i=0; i<14; i++) { if ((avc_sar[i].w==w) && (avc_sar[i].h==h)) return i; } return 0xFF;}GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d){ GF_BitStream *orig, *mod; AVCState avc; u32 i, bit_offset, flag; s32 idx; GF_AVCConfigSlot *slc; memset(&avc, 0, sizeof(AVCState)); i=0; while ((slc = (GF_AVCConfigSlot *)gf_list_enum(avcc->sequenceParameterSets, &i))) { orig = gf_bs_new(slc->data, slc->size, GF_BITSTREAM_READ); /*skip NALU type*/ gf_bs_read_int(orig, 8); idx = AVC_ReadSeqInfo(orig, &avc, &bit_offset); if (idx<0) { gf_bs_del(orig); continue; } mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_seek(orig, 0); /*copy over till vui flag*/ while (bit_offset) { flag = gf_bs_read_int(orig, 1); gf_bs_write_int(mod, flag, 1); bit_offset--; } /*check VUI*/ flag = gf_bs_read_int(orig, 1); gf_bs_write_int(mod, 1, 1); if (flag) { /*aspect_ratio_info_present_flag*/ if (gf_bs_read_int(orig, 1)) { s32 aspect_ratio_idc = gf_bs_read_int(orig, 8); if (aspect_ratio_idc == 255) { gf_bs_read_int(orig, 16); /*AR num*/ gf_bs_read_int(orig, 16); /*AR den*/ } } } if ((ar_d<0) || (ar_n<0)) { /*no AR signaled*/ gf_bs_write_int(mod, 0, 1); } else { u32 sarx; gf_bs_write_int(mod, 1, 1); sarx = avc_get_sar_idx((u32) ar_n, (u32) ar_d); gf_bs_write_int(mod, sarx, 8); if (sarx==0xFF) { gf_bs_write_int(mod, ar_n, 16); gf_bs_write_int(mod, ar_d, 16); } } /*no VUI in input bitstream, set all vui flags to 0*/ if (!flag) { gf_bs_write_int(mod, 0, 1); /*overscan_info_present_flag */ gf_bs_write_int(mod, 0, 1); /*video_signal_type_present_flag */ gf_bs_write_int(mod, 0, 1); /*chroma_location_info_present_flag */ gf_bs_write_int(mod, 0, 1); /*timing_info_present_flag*/ gf_bs_write_int(mod, 0, 1); /*nal_hrd_parameters_present*/ gf_bs_write_int(mod, 0, 1); /*vcl_hrd_parameters_present*/ gf_bs_write_int(mod, 0, 1); /*pic_struct_present*/ gf_bs_write_int(mod, 0, 1); /*bitstream_restriction*/ } /*finally copy over remaining*/ while (gf_bs_bits_available(orig)) { flag = gf_bs_read_int(orig, 1); gf_bs_write_int(mod, flag, 1); } gf_bs_del(orig); free(slc->data); slc->data = NULL; gf_bs_get_content(mod, (char **) &slc->data, &flag); slc->size = flag; gf_bs_del(mod); } return GF_OK;}GF_EXPORTGF_Err gf_avc_get_sps_info(char *sps_data, u32 sps_size, u32 *width, u32 *height, s32 *par_n, s32 *par_d){ GF_BitStream *bs; AVCState avc; s32 idx; memset(&avc, 0, sizeof(AVCState)); bs = gf_bs_new(sps_data, sps_size, GF_BITSTREAM_READ); /*skip NALU type*/ gf_bs_read_int(bs, 8); idx = AVC_ReadSeqInfo(bs, &avc, NULL); gf_bs_del(bs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -