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); }