Hello,

I have several problem when I want to decode a H264 video send by 

RTP.

I'm using libavcodec to decode video but I build my own SDP 

parser.

If you have time, can you tell me where is the problem in my 

method.

     I create a structure to store SDP data :


        typedef struct{
        int packetization_mode;
            uint8_t profile_idc;
            uint8_t profile_iop;
            uint8_t level_idc;
            int extradata_size;
            uint8_t* extradata;
            int width;
            int height;
        } H264CONTEXT;

        H264CONTEXT h264context;


     I parse  the fmtp line of SDP as the function of ffmpeg 

sdp_parse_fmtp_config_h264

      
    Then I found :

                 level_idc= 41 (base 10)
                 profile_idc= 66 (base 10)
                 extradata_size=30
                 I store 00 00 01 67 42 00 1e e2 90 16 02 4d 81 

27 05 01 05 e1 e2 44 54 00 00 01 68 ce 3c 80 00 00 in extradata


    * I initialize CodecContext


        codecContext->level            =    h264context.level_idc;
        codecContext->profile        =   h264context.profile_idc;  

               
       
        codecContext->extradata_size=    

h264context.extradata_size;                     
        codecContext->extradata        =h264context.extradata;
      
        codecContext->hurry_up        = 1;
        codecContext->debug            = 1;
        codecContext->stream_codec_tag        = 462h; 

//0x31637661;

        codecContext->flags                |= CODEC_FLAG_4MV;
        codecContext->flags                |= CODEC_FLAG_PART;
        codecContext->flags                |=CODEC_FLAG_TRUNCATED;
        codecContext->flags2              |=  CODEC_FLAG2_CHUNKS;

       
        codecContext->error_recognition        =    1;             

         
        codecContext->error_concealment        =     

FF_EC_GUESS_MVS;                      
        codecContext->skip_top                =    0;
        codecContext->skip_bottom            =    0;
        codecContext->skip_loop_filter        =    AVDISCARD_NONE;
        codecContext->skip_idct                =    

AVDISCARD_NONE;         
        codecContext->skip_frame            =    AVDISCARD_NONE
         codecContext->workaround_bugs        =    1;

        codecContext->codec_type            =    CODEC_TYPE_VIDEO;
        codecContext->codec_id                =    CODEC_ID_H264;

        codecContext->pix_fmt                =    PIX_FMT_YUV420P;
        codecContext->sample_fmt            =    SAMPLE_FMT_S16;   

      
        codecContext->codec_tag                =    

avcodec_pix_fmt_to_codec_tag (codecContext->pix_fmt ) ;
        codecContext->width        = 768;
        codecContext->height    = 576;

          I try decode IDR frame.



    My IDR frame (nal_type = 5) are fragmented : fragment_type=28 


    I find in a forum this method :



     If the NAL is 28 (1C) then it means that following payload 

represents one H264 IDR (I-Frame)
     fragment and that I need to collect all of them to 

reconstruct H264 IDR (I-Frame).

    Fragment that has START BIT = 1:

    First byte:  [ 3 NAL UNIT BITS | 5 FRAGMENT TYPE BITS] 
    Second byte: [ START BIT | RESERVED BIT | END BIT | 5 NAL UNIT 

BITS] 
    Other bytes: [... IDR FRAGMENT DATA...]

    Other fragments:

    First byte:  [ 3 NAL UNIT BITS | 5 FRAGMENT TYPE BITS]  
    Other bytes: [... IDR FRAGMENT DATA...]

    To reconstruct IDR I collect this info:

    int fragment_type = Data[0] & 0x1F;
    int nal_type = Data[1] & 0x1F;
    int start_bit = Data[1] & 0x80;
    int end_bit = Data[1] & 0x40;

    If fragment_type == 28 then payload following it is one 

fragment of IDR. Next check is start_bit set,
    if it is, then that fragment is the first one in a sequence. I 

use it to reconstruct IDR's NAL byte by taking
    the first 3 bits from first payload byte (3 NAL UNIT BITS) and 

combine them with last 5 bits from

    second payload byte (5 NAL UNIT BITS) so I would get a byte 

like this

    [3 NAL UNIT BITS | 5 NAL UNIT BITS]. Then I  write that NAL 

byte first
    into a clear buffer with all other following bytes from that 

fragment. Remember to skip first byte

    in a sequence since it is not a part of IDR, but only 

identifies the fragment.


    If start_bit and end_bit are 0 then I just write the payload 

(skipping first
    payload byte that identifies the fragment) to the buffer.


    If start_bit is 0 and end_bit is 1, that means that it is the 

last fragment,
    and I just write its payload (skipping the first byte that 

identifies the fragment)
    to the buffer, and now I have my IDR reconstructed.



    Then I send my IDR to decoder but I some error occurs :

           pps_id (32) out of range

          illegal POC type 5


    it think is due SPS/PPS setting  but I don't understant why 



    Thx
 




_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to