I-frame data detection in MPEG-4 transport stream

I am testing a project. I need to break the payload data (making up several bytes of zero) of MPEG-4 ts packets by the percentage coming from the user. I do this by reading the ".ts" file package by package (188 bytes). But the video after the process changes to really dirt. (By the way, I am writing a program in C)

So I decided to find the data / packets belonging to the I-frames, and then did not touch them, but scrambled the other data as a percentage. I could find below

(in hexadecimal) 00 00 00 01 E0 start of the video packet PES .. .. 00 00 01 B8 start of the group of image headers .. .. 00 00 01 00 image start code. This is 32 bits. 10 bits immediately after this is called as a temporary reference. Thus, the temporary reference will include a byte after the image start code and the first two bits of the second byte after the image start code, that is, one byte (8 bits) + 2 bits. We need to skip. Now the three bits present (3, 4 and 5 bits of the second byte from the image start code) will indicate the type of frame, i.e. I, B or P. So, to get this is just a logical AND and the second byte from the image start code with 0x38 and the right shift → from 3.

For example, the data is:

00 00 01 00 00 0F FF F8 00 00 01 B5 ............ etc.

Here, the first four bytes 00 00 01 00 is the image start code. The fifth byte and the first two bits of the sixth byte are a temporary reference. Therefore, our concern is in the sixth byte → 0F

((0F & 38)>>3) 

Frame Type = 1 ==> I Frame

Frame type 000 prohibited

Frame type 001 intra-coded (I) - iframe

Frame Type 010 predictive-coded (P) - p-frame

Frame Type 011 Bidirectional Predictive (B) - b frame

But this is for MPEG-2. Are there some templates, so I recognize and get the frame type with bitwise operations for the MPEG-4 transport stream (extension -.ts)?

And I need to know how many bytes or packets belong to this frame?

Thank you very much for your help

+4
source share
2 answers

I would analyze the full TS package. Therefore, first determine which PID your video stream belongs to (by parsing PAT and PMT). Then find the keyframes by looking for the "Random Access" bit in the "Adaptation" field.

 uint8_t *pkt = <your 188 byte TS packet>; assert( 0x47 == pkt[0] ); int16_t pid = ( ( pkt[1] & 0x1F) << 8 ) | pkt[2]; if ( pid == video_pid ) { // found video stream if( ( pkt[3] & 0x20 ) && ( pkt[4] > 0 ) ) { // have AF if ( pkt[5] & 0x40 ) { // found keyframe } } } 
+5
source

If you use H.264, there must be a specific byte stream for frames i and P. Like 0x0000000165 for frame i and 0x00000001XX for frame P. So, just analyze and look for a continuous stream of bytes this way, you can identify me or the P-frame. Again, the byte stream depends on the implementation of the codec. For more information, you can look at FFMPEG ..

-one
source

Source: https://habr.com/ru/post/1501662/


All Articles