Beispiel #1
0
bool ADM_ffVAEncHEVC::preEncode(void)
{
    uint32_t nb;
    if(source->getNextFrame(&nb,image)==false)
    {
        ADM_warning("[ffVAEncHEVC] Cannot get next image\n");
        return false;
    }

    swFrame=av_frame_alloc();
    if(!swFrame)
    {
        ADM_error("Could not allocate sw frame\n");
        return false;
    }

    swFrame->width=source->getInfo()->width;
    swFrame->height=source->getInfo()->height;
    swFrame->format=AV_PIX_FMT_NV12;

    int err=av_frame_get_buffer(swFrame, 32);
    if(err<0)
    {
        CLEARTEXT(err)
        ADM_warning("get buffer for sw frame failed with error code %d (%s)\n",err,buf);
        return false;
    }

    swFrame->linesize[0] = swFrame->linesize[1] = image->GetPitch(PLANAR_Y);
    swFrame->linesize[2] = 0;
    swFrame->data[2] = NULL;
    image->convertToNV12(swFrame->data[0],swFrame->data[1],swFrame->linesize[0],swFrame->linesize[1]);

    if(hwFrame)
    {
        av_frame_free(&hwFrame);
        hwFrame=NULL;
    }
    hwFrame=av_frame_alloc();
    if(!hwFrame)
    {
        ADM_error("Could not allocate hw frame\n");
        return false;
    }

    hwFrame->width=source->getInfo()->width;
    hwFrame->height=source->getInfo()->height;
    hwFrame->format=AV_PIX_FMT_VAAPI;

    err=av_hwframe_get_buffer(_context->hw_frames_ctx,hwFrame,0);
    if(err<0)
    {
        CLEARTEXT(err)
        ADM_warning("get buffer for hw frame failed with error code %d (%s)\n",err,buf);
        return false;
    }

    err=av_hwframe_transfer_data(hwFrame, swFrame, 0);
    if(err<0)
    {
        CLEARTEXT(err)
        ADM_warning("data transfer to the hw frame failed with error code %d (%s)\n",err,buf);
        return false;
    }

    uint64_t p=image->Pts;
    queueOfDts.push_back(p);
    aprintf("Incoming frame PTS=%" PRIu64", delay=%" PRIu64"\n",p,getEncoderDelay());
    p+=getEncoderDelay();
    hwFrame->pts=timingToLav(p);
    if(!hwFrame->pts)
        hwFrame->pts=AV_NOPTS_VALUE;

    ADM_timeMapping map; // Store real PTS <->lav value mapping
    map.realTS=p;
    map.internalTS=hwFrame->pts;
    mapper.push_back(map);

    av_frame_free(&swFrame);
    swFrame=NULL;
    return true;
}
/**
    \fn postAmble
    \brief update after a frame has been succesfully encoded
*/
bool x264Encoder::postAmble (ADMBitstream * out,uint32_t nbNals,x264_nal_t *nal,x264_picture_t *picout)
{
    int size = encodeNals(out->data, out->bufferSize, nal, nbNals, false);

    if (size < 0)
    {
        ADM_error("[x264] Error encoding NALs\n");
        return false;
    }
    out->len=size;
    out->pts =  picout->i_pts+getEncoderDelay();
    out->dts =  picout->i_dts+getEncoderDelay();
    aprintf("encoder delay=%d, pic out dts=%d picout pts=%d\n",getEncoderDelay(),picout->i_dts,picout->i_pts);
    aprintf("pts = %"PRIu64", dts=%"PRIu64", pts+delay=%"PRIu64" delta=%"PRIu64"\n",picout->i_pts,out->dts,out->pts,
            out->pts-out->dts);
    if(out->dts>out->pts)
    {
        ADM_warning("DTS > PTS, that can happen when there are holes in the source (%"PRIu64"/%"PRIu64")\n",
                    out->dts,out->pts);
        if(picout->i_type!=X264_TYPE_B && picout->i_type!=X264_TYPE_BREF)
        {
            ADM_warning("It is not a bframe, expect problems\n");
            ADM_warning("It is not a bframe, expect problems\n");
        }
        out->dts=out->pts;
    }
    switch (picout->i_type)
    {
    case X264_TYPE_IDR:
        out->flags = AVI_KEY_FRAME;
        /* First Idr ?*/
        if(!param.b_repeat_headers && seiUserData && firstIdr==true)
        {
            // Put our SEI front...
            // first a temp location...
            firstIdr=false;
            uint8_t *tmpBuffer=new uint8_t[size];
            memcpy(tmpBuffer,out->data,size);
            uint8_t *dout=out->data;
            // Put back out SEI and add Size
            dout[0]=(seiUserDataLen>>24)&0xff;
            dout[1]=(seiUserDataLen>>16)&0xff;
            dout[2]=(seiUserDataLen>>8)&0xff;
            dout[3]=(seiUserDataLen>>0)&0xff;
            memcpy(dout+4,seiUserData,seiUserDataLen);
            memcpy(dout+4+seiUserDataLen,tmpBuffer,size);
            size+=4+seiUserDataLen;
            out->len = size; // update total size
            delete [] tmpBuffer;
        }
        break;
    case X264_TYPE_I:
        out->flags = AVI_P_FRAME;
        break;
    case X264_TYPE_P:
        out->flags = AVI_P_FRAME;
        break;
    case X264_TYPE_B:
    case X264_TYPE_BREF:
        out->flags = AVI_B_FRAME;
        break;
    default:
        ADM_error ("[x264] Unknown image type: %d\n", picout->i_type);
        //ADM_assert(0);
    }