基于Android-Framework视频H264/H265解码

主要解码部分代码

void VideoPlayChannel::Decode()
{
    int ret =-1;
    int dec_out;
    int err_cnt =0;
    int dec_cnt =0;
    uint32_t length =0;
    uint64_t cur_time =0,last_time =0;
    uint32_t sleep_time = 0;
    if(mDecodeType == DECODE_H265)
    {
        sleep_time = 40000; // 根据实际情况来
    }else
    {
        sleep_time = mFps==0?33000:1000000/mFps;
    }
    uint32_t decode_time =1;
    uint32_t count = 0;
    int n = 0;
    ALOGD("%d doDecode  start!!!",mIndex);    
    while(mIsStarted) {
        usleep(1000);
        decode_time =0;

        if(mResetflag) {
            if(mDecoder !=NULL) {
                mDecoder->close();    
                mDecoder.clear();
                mDecoder =NULL;
            }
            if(mCodecSurface ==NULL) {
                pause();
                continue;
            }
            mDecoder = new MyAvcDecoder(mWidth, mHeight, mCodecSurface, true);
            if(mDecoder ==NULL) {
                ALOGD("%d decode creat failed",mIndex);    
                pause();
                continue;
            }
            // init decode engine type;0 is 264 mode, 1 is 265mode
            mDecoder->init(mDecodeType);
            ALOGD("reset myavcDecoder decode type %d,index %d\n",mDecodeType,mIndex);
            ums_pipe_reset(mDecode_pipe);            
            mNeedIDR =true;
            mResetflag =false;            
            mState =START;            
            continue;
        }
    
       if((ums_pipe_get_used_len(mDecode_pipe) >= 16) && (mState ==START) &&                  !mResetflag)
           {         
                length =ums_pipe_read( mDecode_pipe, &mf[0].size, sizeof(mf[0].size) );            
                count = 0;
                if(length = 2000) || (100 == current_meet_type))
                        {               
                            for (n = 0; n < 30; n++)                                    
                            {
                                 if (mDecodeType == 0) {

                                    decode(mLogoBuffer,mLogoBufferSize, 1920,1080,10);
                                } else if (mDecodeType == 1) {
                                    decode(mLogoBuffer265,mLogoBufferSize265, 1920,1080,25);
                                }  
                            }  
                        }
                    }
                    count = 0;
                }
                           
                #endif
                
                continue;
            }
            
            if(mDecodeType == DECODE_H265)
            {
                sleep_time = 40000;
            }else
            {
                sleep_time = mFps==0?33000:1000000/mFps;
            }
            
            if(decode_time >sleep_time  ) {//&& (mIndex ==1004 || mIndex ==2002)
                decode_time -=sleep_time;
                uint8_t nalType =mf[0].data[4] & 0x1f;
                if(nalType == NAL_TYPE_SLICE)
                {               
                    continue;
                }
            }
            cur_time =systemTime();           
            if(mDecoder!=NULL && mYv12Buffer !=NULL && (mIsStarted) && (1==stop_ok)){                        
                ret=mDecoder->prepare(mf[0].data,0,mf[0].size,dec_cnt*sleep_time);            
          if(ret !=OK ){
              char buf[50];
              display_timestamp(buf, sizeof(buf));
               ALOGE("%s:%d decode fail %s(0x%x) %d",buf,mIndex,strerror(ret),ret,dec_cnt);    
                    if(ret == -38 || ret == -11 || ret == -19) {    
                        if(!mResetflag && mState ==START) {                  
                            mResetflag =true;    
                            pause();
                            continue;
                        }
                    }
                    else if (ret == -13)
                    {
                        system("busybox killall v2vserver");
                    }
                    else if(err_cnt ++ > 2 || mFlushflag) {
                        ALOGD(" %d decode  flush",mIndex);    
                        mDecoder->flush(mDecodeType);
                        err_cnt =1;
                        mFlushflag =false;
                        continue;
                    }
                    
                    
                } else{
                    if(dec_cnt %2500 ==1) {
                        char buf[50];
                        display_timestamp(buf, sizeof(buf));
                        int buf_size = ums_pipe_get_used_len(mDecode_pipe);
                        int delay_ms = buf_size / 2048;
                        ALOGD("%s:%d decode counter %d,delay:%d ms,buf_size:%d",buf,mIndex,dec_cnt,delay_ms,buf_size);
                    }
                    err_cnt =1;
                }
                if(mIsStarted) {
                    mDecoder->onDoMoreStuff();
                }
                dec_cnt ++;
      }
        #if 1
            last_time =systemTime();    
            decode_time =DELTA_AUDIO_TIMESTAMP(last_time,cur_time)/1000;
            if(decode_time >sleep_time) {
                
                if(decode_time >(sleep_time <<0)) {
                    char buf[50];
                    display_timestamp(buf, sizeof(buf));                    
                }
                if(mIndex !=1004) { 
                    decode_time -=sleep_time/2;
                }
                else {
                    //decode_time -=sleep_time/2;      
                }
                
            }
            else {
                uint32_t delay_time =sleep_time -decode_time;
                if(mIndex <2000 || ((mIndex==2004)&& current_meet_type==100)) {
                    delay_time /=4;
                } else {
                    int len =ums_pipe_get_used_len(mDecode_pipe);                
                    if(mBitrate >100 ) {
                        if(len >(mBitrate <<3)) //*1014/8/16
                        {
                            delay_time /=4;
                        }
                    } else {
                        if(len >= 80000) //*1014/8/4
                        {
                            delay_time /=4;
                        }
                    }
                }
                
                if(delay_time >2000)
                {         
                    usleep(delay_time);    
                }
                //
            }
            #endif            
    }
    mErrorState =false;
    mDecoder->close();   
    mDecoder.clear(); //FIXME!
    mDecoder =NULL;
    ALOGD("%d doDecode  end!!!",mIndex);
}

卡顿和延时需要调整sleep_time和decode_time每帧的实际花费时间和解码实际时间。

你可能感兴趣的:(android,c++)