H264 Encoder w_ipp-samples_p_7.1.1.013 problem with b frames

H264 Encoder w_ipp-samples_p_7.1.1.013 problem with b frames

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

2 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

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?

Lascia un commento

Eseguire l'accesso per aggiungere un commento. Non siete membri? Iscriviti oggi