H264 i/p/b Frame Type Judging __ Streaming media

Source: Internet
Author: User
Tags bitwise bitwise operators

Turn from: http://blog.csdn.net/zhuweigangzwg/article/details/44152239


Here is the first description of the structure of the H264:

01/00 01->nal (1bytes)->slice-> macro block-> motion estimation vector.

If a prefix appears in the body of H264, it is changed from 00 00 00 01/00 00 01 to 00 03 00 00 01/00 03 00 01.

We see commonly used naltype like sps= 0x07 pps= 0x08 sei = 0x06 i/p/b= that is to say only judge 0x01/0x05 = Naltype is not judged 0x01/0x05 frame type, need to go to the i/p/b layer to judge the use of "Entropy Code" specific "Entropy coding" content please see: "H.264 official Chinese version. pdf".

The following is the deduction of the FFmpeg source to determine the i/p/b frame type implementation:

int GetFrameType (nalu_t * nal) {bs_t s; 
	int frame_type = 0;
	unsigned char * oneframebuf_h264 = NULL;  if ((oneframebuf_h264 = (unsigned char *) calloc (Nal->len + 4,sizeof (unsigned char)) = = NULL) {printf ("Error malloc
		Oneframebuf_h264\n ");
	return GetChar ();
		} if (Nal->startcodeprefix_len = = 3) {oneframebuf_h264[0] = 0x00;
		ONEFRAMEBUF_H264[1] = 0x00;
		ONEFRAMEBUF_H264[2] = 0x01;
	memcpy (oneframebuf_h264 + 3,nal->buf,nal->len);
		else if (Nal->startcodeprefix_len = = 4) {oneframebuf_h264[0] = 0x00;
		ONEFRAMEBUF_H264[1] = 0x00;
		ONEFRAMEBUF_H264[2] = 0x00;
		ONEFRAMEBUF_H264[3] = 0x01;
	memcpy (oneframebuf_h264 + 4,nal->buf,nal->len); else {printf ("H264 read error.
	\ n ");


	} bs_init (&s,oneframebuf_h264 + nal->startcodeprefix_len + 1, nal->len-1); if (Nal->nal_unit_type = = Nal_slice | | nal->nal_unit_type = = NAL_SLICE_IDR) {/* I_FIRST_MB/Bs_read_ue (&A
		Mp;s); /* Picture Type */Frame_type = Bs_read_ue ( &s);
			Switch (frame_type) {case 0:case 5:/* P */nal->frametype = frame_p;
		Break
			Case 1:case 6:/* B */nal->frametype = Frame_b;
		Break
			Case 3:case 8:/* SP */nal->frametype = frame_p;
		Break
			Case 2:case 7: * I/* Nal->frametype = frame_i;
			I_frame_num + +;
		Break
			Case 4:case 9:/* SI * * Nal->frametype = frame_i;
		Break
	} else if (Nal->nal_unit_type = Nal_sei) {nal->frametype = Nal_sei;
	else if (Nal->nal_unit_type = = Nal_sps) {nal->frametype = Nal_sps;
	else if (Nal->nal_unit_type = = Nal_pps) {nal->frametype = Nal_pps;
		} if (oneframebuf_h264) {free (oneframebuf_h264);
	oneframebuf_h264 = NULL;
return 1; }


H264 A frame data structure typedef struct TAG_NALU_T {unsigned char forbidden_bit; //!       Should always be FALSE unsigned char nal_reference_idc; //!           nalu_priority_xxxx unsigned char nal_unit_type; //!      nalu_type_xxxx unsigned int startcodeprefix_len; //!                     Prefix byte count unsigned int len; //!                Contains the nal length of the nal head, from the first 00000001 to the next 000000001 length unsigned int max_size; //!                   Up to one nal length unsigned char * BUF; //!               NAL data containing nal headers unsigned char frametype; //!            frame type unsigned int lost_packets; //!

Reserve} nalu_t; NAL type enum Nal_unit_type_e {nal_unknown = 0, Nal_slice = 1, NAL_SLICE_DPA = 2, NAL_SLICE_DPB = 3, NA         L_SLICE_DPC = 4, NAL_SLICE_IDR = 5,/* REF_IDC!= 0/Nal_sei = 6,/* REF_IDC = 0/Nal_sps

= 7, Nal_pps = 8/* REF_IDC = 0 for 6,9,10,11,12 */}; Frame type enum Frametype_e {frame_i = Frame_p =, Frame_b = 17};

Mybs.h #pragma once #include "Information.h"/read byte structure typedef struct TAG_BS_T {unsigned char *p_start;			           The first address of the buffer (this start is the lowest address) unsigned char *p;		           Buffer currently reads and writes the current byte of the address, this will be constant + +, each + +, into a new byte unsigned char *p_end;
	Buffer tail address//typedef unsigned char uint8_t;				           int i_left;		


How many "bits" of the byte currently in the P refer to read and write to count number of available (available) bit}bs_t;

/* Function Name: function function: Initialization structure parameters: return value: No return value, void type mentality: data: * * void Bs_init (bs_t *s, void *p_data, int i_data); /* The function is: reads out the i_count bit from S and makes it the uint32_t type return idea: If I_count>0 and the S stream does not end, start or continue reading the stream; If s current byte remains more than equal to the number of digits to be read I_count, direct read
If s current byte is less than the number of digits to read I_count, the remaining bits are read, and the next byte is read into S.
	Add: When writing S, I_left indicates the bit of s current byte has not been written, and if a new byte is i_left=8, the i_left indicates the bit that s current byte has not been read, if a new byte, then i_left=8.

	Notice the difference and connection between the two.
	00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000-------------000 00000000 ... When written to S: I_left = 3 Read s: i_left = 5 I think: the stream of bytes in advance in the structure of the Bs_s object bs_t, it may not be a one-time reading/analysis of the byte streamFinish, but according to need, every time read a few bits of bs_s, there is a special field to record the results of historical reading, each read, in the last read position for example, 100 bytes of the stream, after several reads, the current position in the middle of a byte, the first 3 bits have been read, This time to read the 2-bit 00001001 000 01 001 (read after this secondary read) I_count = 2 (scheduled to read 2 bits) I_left = 5 (There are 5 bits unread, in this byte) I_shr = s->i_l Eft-i_count = 5-2 = 3 *s->p >> i_shr, move this secondary read bit to the rightmost byte (unread, but not needed to move to byte, throw out) 00000001 I_mask[i_count] that is i_ MASK[2] 0x03:00000011 (*s->p >> i_shr) &i_mask[i_count]; That is, 00000001 & 00000011, which is the 00000001 bitwise AND 00000011 result is: 00000001 i_result |= (*s->p >> i_shr) &i_mask[i_coun T]; I_result |=00000001 is I_result =i_result | 00000001 = 00000000 00000000 00000000 00000000 | 00000001 =00000000 00000000 00000000 00000001 i_result = return (I_result);

The returned I_result is a 4-byte length, is the unsigned type sizeof (unsigned) =4/int Bs_read (bs_t *s, int i_count);
/* Function Name: function function: Read 1 bits from S, and return it as uint32_t type.	Function parameter: Return value: Thought: If the S stream does not end, read a data: Bihoujie: Page 145th, U (n)/U (v), read a number of consecutive bits, and interpret them as "unsigned int" return i_result; unsigned int */int bs_read1 (bs_t *s); /* Function Name: function function: Decoding and reading a syntax element value parameter from S: Return value: Train of thought: reads and counts from the current bit of s, until read to 1; while (bs_read1 (s) = 0 && s->
		P < s->p_end && I < 32 this loop uses I to record the number of 0 of s current position to 1 and discards the first 1 read, and returns 2^i-1+bs_read (S,i). Example: When the s byte is stored in 0001010, 1 before 3 0, so i=3; return: 2^i-1+bs_read (s,i): 8-1+010=9 Data: Bihoujie: Page 145th, UE (v), unsigned exponential golomb entropy encoding x264 BS. A partial function Interpretation of H-file http://wmnmtm.blog.163.com/blog/static/382457142011724101824726/unsigned integer exponent Columbus code encoding http://

 wmnmtm.blog.163.com/blog/static/38245714201172623027946/*/int Bs_read_ue (bs_t *s);

Mybs.cpp #include "Mybs.h" void Bs_init (bs_t *s, void *p_data, int i_data) {S->p_start = (unsigned char *) p_data		;		Initializes the P_start with the incoming P_data first address, noting only the first address of the valid data S->p = (unsigned char *) p_data;	                The first address of the byte, initially initialized with P_data, each reading an entire byte, moves to the next byte first address s->p_end = S->p + i_data;
	Tail address, last byte's first address?				                S->i_left = 8;
                                  Read-write has not started, the current byte remaining unread bit is 8} int bs_read (bs_t *s, int i_count) {static int i_mask[33] ={0x00,
                                  0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xFF, 0X1FF, 0X3FF, 0x7ff, 0xfff, 0X1FFF, 0x3
                                  FFF, 0X7FFF, 0xFFFF, 0x1ffff, 0x3ffff, 0X7FFFF, 0XFFFFF, 0X1FFFFF, 0x3fffff, 0x7fffff, 0xFFFFFF, 0x1ffffff, 0X3FFFFFF, 0X7FFFFF
                   F, 0xFFFFFFF,               0X1FFFFFFF,0X3FFFFFFF,0X7FFFFFFF,0XFFFFFFFF}; /* The elements in the array are represented in binary notation as follows: assumption: Initially 0, written as +, read as-bytes: 1 2 3 4 00000000 00000000 00000000 00000000							  Superscript 0x00:00000000 x[0] 0x01:00000001 x[1] 0x03:00000011 x[2] 0x07:
			  00000111 x[3] 0x0f:00001111 x[4] 0x1f:00011111 x[5] 0x3f:00111111 x[6]						 0x7f:01111111 x[7] 0xff:11111111 x[8] 1 bytes 0x1ff:0001 11111111 x[9] 0x3ff:	0011 11111111 x[10] i_mask[s->i_left] 0x7ff:0111 11111111 x[11] 0xfff:1111 11111111 x[12] 		1.5 bytes 0x1fff:00011111 11111111 x[13] 0x3fff:00111111 11111111 x[14] 0x7fff:01111111 11111111  X[15] 0xffff:11111111 11111111 x[16] 2 bytes 0x1ffff:0001 11111111 11111111 x[17] 0x3ffff:0011 11111111 11111111 x[18] 0x7ffff:0111 11111111 11111111 x[19] 0xFFFFf:1111 11111111 11111111 x[20] 2.5 bytes 0x1fffff:00011111 11111111 11111111 x[21] 0x3fffff:00111111 1111 1111 11111111 x[22] 0x7fffff:01111111 11111111 11111111 x[23] 0xffffff:11111111 11111111 11111111 x[24] 3 byte 0x1ffffff:0001 11111111 11111111 11111111 x[25] 0x3ffffff:0011 11111111 11111111 11111111 x[26] 0x7 ffffff:0111 11111111 11111111 11111111 x[27] 0xfffffff:1111 11111111 11111111 11111111 x[28] 3.5 bytes 0x1ffff fff:00011111 11111111 11111111 11111111 x[29] 0x3fffffff:00111111 11111111 11111111 11111111 x[30] 0x7fffffff:011111 			    One 11111111 11111111 11111111 x[31] 0xffffffff:11111111 11111111 11111111 11111111] 4 bytes */int x[32;	        int i_result = 0;

    Used to store the results of the reading of the typedef unsigned uint32_t;
        while (I_count > 0)///The number of bits to read {if (s->p >= s->p_end)//byte stream at the end of the current position, that represents this bit stream s has been read.
        {//break; } if (I_SHR = S->i_left-i_count) >= 0//////////////////////////////////////////////////// The result of a bit, i_shr=i_left-i_count, if >=0, indicates that the read is in the current byte//i_shr>=0, indicating that the bits to be read are in the current byte//This stage, once read, and then return to I_resul T (quit function)/* More in the buffer than requested/I_result |= (*s->p >> i_shr) &i_mas k[i_count];//"|=": Bitwise OR assignment, a |= B is a = a| B//|= should be executed at the end, placing the result in the I_result (bitwise and priority above the composite operator |=)//i_mask[i_count] The rightmost are all 1, with the bitwise in brackets, you can copy the result in brackets. /!=, the left side of the i_result here are all 0, to the right with it bitwise OR, or copy the results come over, as if several steps are redundant//read, update the structure of the field value/s->i_left-= I_count; That is, I_left = I_left-i_count, the remaining unread digits of the current byte, the original minus the IF (s->i_left = 0)///If the current byte remaining unread digits is exactly 0, indicating that the current byte is read, it is time to start				Next byte {s->p++;		Move the pointer, so p is like S->i_left = 8, which moves the pointer in byte increments;		The new starting byte, the number of unread digits remaining in the current byte, is 8-bit} return (I_result); One of the possible return values is: 00000000 00000000 00000000 00000001 (4 bytes long)
        else//I_SHR < 0, cross-byte situation/{//This phase, is a while loop, may also go to the next cycle, the first and last time can read the non whole byte, such as the first read 3 Special, 2 bytes (ie 2x8 bits) were read in the middle, last read 1 bits, then exit the while loop//current byte remaining unread digits, less than the number of bits to read, such as the current byte has 3 bits unread, and this secondary read 7 bit//??? For the current byte, the bits to be read are at the far right, so they are no longer shifted (the purpose of the shift is to place the bits to be read at the right of the current byte)/* Less (less) in the buffer than requested * * I_result |=	(*s->p&i_mask[s->i_left]) <<-i_shr; "-i_shr" is equivalent to taking the absolute value of//|= and << are bitwise operators, the same priority, so from left to right in order to execute//example: Int|char, where int is 4 bytes, char is 1 bytes, sizeof (int|	char) is 4 bytes//i_left maximum is 8, the smallest is 0, the value range is [0,8] I_count = s->i_left;	The number of bits to be read equals the original I_count minus I_left,i_left is the number of bits that are not read by the current byte, and this else stage, the i_left represents the current byte of the unread bits are read, so subtract it s->p++;	Navigates to the next new byte S->i_left = 8;  For a new byte, the number of unread digits is, of course, 8, that is, none of the bits in this byte has read} return (I_result);//One of the possible returned values is: 00000000 00000000 00000000 00000001

		(4 bytes long)} int bs_read1 (bs_t *s) {if (S->p < s->p_end) {unsigned int i_result;                           s->i_left--; The current byte is notThe number of bits read is less than 1 bits I_result = (*s->p >> s->i_left) &0x01;//to move the bits to be read to the right of the current byte, and then logic and operation with 0X01:00000001, because only a bit is to be read , this bit is not 0 is 1, with 0000 0001 bitwise with can know this condition if (S->i_left = = 0)//If the current byte remaining unread digits is 0, that is to say that the current byte is all read {s->p+			                   +;                     The pointer s->p moves to the next byte S->i_left = 8;                       In the new byte, the number of unread digits is of course 8-bit} return i_result;                                  unsigned int} return 0;

	Return 0 should be not read something} int bs_read_ue (bs_t *s) {int i = 0;
		while (Bs_read1 (s) = = 0 && s->p < s->p_end && I < 32)//condition: Read the current bit = 0, the pointer is not out of bounds, can only read 32 bits {
	i++;	
Return ((1 << i)-1 + bs_read (s, i)); }



Related Article

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.