Fmtp section of SDP

Source: Internet
Author: User

The previous SDP did not parse the "A = fmtp" field for the h264 encoded video. Today, it is added to parse the width and height of the video.

In section 8.2 of rfc3984, field is introduced. Here we only decode the sprop-parameter-sets field, because my main purpose is to parse the video width and height information.

This field is encoded with base-64. Therefore, the base-64 is decoded first. The decoding method is provided here:

long CBase64::Decode(const char *pSrc, long srcLen, unsigned char *pDest, long destLen){int i = 0;int iCnt = 0;unsigned char * p = pDest;for (i=0; i<srcLen; i++){if (pSrc[i] > 127){continue;}if (pSrc[i] == '='){return p-pDest+1;}unsigned char a = Base64IdxTab[pSrc[i]];if (a == 255){continue;}switch (iCnt){case 0:{*p = a << 2;iCnt++;}break;case 1:{*p++ |= a >> 4;*p = a << 4;iCnt++;}break;case 2:{*p++ |= a >> 2;*p = a << 6;iCnt++;}break;case 3:{*p++ |= a;iCnt = 0;}break;} }*p = 0x00;return p-pDest;}

The return value is the length of the target string.

Then, for the contact string, its first byte is a NUL header. We want its nal_type to be 7, that is, the sequential parameter set (SPS)

For this parameter set, we want to solve the pic_width_in_mbs_minus1 field and pic_height_in_map_units_minus1 field in accordance with the 7.3.2.1 Syntax of H.264.

Here we have encountered a problem because it is an exponential Columbus code and therefore needs to be decoded:

Int golombdecode (bool * pbinaryarray, Int & des) {If (pbinaryarray = NULL) {return-1;} int iter = 0; int numofzero = 0; int m_bit = 0; int info = 0; double result; // find the first 1 while (pbinaryarray [iter ++] = 0) {numofzero ++;} For (INT I = NumOfZero-1; i> = 0; I --) {info + = pbinaryarray [iter ++] <I;} result = POW (double) 2, (double) numofzero) + Info-1; des = result; return ITER ;}

The return value is the offset address of the binary string.

Because of the Variable Length of the exponential Columbus code, we need to work out the entire SPS (based on ITU-T h264 7.3.2.1.1 ):

int ParseSPS(unsigned char *pSrc, unsigned long SrcLen, unsigned long &VideoWidth, unsigned long &VideoHeight){int ret = 0;unsigned long offset = 0;bool *pBinaryArray = new bool[SrcLen*8];unsigned long iter = 0;unsigned char mask = 0x80;for (int i=0; i<SrcLen; i++){mask = 0x80;for (int j=0; j<8; j++){if (pSrc[i] & (mask >> j)){pBinaryArray[iter] = 1;}else{pBinaryArray[iter] = 0;}iter++;}}iter = 0;unsigned char profile_idc = *pSrc;int seq_parameter_set_id;offset = 24;ret = GolombDecode(pBinaryArray+offset, seq_parameter_set_id);offset += ret;if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144){int chroma_format_idc;ret = GolombDecode(pBinaryArray+offset, chroma_format_idc);offset += ret;if(chroma_format_idc == 3){offset += 1;}int bit_depth_luma_minus8, bit_depth_chroma_minus8;ret = GolombDecode(pBinaryArray+offset, bit_depth_luma_minus8);offset += ret;ret = GolombDecode(pBinaryArray+offset, bit_depth_chroma_minus8);offset += ret;offset += 2;bool seq_scaling_matrix_present_flag = pBinaryArray[offset];if (seq_scaling_matrix_present_flag){offset += 1;}}int log2_max_frame_num_minus4, pic_order_cnt_type;ret = GolombDecode(pBinaryArray+offset, log2_max_frame_num_minus4);offset += ret;ret = GolombDecode(pBinaryArray+offset, pic_order_cnt_type);offset += ret;if (pic_order_cnt_type == 0){int log2_max_pic_order_cnt_lsb_minus4;ret = GolombDecode(pBinaryArray+offset, pic_order_cnt_type);offset += ret;}else if (pic_order_cnt_type == 1){offset += 1;int offset_for_non_ref_pic, offset_for_top_to_bottom_field, num_ref_frames_in_pic_order_cnt_cycle, offset_for_ref_frame;ret = GolombDecode(pBinaryArray+offset, offset_for_non_ref_pic);offset += ret;ret = GolombDecode(pBinaryArray+offset, offset_for_top_to_bottom_field);offset += ret;ret = GolombDecode(pBinaryArray+offset, num_ref_frames_in_pic_order_cnt_cycle);offset += ret;for (int i=0; i<num_ref_frames_in_pic_order_cnt_cycle ;i++){ret = GolombDecode(pBinaryArray+offset, offset_for_ref_frame);offset += ret;}}int num_ref_frames;ret = GolombDecode(pBinaryArray+offset, num_ref_frames);offset += ret;offset += 1;int pic_width_in_mbs_minus1, pic_height_in_map_units_minus1;ret = GolombDecode(pBinaryArray+offset, pic_width_in_mbs_minus1);offset += ret;ret = GolombDecode(pBinaryArray+offset, pic_height_in_map_units_minus1);offset += ret;VideoWidth = (pic_width_in_mbs_minus1 + 1) * 16;VideoHeight = (pic_height_in_map_units_minus1 + 1) * 16;delete []pBinaryArray;pBinaryArray = NULL;return 0;}

In this way, the target is achieved, and the length and width of the video information are obtained.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.