FMUSER Wirless Transmit Video And Audio More Easier !

[email protected] WhatsApp +8618078869184
Language

    H.264 decoding process analysis - 4

     

    The X264 open source project implements the video encoding of H.264, but does not provide a corresponding decoder. FFMPEG Open Source Multimedia Codes Collect the source code of almost all media formats on the market. The H264.c is a separate source file that can normally decode X264 encoded stream, which is also basically the same as the above-described encoding or decoding CODEC application case. This section describes how H264.C implements the H.264 video decoding process. H264.C source files have thousands of lines, the amount of code is large, it is very inconvenient to browse, analyze and transplant. At the same time, the document also rely on other source files, the organizational structure is more complex, and the platform is not based on Windows-based VC ++, which has brought a lot of inconveniences to compile, tracking. The "Chapter7 \ FFMPEG_H264" directory in the disc exhibits a project case "FFMPEG_H264" extracted from the C language extracted from FFMPEG. The file function classification of "FFMPEG_H264" is clear, compiled under the VC ++ 2005 platform, and the support of MMX, pure C language project facilitates the transplant of the embedded platform. The following is starting from the main function, step-in analysis of the process of implementing the H.264 video decoding. FFMPEG_H264 Project1 decoded the main program Function main implementation of H.264 video decoding console applications, including all processes of the solution work. Its function call relationship is shown in the figure. These applications, the topology of the process with the aforementioned MPEG-1 video decoding process is basically the same, including avcodec_init, avcodec_register_all, avcodec_find_decoder, avcodec_all_context, avcodec_open, avcodec_all_frame, avcodec_decode_video, avcodec_close like ffmpeg of several common module, wherein avcodec_decode_video is a decoder The core is marked in the figure. The code of the main function is implemented as follows: Int main () { FILE * INP_FILE; FILE * OUT_FILE; INT I; INT NALLEN; / * NAL length * / Unsigned char * buf; / *h.264 code stream * / INT got_picture; / * Decoding a frame image * / INT consumed_bytes; / * The code stream length consumed by the decoder * / INT CNT = 0; Avcodec * CODEC; / * Codes CODEC * / AvcodecContext * c; / * Codes CODEC Context * / Avframe * Picture; / * Decoded image * / / * Output and output files * / INP_FILE = FOPEN ("E: \\ Bitavc \\ Busn_Dsp.264", "RB"); OUT_FILE = FOPEN ("E: \\ BitAvc \\ DSP_DEC.YUV", "WB"); Nallen = 0; / * Allocate memory and initialize 0 * / BUF = (unsigned char *) Calloc (500 * 1024, sizeof (char)); / * Initialization of CODEC, initialize some constant tables * / Avcodec_init (); / * Register CODEC * / AVCODEC_REGISTER_ALL (); / * Find H264 CODEC * / CODEC = AVCODEC_FIND_DECODER (CODEC_ID_H264); IF (! CODEC) Return 0; / * Initialize the default parameters of CODEC * / C = AVCODEC_ALLOC_CONTEXT (); IF (! c) Return 0;/ * 1. Open CODEC, here is initialized H.264 decoder, call DECODE_INIT local functions * / IF (AVCODEC_OPEN (C, CODEC) <0) Return 0; / * Application space for Avframe, and clear * / Picture = avcodec_alloc_frame (); IF (! Picture) Return 0; / * Cyclic decoding * / While (! feof) { / * Get a NAL package from the code stream * / Nallen = getNexTnal (INP_FILE, BUF); / * 2. NAL decoding, call DECODE_FRAME Local Function * / ConsuMed_bytes = avcodec_decode_video (C, Picture, & Got_Picture, BUF, NALLEN); CNT ++; / * Output current decoding information * / Printf ("NO: =% 4D, Length =% 4D \ n", CNT, ConsuMed_bytes; / * Returns <0 Indicates the decoded data head, returns> 0, indicating the decoding frame image * / IF (consumed_bytes> 0) { / * Extract the decoded image from the two-dimensional space * / For (i = 0; i height; i ++) FWRITE (Picture-> Data [0] + i * Picture-> LineSize [0], 1, c-> width, out_file; For (i = 0; i height / 2; i ++) FWRITE (Picture-> Data [1] + i * Picture-> LineSize [1], 1, C-> width / 2, out_file; For (i = 0; i height / 2; i ++) FWRITE (Picture-> Data [2] + i * Picture-> LineSize [2], 1, C-> Width / 2, Out_File; / * Close the file * / IF (INP_FILE) Fclose (INP_FILE); IF (out_file) fclose (out_file); / * 3. Turn off CODEC, release resources, call DECODE_END local function * / IF (c) { AVCODEC_CLOSE (C); AV_FREE (C); C = NULL; } / * Release AVFrame Space * / IF (Picture) { AV_Free (Picture); Picture = NULL; } / * Release memory * / IF (buf) { Free (BUF); BUF = NULL; } Return 0;} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 In the above process, steps 1 to 8 are the basic steps of FFmPEG at coding or decoding. The feature of the analysis function name will find that CODEC's processing function is prefixed as "AVCODEC_". In order to use the H.264 decoder CODEC, first need to define CODEC, as shown below: AVCODEC H264_DECODER = { "H264", // decoder name CODEC_TYPE_VIDEO, // Decoder Type, Video CODEC_ID_H264, // Decoder ID SizeOf (H264Context), // decoder context Decode_init, // decoder initialization NULL, / / ​​Encoder, disabled Decode_end, // Destroy the decoder Decode_frame, // decoding 0, // CODEC compatibility, disabled }; 1234567891011 Therefore, the actual decoding processing module is implemented with DECODE_INIT, DECODE_FRAME, DECODE_END. Use a public function interface in the main function to access the functions here. Examples, for example, register CODEC. / ** * Simple call to register all the codecs. * / Void Avcodec_register_all (void) { Static int initection = 0; IF (InInd! = 0) Return; InInited = 1; Register_avcodec (& H264_Decoder); // av_register_codec_parser (& H264_PARSER); } 1234567891011121314 Therefore, the CODEC decoder actually invokes the three subunies in the H264.c to complete the decoding task. 2 configuration decoder The above is a registration and definition decoder, where the ffmpeg's AVCODEC_OPEN module opens CODEC, and actually invokes the DECode_init local function to create, configure the H.264 decoder. Int avcodec_open (avcodeccontext * avctx, avcodec * codec) { int R; IF (avctx-> codec) return -1; / * Codec pointer valid * / AVCTX-> CODEC = CODEC; / * Pointing CODEC * / AVCTX-> CODEC_ID = CODEC-> ID; / * CODEC name * / AVCTX-> frame_number = 0; #if 1 IF (codec-> priv_data_size> 0) {/ * CODEC structure is not 0 * / / * Application Space for CODEC * / AVCTX-> priv_data = av_mallocz (codec-> priv_data_size); IF (! avctx-> priv_data) Return -ENMEM; } else { AVCTX-> priv_data = null; } #ENDIF / * Initialization of CODEC * / Ret = avctx-> codec-> init (avctx); / * If it fails, release the context structure * / IF (RET <0) { AV_FreeP (& AvcTX-> Priv_Data); Return Ret; } Return 0; } 1234567891011121314151617181920212223242526272829 The initialization of the decoder, including setting the default decoding parameters, the image width, and the initialization of the I frame prediction function, etc., then the pixel format is a planar mode of the I420; the final set is the initialization of the variable length encoded VLC table. 3 H.264 video decoding The video decoding module is done by ffmpeg's avcodec_decode_video (). Since the H.264 code stream has passed NAL packaging, you need to call the getNextNal () module before calling the decoder to read the analysis of a NAL package from the code stream file, which is looking for NAL's header 0x00 00 00 00 00 00 00 00 00 00 00 00 00 00 00, then Pass the data between the two headers to the VCL decoder avcodec_decode_video () implementation decoding: / ** * Decode a frame. * @Param BUF BitStream Buffer, Must Be ff_input_buffer_padding_size larger dam @padding_size larger1 the actual read bytes * Because Some Optimized BitStream Readers Read 32 or 64 Bit at ONCE AND COLD Read over the end * @Param buf_size the size of the buffer in bytes * @Param got_picture_ptr Zero if no frame could be decompressed, OtherWise, IT IS NON ZERO * @return -1 if error, OtherWise Return The Number of * Bytes used. * / Int avcodec_decode_video (AvcodecContext * Avctx, Avframe * Picture, INT * GOT_PICTURE_PTR, UINT8_T * BUF, INT BUF_SIZE) { int R; / * There is no decoding ID * / * GOT_PICTURE_PTR = 0; /*H.264 decoding * / Ret = avctx-> codec-> decode (avctx, // decoder context Picture, // Decoded image GOT_PICTURE_PTR, // Image Decoding Identification BUF, // The code stream to be decoded BUF_SIZE); // Code Flow Length / * If you use MMX or other instructions, you need to call this function * / EMMS_C (); / * Decoded is an image, not header data * / IF (* got_picture_ptr) AVCTX-> Frame_Number ++; Return Ret; } 1234567891011121314151617181920212223242526272829303323334 The VCL decoder described above calls the FFMPEG's common function interface Decode, which is the actual decoding function decode_frame implementation of the VCL decoding of the H.264 in accordance with the incoming code stream and length. If the MMX instruction is used during the decoding process and exit, use the float / double type, you need to use the EMMS instruction (EMPTY MMX State) to cool the MMX status to restore the previous CPU status. The actual decoding function decode_frame implements the virtual decoding of the VCL, and the topology of the module is shown in the figure. The Decode_Frame decoded video encoding layer VCL data in the figure, and the module core is decode_nal_units. Static int decode_frame (AvcodecContext * Avctx, / * decoder context * / Void * data, / * Structure of the decoded image * / INT * DATA_SIZE, / * Structure Size * / UINT8_T * BUF, / * Code Space * / INT buf_size) / * Code Flow Length * / { H264Context * h = avctx-> priv_data; / * decoder context * / MPEgencContext * s = & h-> s; / * MPEGENCCONTEXT pointer * / Avframe * Pict = data; / * Image space * / INT buf_index; / * Current code stream position * / S-> Flags = avctx-> flags; / * CODEC logo * / S-> Flags2 = avctx-> flags2; / * CODEC logo 2 * / IF (buf_size == 0) {/ * code stream is not empty * / Return 0; } / * Truncated code stream decoding * / IF (S-> Flags & Codec_Flag_Truncated) { INT next = find_frame_end (& S-> Parse_Context, buf, buf_size); IF (FF_COMBINE_FRAME (& S-> Parse_Context, Next, & Buf, & Buf_size) <0) Return BUF_SIZE; } / * Decoding of special data in the code stream * / IF (S-> Avctx-> EXTRADATA_SIZE && S-> Picture_Number == 0) { IF (0 avctx-> extradata, s-> avctx-> extradata_size))))) Return -1; } / * Normal decoding * / BUF_INDEX = Decode_nal_units (h, buf, buf_size); IF (BUF_INDEX <0) Return -1; #if 0 / * B frame * / IF (S-> Pict_Type == B_TYPE || S-> Low_DELAY) { * Pict = * (avframe *) & S-> Current_Picture; } else { * Pict = * (avframe *) & S-> Last_Picture; } #ENDIF / * No decoded output image, decoding head data * / IF (! s-> current_picture_ptr) { AV_LOG (H-> S.AVCTX, AV_LOG_DEBUG, "ERROR, NO FRAME \ N"); Return -1; } / * Has a decoded image output * / * Pict = * (avframe *) & S-> Current_Picture; Assert (Pict-> DATA [0]); / * Indicates decoded output * / * DATA_SIZE = SizeOf (AVFrame); / * Return the current consumption code stream * / Return GET_CONSUMED_BYTES (S, BUF_INDEX, BUF_SIZE); } 123456781617181920212223242526272829303333333434444344454647484950515253 During the above decoding process, first, if the truncated stream, the decoded code stream is combined with one frame image; whether there is a special data in the code stream such as a Huffman table, then normal decoding NAL; final output decoded image and The length of the stream consumed. Where the core is NAL decoding decode_nal_units. 4 NAL package solution The basic unit in the H.264 stream is behaving as each independent NAL package, so the decoded process function decode_nal_units () implements the decoding NAL package. The topology of the module is shown in the figure: NAL decoding in the above figure mainly includes a sequence parameter set SPS, an image parameter set PPS, an instant decoding brush film IDR, an image tab slice_header, an image slice, and other structures, Decode decode_nal_units implementation process is as follows: / * NAL unit decoding * / Static int decode_nal_units (H264Context * H, // decoder handle UINT8_T * BUF, // Code Space INT buf_size) {// code stream length MPEgencContext * const S = & h-> s; AvcodecContext * const avctx = s-> avctx; INT buf_index = 0; / * Cyclic decoding * / For (;;) { INT consumed; // consumes the length INT DST_LENGTH; / / Target Length INT bit_length; // Bit length UINT8_T * PTR; // Temporary Pointer / * Search prefix start code: 0x 00 00 01 * / For (; buf_index + 3 = BUF_SIZE) BREAK; / * Index post-shift * / BUF_INDEX + = 3; / * Network abstraction layer NAL unpack * / PTR = decode_nal (h, buf + buf_index, & dst_length, & consumed, buf_size - buf_index); IF (PTR [DST_LENGTH - 1] == 0) DST_LENGTH -; / * Determine the accurate end position of the code stream * / Bit_length = 8 * DST_LENGTH - DECODE_RBSP_TRAILING (PTR + DST_LENGTH - 1); IF (S-> AVCTX-> Debug & ff_debug_startcode) { AV_LOG (h-> s.avctx, av_log_debug, "nal% D at% D Length% D \ N", H-> NAL_UNIT_TYPE, BUF_INDEX, DST_LENGTH); } / * Index post-shift * / BUF_INDEX + = ConsuMed; IF (S-> hurry_up == 1 && H-> NAL_REF_IDC == 0) CONTINUE; Switch (h-> nal_unit_type) {/ * Performs Decoding according to NAL type * / Case nal_idr_slice: // idR IDR (h); ////// Case nal_slice: // Image slice SLICE decoding / * Initialized code stream pointer * / INIT_GET_BITS (& S-> GB, PTR, Bit_Length); H-> intra_gb_ptr = H-> inter_gb_ptr = & S-> GB; S-> Data_Partitioning = 0; / * Decoded image slice * / IF (decode_slice_header (h) <0) return -1; IF (h-> redundant_pic_count == 0 && S-> hurry_up <5) / **************** Image piece data decoding * / Decode_slice (h); / **************** Image piece data decoding * / Break; Case Nal_DPA: // Data Partition A INIT_GET_BITS (& S-> GB, PTR, Bit_Length); H-> intra_gb_ptr = H-> inter_gb_ptr = NULL; S-> Data_Partitioning = 1; / * Decoded image slice * / IF (decode_slice_header (h) <0) return -1; Break; Case nal_dpb: // Data Partition B INIT_GET_BITS (& H-> intra_GB, PTR, Bit_length); H-> intra_gb_ptr = & h-> intra_GB; Break; Case Nal_DPC: // Data Partition C INIT_GET_BITS (& H-> Inter_gb, PTR, Bit_Length); H-> interface_gb_ptr = & h-> inter_gb; IF (h-> redundant_pic_count == 0 && H-> intra_gb_ptr && S-> Data_Partitioning && S-> HURRY_UP <5) Decode_slice (h); Break; Case nal_sei: // Supplemental enhancement information Break; Case Nal_SPS: // Sequence Parameter Set SPS / * Initialized code stream * / INIT_GET_BITS (& S-> GB, PTR, Bit_Length); / * SPS decoding * / Decode_seq_parameter_set (h); IF (S-> Flags & Codec_Flag_low_DELAY) S-> low_delay = 1; AVCTX-> HAS_B_FRAMES =! S-> low_delay; Printf ("Decode SPS \ N"); Break; Case nal_pps: // Image parameter set PPS / * Initialized code stream * / INIT_GET_BITS (& S-> GB, PTR, Bit_Length); / * PPS decoding * / Decode_picture_parameter_set (h); Printf ("Decode PPS \ N"); Break; Case Nal_Picture_Delimiter: Break; Case nal_filter_data: Break; DEFAULT: AV_LOG (AVCTX, AV_LOG_ERROR, "Unknown Nal Code:% D \ N", H-> nal_unit_type; } / * Image frame type * / S-> current_picture.pict_type = S-> Pict_Type; / * Key frame type initialization * / S-> current_picture.key_frame = s-> pict_type == i_type; } / * No decoded output image * / IF (! s-> current_picture_ptr) Return BUF_INDEX; // No Frame / * Modify image sequence POC * / H-> prev_frame_num_offset = h-> frame_num_offset; H-> prev_frame_num = h-> frame_num; IF (S-> Current_Picture_Ptr-> Reference) { H-> prev_poc_msb = h-> poc_msb; H-> prev_poc_lsb = h-> poc_lsb; } / * Tag reference frame * / IF (S-> Current_Picture_Ptr-> Reference) Execute_ref_pic_marking (h, h-> mmco, h-> mmco_index); Else Assert (h-> mmco_index == 0); / * Code flow fault end * / FF_ER_FRAME_END (S); / * Decoding a frame is completed, extended image * / MPV_FRAME_END (S); Return buf_index; } 123456789

     

     

     

     

    List all Question

    Nickname

    Email

    Questions

    Our other product:

    Professional FM Radio Station Equipment Package

     



     

    Hotel IPTV Solution

     


      Enter email  to get a surprise

      fmuser.org

      es.fmuser.org
      it.fmuser.org
      fr.fmuser.org
      de.fmuser.org
      af.fmuser.org ->Afrikaans
      sq.fmuser.org ->Albanian
      ar.fmuser.org ->Arabic
      hy.fmuser.org ->Armenian
      az.fmuser.org ->Azerbaijani
      eu.fmuser.org ->Basque
      be.fmuser.org ->Belarusian
      bg.fmuser.org ->Bulgarian
      ca.fmuser.org ->Catalan
      zh-CN.fmuser.org ->Chinese (Simplified)
      zh-TW.fmuser.org ->Chinese (Traditional)
      hr.fmuser.org ->Croatian
      cs.fmuser.org ->Czech
      da.fmuser.org ->Danish
      nl.fmuser.org ->Dutch
      et.fmuser.org ->Estonian
      tl.fmuser.org ->Filipino
      fi.fmuser.org ->Finnish
      fr.fmuser.org ->French
      gl.fmuser.org ->Galician
      ka.fmuser.org ->Georgian
      de.fmuser.org ->German
      el.fmuser.org ->Greek
      ht.fmuser.org ->Haitian Creole
      iw.fmuser.org ->Hebrew
      hi.fmuser.org ->Hindi
      hu.fmuser.org ->Hungarian
      is.fmuser.org ->Icelandic
      id.fmuser.org ->Indonesian
      ga.fmuser.org ->Irish
      it.fmuser.org ->Italian
      ja.fmuser.org ->Japanese
      ko.fmuser.org ->Korean
      lv.fmuser.org ->Latvian
      lt.fmuser.org ->Lithuanian
      mk.fmuser.org ->Macedonian
      ms.fmuser.org ->Malay
      mt.fmuser.org ->Maltese
      no.fmuser.org ->Norwegian
      fa.fmuser.org ->Persian
      pl.fmuser.org ->Polish
      pt.fmuser.org ->Portuguese
      ro.fmuser.org ->Romanian
      ru.fmuser.org ->Russian
      sr.fmuser.org ->Serbian
      sk.fmuser.org ->Slovak
      sl.fmuser.org ->Slovenian
      es.fmuser.org ->Spanish
      sw.fmuser.org ->Swahili
      sv.fmuser.org ->Swedish
      th.fmuser.org ->Thai
      tr.fmuser.org ->Turkish
      uk.fmuser.org ->Ukrainian
      ur.fmuser.org ->Urdu
      vi.fmuser.org ->Vietnamese
      cy.fmuser.org ->Welsh
      yi.fmuser.org ->Yiddish

       
  •  

    FMUSER Wirless Transmit Video And Audio More Easier !

  • Contact

    Address:
    No.305 Room HuiLan Building No.273 Huanpu Road Guangzhou China 510620

    E-mail:
    [email protected]

    Tel / WhatApps:
    +8618078869184

  • Categories

  • Newsletter

    FIRST OR FULL NAME

    E-mail

  • paypal solution  Western UnionBank OF China
    E-mail:[email protected]   WhatsApp:+8618078869184   Skype:sky198710021 Chat with me
    Copyright 2006-2020 Powered By www.fmuser.org

    Contact Us