Analysis of key frame length and width in linuxc/C ++ programming BASICS (17) Video

Source: Internet
Author: User

1. The problem is described as follows:

During video development, before video playback, you usually have to determine the original length and width of the video to obtain the best visual effect with such length and width.

Otherwise, if the length or width is too large, it will cause distortion. If the length is too small, it is obviously unnecessary. The length and width of the video are usually stored after the algorithm is transformed.

The key frames of the video. Therefore, you need to parse them. For example, you need to provide the data of some video frames:




For example, in the development of Web Page YY, the video effect of http://yy.com/42431499/81208043 is as follows:


The length and width of the video of the beautiful girl must be parsed. Otherwise, the playback effect will be affected.


Reprinted please indicate the source: zhujian blog, http://blog.csdn.net/linyanwen99/article/details/8260199

2. Video key frame resolution, that is, the implementation of sps-parse.cpp, as follows:

# Include <stdlib. h>
# Include <stdint. h>
# Include <stdio. h>

Typedef uint8_t byte, uint8, uint8_bitmask;
Typedef uint16_t uint16, uint16_be, uint16_le;
Typedef int16_t sint16, sint16_be, sint16_le;
Typedef uint32_t uint32, uint32_be, uint32_le;
Typedef int32_t sint32, sint32_be, sint32_le;
Typedef struct _ uint24 {
Uint8 B [3];
} Uint24, uint24_be, uint24_le;
Typedef struct _ bit_buffer {
Byte * start;
Size_t size;
Byte * current;
Uint8 read_bits;
} Bit_buffer;
Static void skip_bits (bit_buffer * BB, size_t nbits ){
Bb-> current = BB-> current + (nbits + BB-> read_bits)/8 );
Bb-> read_bits = (uint8) (bb-> read_bits + nbits) % 8 );
}

/**

* The static uint8 get_bit (bit_buffer * bb) function reads each bit of a byte of BB and returns the result. The implementation is very simple. skip this step.

*/


/**

* The function static uint32 get_bits (bit_buffer * BB, size_t nbits) is equivalent to continuously reading the nbits of BB. If nbits is an integer multiple of 8, it is equivalent to reading several bytes.

* According to uint32, the value range of nbits is 0 ~ 32. The implementation is very simple. Skip it here.

*/

Reprinted please indicate the source: zhujian blog, http://blog.csdn.net/linyanwen99/article/details/8260199

