Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6709 Discussions

H264 Encoder w_ipp-samples_p_7.1.1.013 problem with b frames

sdi_3
Beginner
288 Views

Hi,

Im trying to upgrate the H264Encoder and MP4Muxer to UMC w_ipp-samples_p_7.1.1.013 with registered IPP 7.1. I made a small code to encode and mux 30 YUV420 raw frames, 1280x720. Many variables are changed and the manual seems to be outdated, after some guessing I got the thing almost working.

After inicialize all, if not using B frames it works fine:

-H264Encoder not using B frames:

    H264Params->chroma_format_idc=1;    // 1 - YUV420
    H264Params->coding_type=0;        // 0 - Frame (all frames are coded as frames) 1 - Fields
    H264Params->profile_idc=100;
    H264Params->B_frame_rate=0;
    H264Params->B_reference_mode=0;
    H264Params->num_ref_frames=1;        // Maximum number of reference frames....
    H264Params->level_idc=0;        //level_idc value according to the standard. Set 0 for automatic level_idc computation.
    H264Params->key_interval=12;        // Distance between two sequential I frames.
    H264Params->idr_interval=0; // Must be greater or equal to 0.


the output file plays fine in all players and checked with a h264 tool shows correctly the frame estructure IP...PI, using different H264Params->key_interval works fine.


-H264Encoder using B frames

    H264Params->chroma_format_idc=1;    // 1 - YUV420
    H264Params->coding_type=0;        // 0 - Frame (all frames are coded as frames) 1 - Fields
    H264Params->profile_idc=100;
    H264Params->B_frame_rate=2;
    H264Params->B_reference_mode=3;    // tested 0 1 2 3 4 ...
    H264Params->num_ref_frames=2;        // Maximum number of reference frames.
    H264Params->level_idc=0;        //level_idc value according to the standard. 0 for automatic level_idc computation.
    H264Params->key_interval=12;        // Distance between two sequential I frames.
    H264Params->idr_interval=0; // Must be greater or equal to 0.


encoder crashes after 10-12 frames feed, heap corruption detected, tested several times always crash,

changing Params->key_interval=14; the output video is ok, but the frame sequence is IPBBPBBPBBPBBPBPI first I=0 second I=16 , it should be 14 frames between I, not 15

changing Params->key_interval=13; the output video is ok, but the frame sequence is exactly the same as 14

changing Params->key_interval=11; always crash heap corruption detected

changing Params->key_interval=21;  and also other values,  video cannot be played in qt/windows media player, but the h264 inspector shows correct GOP


is something wrong with the params? or what?

I can provide all the code and a vc2008 project.

thanks in advance

0 Kudos
1 Reply
sdi_3
Beginner
288 Views

Update: 

with these params a crash happens always when few frames are sent to encoder:

    input:    yuv420 interlaced 1440x1080

    H264Params->coding_type=1;        // interlaced
    H264Params->B_frame_rate=2;        // b frame rate 2


By tracing in debug mode, the crash happens here in UMC, it looks like a bug:

umc_h264_me.cpp
line 811


> ref_mvs is declared as NULL

            H264MotionVector* ref_mvs = NULL;           
                H264EncoderFrame<PIXTYPE> *prev_frame =
                    core_enc->m_is_cur_pic_afrm?
                    FindDirectRefIdxMBAFF(mb_col, uMB,block_col, pGetMBFieldDecodingFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo),pRefPicList0,pRefPicList1, mv_col, ref_idx_l0, curr_slice->num_ref_idx_l0_active, core_enc->m_MaxSliceSize)
                    :
> if is_cur_mb_field==1 ref_mvs is correctly initialized calling FindDirectRefIdx
> but if is_cur_mb_field==0 then it remains NULL

                (is_cur_mb_field!=0)?
                    FindDirectRefIdxFLD(mb_col, block_col, pRefPicList0,pRefPicList1, pFields0, pFields1, mv_col, ref_idx_l0,curr_slice->num_ref_idx_l0_active, core_enc->m_MaxSliceSize)
                    :
                FindDirectRefIdx(curr_slice, mb_col, block_col, pRefPicList0,pRefPicList1, &ref_mvs, ref_idx_l0, curr_slice->num_ref_idx_l0_active);

        if (!prev_frame) return false;
       
> commented out line initializing ref_mvs (?)

                //  H264MotionVector  *ref_mvs = &futr_frame->m_mbinfo.MV[LIST_0][mb_col].MotionVectors[block_col];
   
                ref_direct_l0[sb_pos] = ref_idx_l0;
                ref_direct_l0[sb_pos + 1] = ref_idx_l0;
                ref_direct_l0[sb_pos + 4] = ref_idx_l0;
                ref_direct_l0[sb_pos + 5] = ref_idx_l0;
                Ipp32s uFwdRatio = pGetMBFieldDecodingFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo)?
                    curr_slice->DistScaleFactorMVAFF[uMB&1][uMB&1][(uMB&1)^(ref_idx_l0&1)][ref_idx_l0 >> 1] //FIXME
                : curr_slice->DistScaleFactorMV[ref_idx_l0][0];
   
                for (Ipp32s ypos = 0; ypos < 2; ypos++) // 4 4x4 blocks
                {
                    for (Ipp32s xpos = 0; xpos < 2; xpos++)
                    {
> here ref_mvs may be NULL and program crash

                        H264MotionVector mv_col = core_enc->m_SeqParamSet.direct_8x8_inference_flag ? *ref_mvs :
                            *(ref_mvs + ypos*4 + xpos);





I "solved" it changing the commented out line :

               
                //            H264MotionVector  *ref_mvs = &futr_frame->m_mbinfo.MV[LIST_0][mb_col].MotionVectors[block_col];
         if (ref_mvs==NULL)  ref_mvs = &futr_frame->m_mbinfo.MV[LIST_0][mb_col].MotionVectors[block_col];


I don't know if this solved anything or may be it brokes the encoder, could the programmerd check this?

0 Kudos
Reply