On Thu, 2015-01-08 at 14:28 -0800, Tony Di Croce wrote: > While adapting the encoding example to my use at some point I broke > bitrate control... Basically, no matter what I set the bitrate to I > get the same video out of libva. Here is my code: > >
Are you using the intel-vaapi driver downloaded from: http://cgit.freedesktop.org/vaapi/intel-driver/ It will be better that you can take a look at the encoding example of : http://cgit.freedesktop.org/vaapi/libva/ It can be found under the directory of libva/test/encode/ Thanks. Yakui > #include "VAKit/VAH264Encoder.h" > #include "VAKit/BitStream.h" > #include "VAKit/NALTypes.h" > #include "XSDK/XException.h" > > > using namespace VAKit; > using namespace std; > using namespace XSDK; > using namespace AVKit; > > > const size_t MAX_FRAME_NUM = (2<<16); > const size_t MAX_PIC_ORDER_CNT_LSB = (2<<8); > const size_t LOG_2_MAX_FRAME_NUM = 16; > const size_t LOG_2_MAX_PIC_ORDER_CNT_LSB = 8; > const int32_t H264_MAXREF = (1<<16|1); > > > const int32_t FRAME_P = 0; > const int32_t FRAME_I = 2; > const int32_t FRAME_IDR = 7; > > > static const size_t DEFAULT_PADDING = 16; > static const size_t DEFAULT_ENCODE_BUFFER_SIZE = (1024*1024); > static const size_t DEFAULT_EXTRADATA_BUFFER_SIZE = (1024*256); > > > VAH264Encoder::VAH264Encoder( const struct AVKit::CodecOptions& > options, > bool annexB ) : > _devicePath(), > _annexB( annexB ), > _fd(-1), > _display(), > _h264Profile( VAProfileH264High ), > _configID( 0 ), > _srcSurfaceID( 0 ), > _codedBufID( 0 ), > _refSurfaceIDs(), > _contextID(0), > _seqParam(), > _picParam(), > _sliceParam(), > _currentCurrPic(), > _referenceFrames(), > _refPicListP(), > _constraintSetFlag( 0 ), > _h264EntropyMode( 1 ), /* cabac */ > _frameWidth( 0 ), > _frameWidthMBAligned( 0 ), > _frameHeight( 0 ), > _frameHeightMBAligned( 0 ), > _frameBitRate( 0 ), > _intraPeriod( 15 ), > _currentIDRDisplay( 0 ), > _currentFrameNum( 0 ), > _currentFrameType( 0 ), > _timeBaseNum( 0 ), > _timeBaseDen( 0 ), > _extraData(), > _pkt(), > _options( options ) > { > if( options.device_path.IsNull() ) > X_THROW(("device_path needed for VAH264Encoder.")); > > > _devicePath = options.device_path.Value(); > > > _fd = open( _devicePath.c_str(), O_RDWR ); > if( _fd <= 0 ) > X_THROW(("Unable to open %s",_devicePath.c_str())); > > > _display = (VADisplay)vaGetDisplayDRM( _fd ); > > > if( !options.width.IsNull() ) > { > _frameWidth = options.width.Value(); > _frameWidthMBAligned = (_frameWidth + 15) & (~15); > } > else X_THROW(( "Required option missing: width" )); > > > if( !options.height.IsNull() ) > { > _frameHeight = options.height.Value(); > _frameHeightMBAligned = (_frameHeight + 15) & (~15); > } > else X_THROW(( "Required option missing: height" )); > > > if( !options.bit_rate.IsNull() ) > _frameBitRate = options.bit_rate.Value(); > // _frameBitRate = (options.bit_rate.Value() / 1024) / 8; > else X_THROW(( "Required option missing: bit_rate" )); > > > if( !options.gop_size.IsNull() ) > _intraPeriod = options.gop_size.Value(); > > > if( !options.time_base_num.IsNull() ) > _timeBaseNum = options.time_base_num.Value(); > else X_THROW(("Required option missing: time_base.num")); > > > if( !options.time_base_den.IsNull() ) > _timeBaseDen = options.time_base_den.Value(); > else X_THROW(("Required option missing: time_base.den")); > > > int major_ver = 0, minor_ver = 0; > VAStatus status = vaInitialize( _display, &major_ver, > &minor_ver ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaInitialize (%s).", > vaErrorStr(status) )); > > > switch( _h264Profile ) > { > case VAProfileH264Baseline: > _constraintSetFlag |= (1 << 0); /* Annex A.2.1 */ > _h264EntropyMode = 0; > break; > case VAProfileH264ConstrainedBaseline: > _constraintSetFlag |= (1 << 0 | 1 << 1); /* Annex A.2.2 */ > _h264EntropyMode = 0; > break; > case VAProfileH264Main: > _constraintSetFlag |= (1 << 1); /* Annex A.2.2 */ > break; > case VAProfileH264High: > _constraintSetFlag |= (1 << 3); /* Annex A.2.4 */ > break; > default: > _h264Profile = VAProfileH264Baseline; > _constraintSetFlag |= (1 << 0); /* Annex A.2.1 */ > break; > } > > > VAConfigAttrib configAttrib[VAConfigAttribTypeMax]; > int configAttribNum = 0; > > > configAttrib[configAttribNum].type = VAConfigAttribRTFormat; > configAttrib[configAttribNum].value = VA_RT_FORMAT_YUV420; > configAttribNum++; > > > configAttrib[configAttribNum].type = VAConfigAttribRateControl; > configAttrib[configAttribNum].value = VA_RC_VBR; > configAttribNum++; > > > configAttrib[configAttribNum].type = > VAConfigAttribEncPackedHeaders; > configAttrib[configAttribNum].value = VA_ENC_PACKED_HEADER_NONE; > configAttrib[configAttribNum].value = > VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE; > configAttribNum++; > > > status = vaCreateConfig( _display, > _h264Profile, > VAEntrypointEncSlice, > &configAttrib[0], > configAttribNum, > &_configID ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateConfig (%s).", > vaErrorStr(status) )); > > > > > // Configuration below this point can be thought of as specific to > a particular > // encoder channel. I point this out because we might want to > split this out > // someday. > > > /* create source surfaces */ > status = vaCreateSurfaces( _display, > VA_RT_FORMAT_YUV420, > _frameWidthMBAligned, > _frameHeightMBAligned, > &_srcSurfaceID, > 1, > NULL, > 0 ); > > > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateSurfaces (%s).", > vaErrorStr(status) )); > > > /* create reference surfaces */ > status = vaCreateSurfaces( _display, > VA_RT_FORMAT_YUV420, > _frameWidthMBAligned, > _frameHeightMBAligned, > &_refSurfaceIDs[0], > SURFACE_NUM, > NULL, > 0 ); > > > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateSurfaces (%s).", > vaErrorStr(status) )); > > > VASurfaceID* tmp_surfaceid = (VASurfaceID*)calloc( 2, > sizeof(VASurfaceID) ); > memcpy( tmp_surfaceid, &_srcSurfaceID, sizeof(VASurfaceID) ); > memcpy( tmp_surfaceid + 1, &_refSurfaceIDs, sizeof(VASurfaceID) ); > > > /* Create a context for this encode pipe */ > status = vaCreateContext( _display, > _configID, > _frameWidthMBAligned, > _frameHeightMBAligned, > VA_PROGRESSIVE, > tmp_surfaceid, > 2, > &_contextID ); > > > free(tmp_surfaceid); > > > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateContext (%s).", > vaErrorStr(status) )); > > > status = vaCreateBuffer( _display, > _contextID, > VAEncCodedBufferType, > (_frameWidthMBAligned * > _frameHeightMBAligned * 400) / (16*16), > 1, > NULL, > &_codedBufID ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(status) )); > } > > > VAH264Encoder::~VAH264Encoder() throw() > { > vaDestroyBuffer( _display, _codedBufID ); > > > vaDestroyContext( _display, _contextID ); > > > vaDestroySurfaces( _display, &_refSurfaceIDs[0], SURFACE_NUM ); > > > vaDestroySurfaces( _display, &_srcSurfaceID, 1 ); > > > vaDestroyConfig( _display, _configID ); > > > vaTerminate( _display ); > > > close( _fd ); > } > > > size_t VAH264Encoder::EncodeYUV420P( uint8_t* pic, > uint8_t* output, > size_t outputSize, > AVKit::FrameType type ) > { > VAImage image; > vaDeriveImage( _display, _srcSurfaceID, &image ); > > > _UploadImage( pic, image, _frameWidth, _frameHeight ); > > > _currentFrameType = _ComputeCurrentFrameType( _currentFrameNum, > _intraPeriod, > type ); > > > if( _currentFrameType == FRAME_IDR ) > { > _numShortTerm = 0; > _currentFrameNum = 0; > _currentIDRDisplay = _currentFrameNum; > } > > > VAStatus status = vaBeginPicture( _display, _contextID, > _srcSurfaceID ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaBeginPicture (%s).", > vaErrorStr(status) )); > > > if( _currentFrameType == FRAME_IDR ) > { > _RenderSequence(); > > > _RenderPicture( false ); > > > _RenderPackedSPS(); > > > _RenderPackedPPS(); > > > if( !_extraData.Get() ) > { > BitStream seqBS; > BuildPackedSeqBuffer( seqBS, > _seqParam, > _h264Profile, > _constraintSetFlag, > _timeBaseNum, > _timeBaseDen, > _frameBitRate / 8 ); > // _frameBitRate * 1024 * 8 ); > > > BitStream ppsBS; > BuildPackedPicBuffer( ppsBS, _picParam ); > > > _extraData = new XMemory; > > > memcpy( &_extraData->Extend(seqBS.Size()), seqBS.Map(), > seqBS.Size() ); > memcpy( &_extraData->Extend(ppsBS.Size()), ppsBS.Map(), > ppsBS.Size() ); > } > } > else _RenderPicture( false ); > > > _RenderSlice(); > > > status = vaEndPicture( _display, _contextID ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaEndPicture (%s).", > vaErrorStr(status) )); > > > _UpdateReferenceFrames(); > > > status = vaSyncSurface( _display, _srcSurfaceID ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaSyncSurface (%s).", > vaErrorStr(status) )); > > > VACodedBufferSegment* bufList = NULL; > > > status = vaMapBuffer( _display, _codedBufID, (void > **)(&bufList) ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaMapBuffer (%s).", > vaErrorStr(status) )); > > > VACodedBufferSegment* current = bufList; > > > uint32_t accumSize = 0; > > > while( current != NULL ) > { > accumSize += current->size; > current = (VACodedBufferSegment*)current->next; > } > > > if( outputSize < accumSize ) > X_THROW(("Not enough room in output buffer.")); > > > uint8_t* dst = output; > > > while( bufList != NULL ) > { > memcpy( dst, bufList->buf, bufList->size ); > dst += bufList->size; > bufList = (VACodedBufferSegment*)bufList->next; > } > > > vaUnmapBuffer( _display, _codedBufID ); > > > return accumSize; > } > > > XIRef<XMemory> VAH264Encoder::EncodeYUV420P( XIRef<XMemory> input, > AVKit::FrameType type ) > { > XIRef<XMemory> frame = new XMemory( DEFAULT_ENCODE_BUFFER_SIZE + > DEFAULT_PADDING ); > > > uint8_t* p = &frame->Extend( DEFAULT_ENCODE_BUFFER_SIZE ); > > > size_t outputSize = EncodeYUV420P( input->Map(), > p, > frame->GetDataSize(), > type ); > > > frame->ResizeData( outputSize ); > > > return frame; > } > > > bool VAH264Encoder::LastWasKey() const > { > return (_currentFrameType == FRAME_IDR) ? true : > (_currentFrameType == FRAME_I) ? true : false; > } > > > struct CodecOptions VAH264Encoder::GetOptions() const > { > return _options; > } > > > XIRef<XMemory> VAH264Encoder::GetExtraData() const > { > if( _extraData->GetDataSize() == 0 ) > X_THROW(("Decode one frame before call to GetExtraData().")); > > > return _extraData; > } > > > int32_t VAH264Encoder::_ComputeCurrentFrameType( uint32_t > currentFrameNum, > int32_t intraPeriod, > AVKit::FrameType > type ) const > { > if( type == FRAME_TYPE_AUTO_GOP ) > { > if( (currentFrameNum % intraPeriod) == 0 ) > { > if( currentFrameNum == 0 ) > return FRAME_IDR; > else return FRAME_I; > } > > > return FRAME_P; > } > else > { > if( type == FRAME_TYPE_KEY ) > { > if( currentFrameNum == 0 ) > return FRAME_IDR; > else return FRAME_I; > } > else return FRAME_P; > } > } > > > void VAH264Encoder::_UpdateReferenceFrames() > { > _currentCurrPic.flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; > _numShortTerm++; > > > if( _numShortTerm > SURFACE_NUM ) > _numShortTerm = SURFACE_NUM; > > > for( int i = _numShortTerm - 1; i > 0; i-- ) > _referenceFrames[i] = _referenceFrames[i-1]; > > > _referenceFrames[0] = _currentCurrPic; > > > _currentFrameNum++; > > > if( _currentFrameNum > MAX_FRAME_NUM ) > _currentFrameNum = 0; > } > > > void VAH264Encoder::_UpdateRefPicList() > { > uint32_t current_poc = _currentCurrPic.TopFieldOrderCnt; > > > if( _currentFrameType == FRAME_P ) > memcpy( _refPicListP, _referenceFrames, _numShortTerm * > sizeof(VAPictureH264)); > } > > > void VAH264Encoder::_RenderSequence() > { > VABufferID seq_param_buf, rc_param_buf, misc_param_tmpbuf, > render_id[2]; > VAStatus status; > VAEncMiscParameterBuffer *misc_param, *misc_param_tmp; > VAEncMiscParameterRateControl *misc_rate_ctrl; > > > _seqParam.level_idc = 41 /*SH_LEVEL_3*/; > _seqParam.picture_width_in_mbs = _frameWidthMBAligned / 16; > _seqParam.picture_height_in_mbs = _frameHeightMBAligned / 16; > // _seqParam.bits_per_second = _frameBitRate * 1024 * 8; > _seqParam.bits_per_second = _frameBitRate / 8; > _seqParam.intra_period = _intraPeriod; > _seqParam.intra_idr_period = _intraPeriod * 64; > _seqParam.ip_period = 1; > > > _seqParam.max_num_ref_frames = NUM_REFERENCE_FRAMES; > _seqParam.seq_fields.bits.frame_mbs_only_flag = 1; > _seqParam.time_scale = 900; > _seqParam.num_units_in_tick = _timeBaseDen; > _seqParam.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = > LOG_2_MAX_PIC_ORDER_CNT_LSB - 4; > _seqParam.seq_fields.bits.log2_max_frame_num_minus4 = > LOG_2_MAX_FRAME_NUM - 4; > _seqParam.seq_fields.bits.frame_mbs_only_flag = 1; > _seqParam.seq_fields.bits.chroma_format_idc = 1; > _seqParam.seq_fields.bits.direct_8x8_inference_flag = 1; > > > if( _frameWidth != _frameWidthMBAligned || _frameHeight != > _frameHeightMBAligned ) > { > _seqParam.frame_cropping_flag = 1; > _seqParam.frame_crop_left_offset = 0; > _seqParam.frame_crop_right_offset = (_frameWidthMBAligned - > _frameWidth) / 2; > _seqParam.frame_crop_top_offset = 0; > _seqParam.frame_crop_bottom_offset = (_frameHeightMBAligned - > _frameHeight) / 2; > } > > > status = vaCreateBuffer( _display, > _contextID, > VAEncSequenceParameterBufferType, > sizeof(_seqParam), > 1, > &_seqParam, > &seq_param_buf ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(status) )); > > > // Rate control... > > > status = vaCreateBuffer( _display, > _contextID, > VAEncMiscParameterBufferType, > sizeof(VAEncMiscParameterBuffer) + > sizeof(VAEncMiscParameterRateControl), > 1, > NULL, > &rc_param_buf ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(status) )); > > > vaMapBuffer( _display, rc_param_buf,(void **)&misc_param); > if( !misc_param ) > X_THROW(( "Unable to vaMapBuffer." )); > > > misc_param->type = VAEncMiscParameterTypeRateControl; > misc_rate_ctrl = (VAEncMiscParameterRateControl > *)misc_param->data; > > > memset( misc_rate_ctrl, 0, sizeof(*misc_rate_ctrl) ); > > > // misc_rate_ctrl->bits_per_second = _frameBitRate * 1024 * 8; > misc_rate_ctrl->bits_per_second = _frameBitRate / 8; > misc_rate_ctrl->target_percentage = 66; > misc_rate_ctrl->window_size = 1000; > misc_rate_ctrl->initial_qp = 26; > misc_rate_ctrl->min_qp = 1; > misc_rate_ctrl->basic_unit_size = 0; > > > vaUnmapBuffer( _display, rc_param_buf ); > > > // Push buffers to hardware... > > > render_id[0] = seq_param_buf; > render_id[1] = rc_param_buf; > > > // According to documentation, vaRenderPicture recycles the > buffers given to it > // so we apparently do not owe vaDestroyBuffers() for the above > buffers. > > > status = vaRenderPicture( _display, _contextID, &render_id[0], > 2 ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaRenderPicture (%s).", > vaErrorStr(status) )); > } > > > int32_t VAH264Encoder::_CalcPOC( int32_t picOrderCntLSB ) > { > static int picOrderCntMsbRef = 0, picOrderCntLsbRef = 0; > int prevPicOrderCntMsb = 0, prevPicOrderCntLsb = 0; > int picOrderCntMsb = 0, topFieldOrderCnt = 0; > > > if( _currentFrameType == FRAME_IDR ) > prevPicOrderCntMsb = prevPicOrderCntLsb = 0; > else { > prevPicOrderCntMsb = picOrderCntMsbRef; > prevPicOrderCntLsb = picOrderCntLsbRef; > } > > > if( (picOrderCntLSB < prevPicOrderCntLsb) && > ((prevPicOrderCntLsb - picOrderCntLSB) >= > (int)(MAX_PIC_ORDER_CNT_LSB / 2))) > picOrderCntMsb = prevPicOrderCntMsb + MAX_PIC_ORDER_CNT_LSB; > else if( (picOrderCntLSB > prevPicOrderCntLsb) && > ((picOrderCntLSB - prevPicOrderCntLsb) > > (int)(MAX_PIC_ORDER_CNT_LSB / 2))) > picOrderCntMsb = prevPicOrderCntMsb - MAX_PIC_ORDER_CNT_LSB; > else > picOrderCntMsb = prevPicOrderCntMsb; > > > topFieldOrderCnt = picOrderCntMsb + picOrderCntLSB; > > > picOrderCntMsbRef = picOrderCntMsb; > picOrderCntLsbRef = picOrderCntLSB; > > > return topFieldOrderCnt; > } > > > void VAH264Encoder::_RenderPicture( bool done ) > { > VABufferID pic_param_buf; > > > _picParam.CurrPic.picture_id = _refSurfaceIDs[(_currentFrameNum % > SURFACE_NUM)]; > _picParam.CurrPic.frame_idx = _currentFrameNum; > _picParam.CurrPic.flags = 0; > _picParam.CurrPic.TopFieldOrderCnt = > _CalcPOC((_currentFrameNum - _currentIDRDisplay) % > MAX_PIC_ORDER_CNT_LSB); > _picParam.CurrPic.BottomFieldOrderCnt = > _picParam.CurrPic.TopFieldOrderCnt; > > > _currentCurrPic = _picParam.CurrPic; > > > memcpy( _picParam.ReferenceFrames, > _referenceFrames, > _numShortTerm*sizeof(VAPictureH264) ); > > > for (int i = _numShortTerm; i < SURFACE_NUM; i++) > { > _picParam.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE; > _picParam.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; > } > > > _picParam.pic_fields.bits.idr_pic_flag = (_currentFrameType == > FRAME_IDR); > _picParam.pic_fields.bits.reference_pic_flag = 1; > _picParam.pic_fields.bits.entropy_coding_mode_flag = > _h264EntropyMode; > _picParam.pic_fields.bits.deblocking_filter_control_present_flag = > 1; > _picParam.frame_num = _currentFrameNum; > _picParam.coded_buf = _codedBufID; > _picParam.last_picture = (done)?1:0; > _picParam.pic_init_qp = 26; > > > VAStatus status = vaCreateBuffer( _display, > _contextID, > VAEncPictureParameterBufferType, > sizeof(_picParam), > 1, > &_picParam, > &pic_param_buf ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(status) )); > > > status = vaRenderPicture( _display, > _contextID, > &pic_param_buf, > 1 ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaRenderPicture (%s).", > vaErrorStr(status) )); > } > > > void VAH264Encoder::_RenderPackedPPS() > { > BitStream ppsBS; > BuildPackedPicBuffer( ppsBS, _picParam ); > > > VAEncPackedHeaderParameterBuffer packedheader_param_buffer; > packedheader_param_buffer.type = VAEncPackedHeaderPicture; > packedheader_param_buffer.bit_length = ppsBS.SizeInBits(); > packedheader_param_buffer.has_emulation_bytes = 0; > > > VABufferID packedpic_para_bufid; > > > VAStatus va_status = vaCreateBuffer( _display, > _contextID, > > VAEncPackedHeaderParameterBufferType, > > sizeof(packedheader_param_buffer), > 1, > &packedheader_param_buffer, > &packedpic_para_bufid ); > > > if( va_status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(va_status) )); > > > VABufferID packedpic_data_bufid; > > > va_status = vaCreateBuffer( _display, > _contextID, > VAEncPackedHeaderDataBufferType, > (ppsBS.SizeInBits() + 7) / 8, > 1, > ppsBS.Map(), > &packedpic_data_bufid ); > > > if( va_status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(va_status) )); > > > VABufferID render_id[2]; > render_id[0] = packedpic_para_bufid; > render_id[1] = packedpic_data_bufid; > va_status = vaRenderPicture( _display, _contextID, render_id, 2 ); > > > if( va_status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaRenderPicture (%s).", > vaErrorStr(va_status) )); > } > > > void VAH264Encoder::_RenderPackedSPS() > { > BitStream seqBS; > BuildPackedSeqBuffer( seqBS, > _seqParam, > _h264Profile, > _constraintSetFlag, > _timeBaseNum, > _timeBaseDen, > _frameBitRate / 8 ); > // _frameBitRate * 1024 * 8 ); > > > VAEncPackedHeaderParameterBuffer packedheader_param_buffer; > packedheader_param_buffer.type = VAEncPackedHeaderSequence; > packedheader_param_buffer.bit_length = seqBS.SizeInBits(); > packedheader_param_buffer.has_emulation_bytes = 0; > > > VABufferID packedseq_para_bufid; > > > VAStatus va_status = vaCreateBuffer( _display, > _contextID, > > VAEncPackedHeaderParameterBufferType, > > sizeof(packedheader_param_buffer), > 1, > &packedheader_param_buffer, > &packedseq_para_bufid ); > > > if( va_status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(va_status) )); > > > VABufferID packedseq_data_bufid; > > > va_status = vaCreateBuffer( _display, > _contextID, > VAEncPackedHeaderDataBufferType, > (seqBS.SizeInBits() + 7) / 8, > 1, > seqBS.Map(), > &packedseq_data_bufid); > > > if( va_status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(va_status) )); > > > VABufferID render_id[2]; > render_id[0] = packedseq_para_bufid; > render_id[1] = packedseq_data_bufid; > > > va_status = vaRenderPicture( _display, _contextID, render_id, 2 ); > > > if( va_status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaRenderPicture (%s).", > vaErrorStr(va_status) )); > } > > > void VAH264Encoder::_RenderSlice() > { > VABufferID slice_param_buf; > > > _UpdateRefPicList(); > > > /* one frame, one slice */ > _sliceParam.macroblock_address = 0; > _sliceParam.num_macroblocks = _frameWidthMBAligned * > _frameHeightMBAligned/(16*16); /*Measured by MB*/ > _sliceParam.slice_type = (_currentFrameType == > FRAME_IDR)?2:_currentFrameType; > _sliceParam.slice_qp_delta = 0; > > > if( _currentFrameType == FRAME_IDR ) > { > if( _currentFrameNum != 0 ) > ++_sliceParam.idr_pic_id; > } > else if( _currentFrameType == FRAME_P ) > { > int refpiclist0_max = H264_MAXREF & 0xffff; > memcpy( _sliceParam.RefPicList0, > _refPicListP, > refpiclist0_max*sizeof(VAPictureH264) ); > > > for (int i = refpiclist0_max; i < 32; i++) > { > _sliceParam.RefPicList0[i].picture_id = > VA_INVALID_SURFACE; > _sliceParam.RefPicList0[i].flags = > VA_PICTURE_H264_INVALID; > } > } > > > _sliceParam.slice_alpha_c0_offset_div2 = 0; > _sliceParam.slice_beta_offset_div2 = 0; > _sliceParam.direct_spatial_mv_pred_flag = 1; > _sliceParam.pic_order_cnt_lsb = (_currentFrameNum - > _currentIDRDisplay) % MAX_PIC_ORDER_CNT_LSB; > > > VAStatus status = vaCreateBuffer( _display, > _contextID, > VAEncSliceParameterBufferType, > sizeof(_sliceParam), > 1, > &_sliceParam, > &slice_param_buf ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(status) )); > > > status = vaRenderPicture( _display, > _contextID, > &slice_param_buf, > 1 ); > if( status != VA_STATUS_SUCCESS ) > X_THROW(( "Unable to vaCreateBuffer (%s).", > vaErrorStr(status) )); > } > > > void VAH264Encoder::_UploadImage( uint8_t* yv12, VAImage& image, > uint16_t width, uint16_t height ) > { > assert( image.num_planes == 2 ); > > > unsigned char* p = NULL; > vaMapBuffer( _display, image.buf, (void **)&p ); > if( !p ) > X_THROW(( "Unable to vaMapBuffer." )); > > > uint8_t* sy = yv12; > uint8_t* su = sy + (width * height); > uint8_t* sv = su + ((width/2)*(height/2)); > > > uint8_t* dy = p + image.offsets[0]; > uint8_t* duv = p + image.offsets[1]; > > > for( size_t i = 0; i < height; i++ ) > { > memcpy( dy, sy, width ); > dy += image.pitches[0]; > sy += width; > } > > > for( size_t i = 0; i < (height/2); i++ ) > { > uint8_t* dst = duv; > > > for( size_t ii = 0; ii < (width/2); ii++ ) > { > *dst = *su; > dst++; > su++; > > > *dst = *sv; > dst++; > sv++; > } > > > duv += image.pitches[1]; > } > > > vaUnmapBuffer( _display, image.buf ); > } > > > _______________________________________________ > Libva mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/libva _______________________________________________ Libva mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libva