Static uint32 exp_golomb_ue (bit_buffer * bb ){
Uint8 bit, significant_bits;
Significant_bits = 0;
Bit = get_bit (bb );
While (bit = 0 ){
Significant_bits ++;
Bit = get_bit (bb );
}
Return (1 <significant_bits) + get_bits (BB, significant_bits)-1;
}
Static sint32 exp_golomb_se (bit_buffer * bb ){
Sint32 ret;
Ret = exp_golomb_ue (bb );
If (Ret & 0x1) = 0 ){
Return-(Ret> 1 );
}
Else {
Return (Ret + 1)> 1;
}
}
Static void parse_scaling_list (uint32 size, bit_buffer * bb ){
Uint32 last_scale, next_scale, I;
Sint32 delta_scale;
Last_scale = 8;
Next_scale = 8;
For (I = 0; I <size; I ++ ){
If (next_scale! = 0 ){
Delta_scale = exp_golomb_se (bb );
Next_scale = (last_scale + delta_scale + 256) % 256;
}
If (next_scale! = 0 ){
Last_scale = next_scale;
}
}
}
/**
Parses a sps nalu to retrieve video width and height
*/
Static void parse_sps (byte * SPS, size_t sps_size, uint32 * width, uint32 * Height ){
Bit_buffer BB;
Uint32 profile, pic_order_cnt_type, width_in_mbs, height_in_map_units;
Uint32 I, size, left, right, top, bottom;
Uint8 frame_mbs_only_flag;
BB. Start = SPS;
BB. size = sps_size;
BB. Current = SPS;
BB. read_bits = 0;
/* Skip first byte, since we already know we're parsing a SPS */
Skip_bits (& BB, 8 );
/* Get profile */
Profile = get_bits (& BB, 8 );
/* Skip 4 bits + 4 zeroed bits + 8 bits = 32 bits = 4 bytes */
Skip_bits (& BB, 16 );
/* Read sps id, first exp-golomb encoded value */
Exp_golomb_ue (& bb );
If (profile = 100 | profile = 110 | profile = 122 | profile = 144 ){
/* Chroma format idx */
If (exp_golomb_ue (& bb) = 3 ){
Skip_bits (& BB, 1 );
}
/* Bit depth Luma minus8 */
Exp_golomb_ue (& bb );
/* Bit depth chroma minus8 */
Exp_golomb_ue (& bb );
/* Qpprime y zero transform bypass flag */
Skip_bits (& BB, 1 );
/* Seq scaling matrix present flag */
If (get_bit (& bb )){
For (I = 0; I <8; I ++ ){
/* Seq scaling list present flag */
If (get_bit (& bb )){
Parse_scaling_list (I <6? 16: 64, & bb );
}
}
}
}
/* Log2_max_frame_num_minus4 */
Exp_golomb_ue (& bb );
/* Pic_order_cnt_type */
Pic_order_cnt_type = exp_golomb_ue (& bb );
If (pic_order_cnt_type = 0 ){
/* Log2_max_pic_order_cnt_lsb_minus4 */
Exp_golomb_ue (& bb );
}
Else if (pic_order_cnt_type = 1 ){
/* Delta_pic_order_always_zero_flag */
Skip_bits (& BB, 1 );
/* Offset_for_non_ref_pic */
Exp_golomb_se (& bb );
/* Offset_for_top_to_bottom_field */
Exp_golomb_se (& bb );
Size = exp_golomb_ue (& bb );
For (I = 0; I <size; I ++ ){
/* Offset_for_ref_frame */
Exp_golomb_se (& bb );
}
}
/* Num_ref_frames */
Exp_golomb_ue (& bb );
/* Gaps_in_frame_num_value_allowed_flag */
Skip_bits (& BB, 1 );
/* Pic_width_in_mbs */
Width_in_mbs = exp_golomb_ue (& bb) + 1;
/* Pic_height_in_map_units */
Height_in_map_units = exp_golomb_ue (& bb) + 1;
/* Frame_mbs_only_flag */
Frame_mbs_only_flag = get_bit (& bb );
If (! Frame_mbs_only_flag ){
/* Mb_adaptive_frame_field */
Skip_bits (& BB, 1 );
}
/* Direct_8x8_inference_flag */
Skip_bits (& BB, 1 );
/* Frame_cropping */
Left = right = Top = Bottom = 0;
If (get_bit (& bb )){
Left = exp_golomb_ue (& bb) * 2;
Right = exp_golomb_ue (& bb) * 2;
Top = exp_golomb_ue (& bb) * 2;
Bottom = exp_golomb_ue (& bb) * 2;
If (! Frame_mbs_only_flag ){
Top * = 2;
Bottom * = 2;
}
}
/* Width */
* Width = width_in_mbs * 16-(left + right );
/* Height */
* Height = height_in_map_units * 16-(top + bottom );
If (! Frame_mbs_only_flag ){
* Height * = 2;
}
}

Reprinted please indicate the source: zhujian blog, http://blog.csdn.net/linyanwen99/article/details/8260199

Iii. Main function implementation:

Int main (){
File * fp = fopen ("./Pkt", "rb"); // Pkt indicates the video data given in
Int n = 0;
Byte C = 0;
Byte Buf [256] = {0 };
Uint32 width, height;

Fseek (FP, 0x0a, seek_set); // set the offset 0x0a from the begining of the file
Fread (& C, 1, 1, FP );
N | = (C <8 );
Fread (& C, 1, 1, FP );
N | = C;


Printf ("SPS Len: 0x % x \ n", N );
Fread (BUF, 1, n, FP );
Parse_sps (BUF, N, & width, & height );
Printf ("video width: % d \ n", width );
Printf ("video Height: % d \ n", height );

Return 0;
}

Note: The code is concise and clear. Note that it has been clicked out in the comments and will not be repeated here.


4. The running result is as follows:

Note: The figure shows that in the key frame of a video, the length and width of the video can be parsed by 0x18 bytes, that is, 24 bytes. Which 24 bytes are specific?

It can be seen from the main function that it is 24 bytes starting from the first row's 13th bytes (0x67 ).


Reprinted please indicate the source: zhujian blog, http://blog.csdn.net/linyanwen99/article/details/8260199

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.