=====================================================
Audio-visual data Processing Primer series articles:
Getting started with visual audio data processing: RGB, YUV pixel data processing
Getting Started with AV data processing: PCM Audio sampling data processing
Getting Started with AV data processing: Analysis of video stream in H.
Getting Started with AV data processing: AAC audio bitstream parsing
Getting Started with AV data processing: FLV Encapsulation Format parsing
Getting Started with AV data processing: UDP-RTP Protocol resolution
=====================================================
The first two articles introduced the Audio stream processing program and the video stream processing program, this article describes the data after they are packaged together--the processing program that encapsulates the format data. The location of the encapsulated format data in the video player is as follows.
The program in this article is an FLV Encapsulation Format resolver. The program can parse from FLV to get its basic unit tag, and can simply parse the field of the tag header. Different FLV format data processing functions can be implemented by modifying the program.
Principle
The FLV Encapsulation format consists of an FLV header file head and a single tag. The tag contains audio data as well as video data. The structure of the FLV is as shown.
The format for FLV is no longer recorded in this article. can refer to the article "Video Audio Codec Learning project: FLV Encapsulation Format Analyzer." The program of this paper realizes the parsing of FLV header and tag in FLV, and can separate the audio stream.
The code throughout the program is in the Simplest_flv_parser () function, as shown below.
/** * Simplest audio-visual data processing example * Simplest mediadata Test * * Lei hua Lei Xiaohua * [email protected] * Communication University/Digital TV Technology * Communication University of China/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This project contains the following examples of audio and visual testing: * (1) pixel data processing program. Functions that contain RGB and YUV pixel format processing. * (2) Audio sampling data processing program. A function that contains the processing of PCM audio sampling format. * (3) The Code stream analysis program. Nalu can be detached and parsed. * (4) AAC Code Stream analysis program. Adts frames can be detached and parsed. * (5) FLV Encapsulation Format analysis program. You can separate the MP3 audio stream from the FLV. * (6) UDP-RTP Protocol analysis program. You can analyze the udp/rtp/mpeg-ts packets. * * This project contains following samples to handling multimedia data: * (1) Video pixel data handling program. It contains several examples to handle RGB and YUV data. * (2) Audio Sample data Handling program. It contains several examples to handle PCM data. * (3) H. Stream Analysis program. It can parse H. bitstream and analysis Nalu of stream. * (4) AAC Stream analysis program. It can parse AAC bitstream and analysis ADTS frame of stream. * (5) FLV format analysis program. It can analysis FLV file and extract MP3 audio stream. * (6) UDP-RTP Protocol Analysis Program. It can analysis Udp/rtp/mpeg-ts Packet. * */#include <stdio.h> #include <stdlib.h> #include <string.h>//important! #pragma pack (1) #define TAG _type_script 18#define tag_type_audio 8#define tag_type_video 9typedef unsigned char byte;typedef unsigned int uint;type def struct {byte signature[3];byte version;byte flags;uint dataoffset;} flv_header;typedef struct {byte tagtype;byte datasize[3];byte timestamp[3];uint Reserved;} Tag_header;//reverse_bytes-turn a Bigendian byte array into a Littleendian integeruint reverse_bytes (Byte *p, char c) {i NT R = 0;int i;for (i=0; i<c; i++) R |= (* (P+i) << (((c-1) *8) -8*i); return r;} /** * Analysis flv file * @param the URL location of the input FLV file. */int Simplest_flv_parser (char *url) {//whether output audio/video streamint output_a=1;int output_v=1;//------------- FILE *ifh=null,*vfh=null, *afh = Null;//file *myout=fopen ("Output_log.txt", "wb+"); FILE *myout=stdout; Flv_header flv; Tag_header TaghEader;uint previoustagsize, Previoustagsize_z=0;uint ts=0, ts_new=0;ifh = fopen (URL, "rb+"), if (ifh== NULL) {printf ("Fai led to open files! "); return-1;} FLV file Headerfread ((char *) &flv,1,sizeof (flv_header), IFH); fprintf (Myout, "============== flv HEADER ========= =====\n "); fprintf (Myout," signature:0x%c%c%c\n ", flv. signature[0],flv. signature[1],flv. SIGNATURE[2]); fprintf (Myout, "version:0x%x\n", flv. Version); fprintf (Myout, "flags:0x%x\n", flv. Flags); fprintf (Myout, "headersize:0x%x\n", Reverse_bytes ((BYTE *) &flv. Dataoffset, sizeof (FLV). Dataoffset)) fprintf (Myout, "========================================\n");//move the file pointer to the end of the Headerfseek (IFH, Reverse_bytes (BYTE *) &flv. Dataoffset, sizeof (FLV). Dataoffset), Seek_set)//process each Tagdo {previoustagsize = _GETW (IFH); Fread ((void *) &tagheader,sizeof (tag_ HEADER), 1,IFH);//int temp_datasize1=reverse_bytes ((BYTE *) &tagheader. DataSize, sizeof (Tagheader. datasize)); int Tagheader_datasize=tagheAder. Datasize[0]*65536+tagheader. Datasize[1]*256+tagheader. Datasize[2];int Tagheader_timestamp=tagheader. Timestamp[0]*65536+tagheader. Timestamp[1]*256+tagheader. Timestamp[2];char Tagtype_str[10];switch (Tagheader. Tagtype) {case tag_type_audio:sprintf (tagtype_str, "AUDIO") break;case tag_type_video:sprintf (tagtype_str, "VIDEO") ; Break;case tag_type_script:sprintf (Tagtype_str, "SCRIPT"); break;default:sprintf (Tagtype_str, "UNKNOWN"); break;} fprintf (Myout, "[%6s]%6d%6d |", Tagtype_str,tagheader_datasize,tagheader_timestamp);//if we is not past the end of file, Process the Tagif (feof (IFH)) {break;} Process tag by Typeswitch (Tagheader. Tagtype) {case tag_type_audio:{char audiotag_str[100]={0};strcat (audiotag_str, "| "); Char tagdata_first_byte;tagdata_first_byte=fgetc (IFH); int X=tagdata_first_byte&0xf0;x=x>>4;switch (x {Case 0:strcat (audiotag_str, "Linear PCM, Platform endian"), Break;case 1:strcat (audiotag_str, "ADPCM"); Break;case 2: strcat (Audiotag_str, "MP3"); Break;case 3:strcat (audiotag_sTR, "Linear PCM, Little Endian"); Break;case 4:strcat (Audiotag_str, "Nellymoser 16-khz Mono"); Break;case 5:strcat ( Audiotag_str, "Nellymoser 8-khz Mono"), Break;case 6:strcat (audiotag_str, "Nellymoser"); Break;case 7:strcat (audiotag_ STR, "g.711 A-law logarithmic pcm"), Break;case 8:strcat (audiotag_str, "g.711 Mu-law logarithmic pcm"); Break;case 9: strcat (AUDIOTAG_STR, "reserved"); Break;case 10:strcat (Audiotag_str, "AAC"); break;case 11:strcat (Audiotag_str, " Speex "); break;case 14:strcat (Audiotag_str," MP3 8-khz "); break;case 15:strcat (Audiotag_str," device-specific sound "); Break;default:strcat (Audiotag_str, "UNKNOWN"); strcat (Audiotag_str, "| "); X=tagdata_first_byte&0x0c;x=x>>2;switch (x) {case 0:strcat (audiotag_str," 5.5-khz "); Break;case 1: strcat (Audiotag_str, "1-khz"); break;case 2:strcat (Audiotag_str, "22-khz"); break;case 3:strcat (Audiotag_str, "44-kHz "); Break;default:strcat (Audiotag_str," UNKNOWN "); break;} strcat (Audiotag_str, "| "); X=tagdata_first_byte&0x02;x=x>>1;switch (x) {case 0:STRCat (Audiotag_str, "8Bit"); break;case 1:strcat (Audiotag_str, "16Bit"); Break;default:strcat (Audiotag_str, "UNKNOWN") ; break;} strcat (Audiotag_str, "| "); X=tagdata_first_byte&0x01;switch (x) {case 0:strcat (audiotag_str," Mono "); break;case 1:strcat (Audiotag_str," Stereo "); Break;default:strcat (Audiotag_str," UNKNOWN "); fprintf (Myout, "%s", audiotag_str);//if the output file hasn ' t been opened, open it.if (output_a!=0&&afh = = NULL) { AFH = fopen ("Output.mp3", "WB");} Tagdata-first Byte dataint data_size=reverse_bytes ((Byte *) &tagheader. DataSize, sizeof (Tagheader. datasize)) -1;if (output_a!=0) {//tagdata+1for (int i=0; i<data_size; i++) FPUTC (fgetc (IFH), AFH);} else{for (int i=0; i<data_size; i++) fgetc (IFH);} break;} Case Tag_type_video:{char Videotag_str[100]={0};strcat (videotag_str, "| "); Char tagdata_first_byte;tagdata_first_byte=fgetc (IFH); int X=tagdata_first_byte&0xf0;x=x>>4;switch (x {Case 1:strcat (VIDEOTAG_STR, "key frame") Break;case 2:strcat (videotag_str, "Inter FramE "); Break;case 3:strcat (VIDEOTAG_STR," disposable Inter Frame "); Break;case 4:strcat (Videotag_str," generated keyframe "); Break;case 5:strcat (Videotag_str," video Info/command Frame "); Break;default:strcat (Videotag_str," UNKNOWN "); break;} strcat (Videotag_str, "| "); X=tagdata_first_byte&0x0f;switch (x) {case 1:strcat (videotag_str," JPEG (currently unused) "); Break;case 2: strcat (Videotag_str, "Sorenson h.263"); break;case 3:strcat (videotag_str, "screen video"); Break;case 4:strcat ( Videotag_str, "On2 VP6"); break;case 5:strcat (Videotag_str, "On2 VP6 with alpha channel"); Break;case 6:strcat (videotag_ STR, "screen video version 2"); Break;case 7:strcat (Videotag_str, "AVC"); Break;default:strcat (Videotag_str, "UNKNOWN") ; break;} fprintf (Myout, "%s", videotag_str); Fseek (IFH,-1, seek_cur);//if the output file hasn ' t been opened, open it.if (VFH = = NULL &&output_v!=0) {//write The FLV header (reuse the original file ' s HDR) and first PREVIOUSTAGSIZEVFH = fopen ("Outpu t.flv "," WB "); fwrite (char *) &flv,1, SizeoF (FLV), VFH); fwrite ((char *) &previoustagsize_z,1,sizeof (previoustagsize_z), VFH);} #if 0//change Timestamp//get timestampts = reverse_bytes ((BYTE *) &tagheader. Timestamp, sizeof (Tagheader. Timestamp)); Ts=ts*2;//writeback timestampts_new = Reverse_bytes ((BYTE *) &ts, sizeof (TS)); memcpy (&tagheader. Timestamp, ((char *) &ts_new) + 1, sizeof (Tagheader. Timestamp)); #endif//tagdata + Previous Tag sizeint data_size=reverse_bytes ((BYTE *) &tagheader. DataSize, sizeof (Tagheader. datasize)) +4;if (output_v!=0) {//tagheaderfwrite ((char *) &tagheader,1, sizeof (Tagheader), VFH);//tagdatafor (int i=0; i<data_size; i++) FPUTC (fgetc (IFH), VFH);} else{for (int i=0; i<data_size; i++) fgetc (IFH);} Rewind 4 bytes, because we need to read the previoustagsize again for the Loop ' s Sakefseek (IFH, -4, seek_cur); Default://skip the data of this tagfseek (IFH, Reverse_bytes (BYTE *) &tagheader. DataSize, sizeof (Tagheader. datasize)), seek_cur);} fprintf (myout, "\ n");} while (!feof (IFH)); _fcloseAll (); return 0;}
The function call method above is shown below.
Simplest_flv_parser ("cuc_ieschool.flv");
Results
The input of this program is an FLV file path, output as an FLV statistic, as shown in.
In addition, this program can also separate the video stream and audio stream in FLV. It is important to note that this program does not separate certain types of audio (such as AAC) and video, and this work needs to be completed later.
Download
Simplest mediadata test
Project Home
sourceforge:https://sourceforge.net/projects/simplest-mediadata-test/
Github:https://github.com/leixiaohua1020/simplest_mediadata_test
Open source China: http://git.oschina.net/leixiaohua1020/simplest_mediadata_test
csdn:http://download.csdn.net/detail/leixiaohua1020/9422409
This project contains several examples of audio and visual data parsing:
(1) Pixel data processing program. Functions that contain RGB and YUV pixel format processing.
(2) Audio sampling data processing program. A function that contains the processing of PCM audio sampling format.
(3) The Code Stream analysis program for H. Nalu can be detached and parsed.
(4) AAC Stream Analysis Program. Adts frames can be detached and parsed.
(5) FLV Encapsulation Format parser. You can separate the MP3 audio stream from the FLV.
(6) UDP-RTP Protocol Analysis Program. You can analyze the udp/rtp/mpeg-ts packets.
Rai (Lei Xiaohua)
[Email protected]
http://blog.csdn.net/leixiaohua1020
Getting Started with AV data processing: FLV Encapsulation Format parsing