how H264 (ES) packaged into H264 (PES)
has been on the internet to collect all kinds of information, heart tired ah. The following nine locks are very complicated for you to explain the unknown relationship between TS and H264. first, the overall general diagram
This I do not know is in which CSDN master that get the figure, helped me a lot of busy, on the picture time to:
How to encapsulate the PES data by ES data
1 , how to extract a frame es data, is so simple ...
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct {int S Tartcodeprefix_len; //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested) unsigned len; //! Length of the NAL unit (excluding the start code, which does not belong to the Nalu) unsigned max_size; //! Nal Unit Buffer size int forbidden_bit; //! Should is always FALSE int nal_reference_idc; //! nalu_priority_xxxx int nal_unit_type; //! Nalu_type_xxxx Char *buf; //! Contains the first byte followed by the EBSP unsigned short lost_packets; //!
True if packet loss is detected} nalu_t; FILE *bits = NULL; !< the bit stream file static int FindStartCode2 (unsigned char *buf);//Find start character 0x000001 static int FindStartCode3 (uns
igned char *buf);//Find start character 0x00000001//static bool flag = true;
static int info2=0, info3=0; Nalu_t *allocnalu (int buffersize) {nalu_t *n;
if (n = (nalu_t*) calloc (1, sizeof (nalu_t)) = = = NULL) {printf ("allocnalu:n");
Exit (0);
} n->max_size=buffersize;
if (N->buf = (char*) calloc (buffersize, sizeof (char)) = = = NULL) {free (n);
printf ("Allocnalu:n->buf");
Exit (0);
} return N;
} void Freenalu (nalu_t *n) {if (n) {if (n->buf) {free (N->BUF);
n->buf=null;
} free (n);
}} void Openbitstreamfile (char *fn) {if (NULL = = (Bits=fopen (FN, "RB"))) {printf ("Open File error\n");
Exit (0);
}} int Getannexbnalu (nalu_t *nalu) {int pos = 0;
int Startcodefound, rewind;
unsigned char *buf; if (Buf = (unsigned char*) calloc (nalu->max_size, sizeof (char)) = = NULL) printf ("Getannexbnalu:could not alloc
Ate Buf memory\n ");
The start character of the nalu->startcodeprefix_len=3;//initialization stream sequence is 3 bytes if (3! = Fread (Buf, 1, 3, BITS))//Read 3 bytes {free (BUF) from the bitstream;
return 0;
} Info2 = FindStartCode2 (BUF);//Determine if 0x000001 if (info2! = 1) {//if not, read one more byte if (1! = Fread (buf+3, 1, 1, BITS))//read one
bytes {free (BUF);
return 0;
} Info3 = FindStartCode3 (BUF);//Determine if 0x00000001 if (Info3! = 1)//If not, return-1 {free (BUF);
return-1;
} else {//If it is 0x00000001, get a start character of 4 bytes pos = 4;
Nalu->startcodeprefix_len = 4;
}} else{//if it is 0x000001, get the start character as 3 bytes Nalu->startcodeprefix_len = 3;
pos = 3;
} Startcodefound = 0;//finds the next start character's flag bit Info2 = 0;
Info3 = 0; while (!
Startcodefound) {if (feof (BITS))//Determines whether to the end of the file {Nalu->len = (pos-1)-nalu->startcodeprefix_len;
memcpy (Nalu->buf, &buf[nalu->startcodeprefix_len], Nalu->len);
Nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
NALU->NAL_REFERENCE_IDC = (nalu->buf[0]>>5) & 3;
Nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
Free (BUF); return pos-1; } buf[pos++] = fgetc (bits);//Read a byte to Buf Info3 = FindStartCode3 (&buf[pos-4]);//Determine if it is 0x00000001 if (info3! =
1) Info2 = FindStartCode2 (&buf[pos-3]);//Determine whether it is 0x000001 startcodefound = (Info2 = = 1 | | info3 = 1);
}//flag = false; Here, we had found another start code (and read length of Startcode bytes more than we should//had. Hence, go back in the file Rewind = (Info3 = = 1)?
-4:-3;
if (0! = fseek (Bits, rewind, seek_cur))///Put the file pointer back to the byte number of bytes {free (BUF);
printf ("Getannexbnalu:cannot fseek in the bit stream file");
}//Here's the start code, the complete Nalu, and the next start code are in the Buf. The size of Buf is POS, Pos+rewind is the number of bytes excluding the next/Start code, and (Pos+rewind)-startco
Deprefix_len is the size of the Nalu Nalu->len = (pos+rewind)-nalu->startcodeprefix_len;
memcpy (Nalu->buf, &buf[nalu->startcodeprefix_len], Nalu->len); Nalu->forbidden_bit = nalu->buf[0] & 0x80;
(nalu->buf[0]>>7) & 1; NALU->NAL_REFERENCE_IDC = nalu->buf[0] & 0x60;
(nalu->buf[0]>>5) & 3;
Nalu->nal_unit_type = (nalu->buf[0]) & 0x1f; /*write by Qiuliangbin of 2015-7-18 where is Rongle changsha*/if (nalu->nal_unit_type = = 7)//7 sequence parameter set 8 bytes {Prin
TF ("\ t NALU->RBSP->SPS->PROFILE_IDC (8):%d\n", nalu->buf[1]);
printf ("\ t Constraint_set0_flag (1):%d\n", (nalu->buf[2]>>7) & 1);
printf ("\ t Constraint_set1_flag (1):%d\n", (nalu->buf[2]>>6) & 1);
printf ("\ t Constraint_set2_flag (1):%d\n", (nalu->buf[2]>>5) & 1);
printf ("\ t Constraint_set3_flag (1):%d\n", (nalu->buf[2]>>4) & 1);
printf ("\ t Reserved_zero_4bits (4):%d\n", (nalu->buf[2]>>0) & 0x0f);
printf ("\ t LEVEL_IDC (8):%d\n", nalu->buf[3]); printf ("\ t seq_parameter_set_id (UE (V)): UVLC (1):%d\n", (nalu->buf[4]>>7) & 1);//indicates that the data in the future ignores the highest bit//Ignore the part according to PROFILE_IDC.
printf ("\ t LOG2_MAX_FRAME_NUM_MINUS4 (UE (v): len=5,value=%d\n", (nalu->buf[4]>>5) & 0x1f);
printf ("\ t Pic_order_cnt_type (UE (v)): len=3,value=%d\n", ((Nalu->buf[4]) & 0x03) <<1); Omit several parameters according to Pic_order_cnt_type printf ("\ t Num_ref_frames (UE): len=3,value=%d\n", (nalu->buf[5]>>4) & 0x07
);
printf ("\ t Gaps_in_frame_num_value_allowed_flag (1): value=%d\n", (nalu->buf[5]>>3) & 1); printf ("\ t pic_width_in_mbs_minus1-ue-:len=7, value=%d\n", ((((nalu->buf[5)) &0x07) <<4) |
(((nalu->buf[6) >>4) &0x0e)); printf ("\ t pic_height_in_map_units_minus1-ue-:len=7, value=%d\n", ((((nalu->buf[6)) &0x0f) <<3) | (
(((nalu->buf[7)) >>5)) (&0x06));
printf ("\ t Frame_mbs_only_flag (1):%d\n", (nalu->buf[7]>>4) & 1);
Ignore 1 printf ("\ t flag (4):%d\n", (Nalu->buf[7]) & 0x0f); } if (Nalu->nal_unit_type = = 8)//8 image parameter set 4 bytes {/* * * * CE---0110-forbidDen_zero_bit (1) = 0 NAL_REF_IDC (2) = one nal_unit_type (5) =01000:pic_parameter_set_rbsp (), 7.3.2.2//8 image parameter set 1100 PIC_PARAMETER_SET_ID (UE) =0 SEQ_PARAMETER_SET_ID (UE) =0 Entropy_coding_mode_flag (1): 0, important flag,0 denotes encoding Exp-golom
b coded and cavlc,1 represent Cabac Pic_order_present_flag (1): 0
1110 NUM_SLICE_GROUPS_MINUS1 (UE): 0
Ignore NUM_REF_IDX_L0_ACTIVE_MINUS1 (UE): 0 NUM_REF_IDX_L1_ACTIVE_MINUS1 (UE): 0 weighted_pred_flag (1); 0 0011 0000 WEIGHTED_BIPRED_IDC (2): xx pic_init_qp_minus26/* relative to *///(SE): 0//pic_init_qs_m
INUS26/* Relative to *///(SE): 0/* Chroma_qp_index_offset (SE): 0 deblocking_filter_control_present_flag (1); 0
Constrained_intra_pred_flag (1): 0 redundant_pic_cnt_present_flag (1): 0
Ignore Nalu end */} if (Nalu->nal_unit_type = = 5)//5 IDR Frame {} free (BUF);
return (pos+rewind);//Returns the number of bytes between two start characters} void dump (nalu_t *n) {if (!n) return;
printf ("A new nal:"); printf ("Len: %d ", N->len);
printf ("Nal_unit_type:%x\n", N->nal_unit_type);
} int main (int argc, char* argv[]) {openbitstreamfile ("./my.h264");
nalu_t *n;
n = Allocnalu (8000000);
while (!feof (bits)) {Getannexbnalu (n);
Dump (n);
} freenalu (n);
return 0; } static int FindStartCode2 (unsigned char *buf) {if (buf[0]!=0 | | buf[1]!=0 | | BUF[2]!=1) return 0;
Determine if it is 0x000001, if it returns 1 else return 1; } static int FindStartCode3 (unsigned char *buf) {if (buf[0]!=0 | | buf[1]!=0 | | BUF[2]!=0 | |
BUF[3]!=1) return 0;//determine if it is 0x00000001, if return 1 else return 1;
}
This is an example of a pure C language and should be well understood, in no case. Next there will be more fierce material, please look forward to, feel good can pay attention to the next ...