VideoEncoderVP8.cpp revision 82b428e49a70ddc051a36d2b3a25d90db79770dc
1/* 2* Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 3* 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15*/ 16 17#include <string.h> 18#include <stdlib.h> 19#include "VideoEncoderLog.h" 20#include "VideoEncoderVP8.h" 21#include <va/va_tpi.h> 22#include <va/va_enc_vp8.h> 23 24VideoEncoderVP8::VideoEncoderVP8() 25 :VideoEncoderBase() { 26 27 mVideoParamsVP8.profile = 0; 28 mVideoParamsVP8.error_resilient = 0; 29 mVideoParamsVP8.num_token_partitions = 4; 30 mVideoParamsVP8.kf_auto = 0; 31 mVideoParamsVP8.kf_min_dist = 128; 32 mVideoParamsVP8.kf_max_dist = 128; 33 mVideoParamsVP8.min_qp = 0; 34 mVideoParamsVP8.max_qp = 63; 35 mVideoParamsVP8.init_qp = 26; 36 mVideoParamsVP8.rc_undershoot = 100; 37 mVideoParamsVP8.rc_overshoot = 100; 38 mVideoParamsVP8.hrd_buf_size = 1000; 39 mVideoParamsVP8.hrd_buf_initial_fullness = 500; 40 mVideoParamsVP8.hrd_buf_optimal_fullness = 600; 41 mVideoParamsVP8.max_frame_size_ratio = 0; 42 43 mVideoConfigVP8.force_kf = 0; 44 mVideoConfigVP8.refresh_entropy_probs = 0; 45 mVideoConfigVP8.value = 0; 46 mVideoConfigVP8.sharpness_level = 2; 47 48 mVideoConfigVP8ReferenceFrame.no_ref_last = 0; 49 mVideoConfigVP8ReferenceFrame.no_ref_gf = 0; 50 mVideoConfigVP8ReferenceFrame.no_ref_arf = 0; 51 mVideoConfigVP8ReferenceFrame.refresh_last = 1; 52 mVideoConfigVP8ReferenceFrame.refresh_golden_frame = 1; 53 mVideoConfigVP8ReferenceFrame.refresh_alternate_frame = 1; 54 55 mComParams.profile = VAProfileVP8Version0_3; 56} 57 58VideoEncoderVP8::~VideoEncoderVP8() { 59} 60 61Encode_Status VideoEncoderVP8::start() { 62 63 Encode_Status ret = ENCODE_SUCCESS; 64 LOG_V( "Begin\n"); 65 66 ret = VideoEncoderBase::start (); 67 CHECK_ENCODE_STATUS_RETURN("VideoEncoderBase::start"); 68 69 if (mComParams.rcMode == VA_RC_VCM) { 70 mRenderBitRate = false; 71 } 72 73 LOG_V( "end\n"); 74 return ret; 75} 76 77 78Encode_Status VideoEncoderVP8::renderSequenceParams() { 79 Encode_Status ret = ENCODE_SUCCESS; 80 VAStatus vaStatus = VA_STATUS_SUCCESS; 81 VAEncSequenceParameterBufferVP8 vp8SeqParam = VAEncSequenceParameterBufferVP8(); 82 83 LOG_V( "Begin\n"); 84 85 vp8SeqParam.frame_width = mComParams.resolution.width; 86 vp8SeqParam.frame_height = mComParams.resolution.height; 87 vp8SeqParam.error_resilient = mVideoParamsVP8.error_resilient; 88 vp8SeqParam.kf_auto = mVideoParamsVP8.kf_auto; 89 vp8SeqParam.kf_min_dist = mVideoParamsVP8.kf_min_dist; 90 vp8SeqParam.kf_max_dist = mVideoParamsVP8.kf_max_dist; 91 vp8SeqParam.bits_per_second = mComParams.rcParams.bitRate; 92 memcpy(vp8SeqParam.reference_frames, mAutoRefSurfaces, sizeof(mAutoRefSurfaces) * mAutoReferenceSurfaceNum); 93 94 vaStatus = vaCreateBuffer( 95 mVADisplay, mVAContext, 96 VAEncSequenceParameterBufferType, 97 sizeof(vp8SeqParam), 98 1, &vp8SeqParam, 99 &mSeqParamBuf); 100 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 101 102 vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mSeqParamBuf, 1); 103 CHECK_VA_STATUS_RETURN("vaRenderPicture"); 104 105 LOG_V( "End\n"); 106 return ret; 107} 108 109Encode_Status VideoEncoderVP8::renderPictureParams(EncodeTask *task) { 110 Encode_Status ret = ENCODE_SUCCESS; 111 VAStatus vaStatus = VA_STATUS_SUCCESS; 112 VAEncPictureParameterBufferVP8 vp8PicParam = VAEncPictureParameterBufferVP8(); 113 LOG_V( "Begin\n"); 114 115 vp8PicParam.coded_buf = task->coded_buffer; 116 vp8PicParam.pic_flags.value = 0; 117 vp8PicParam.ref_flags.bits.force_kf = mVideoConfigVP8.force_kf; //0; 118 if(!vp8PicParam.ref_flags.bits.force_kf) { 119 vp8PicParam.ref_flags.bits.no_ref_last = mVideoConfigVP8ReferenceFrame.no_ref_last; 120 vp8PicParam.ref_flags.bits.no_ref_arf = mVideoConfigVP8ReferenceFrame.no_ref_arf; 121 vp8PicParam.ref_flags.bits.no_ref_gf = mVideoConfigVP8ReferenceFrame.no_ref_gf; 122 } 123 vp8PicParam.pic_flags.bits.refresh_entropy_probs = 0; 124 vp8PicParam.sharpness_level = 2; 125 vp8PicParam.pic_flags.bits.num_token_partitions = 2; 126 vp8PicParam.pic_flags.bits.refresh_last = mVideoConfigVP8ReferenceFrame.refresh_last; 127 vp8PicParam.pic_flags.bits.refresh_golden_frame = mVideoConfigVP8ReferenceFrame.refresh_golden_frame; 128 vp8PicParam.pic_flags.bits.refresh_alternate_frame = mVideoConfigVP8ReferenceFrame.refresh_alternate_frame; 129 130 vaStatus = vaCreateBuffer( 131 mVADisplay, mVAContext, 132 VAEncPictureParameterBufferType, 133 sizeof(vp8PicParam), 134 1, &vp8PicParam, 135 &mPicParamBuf); 136 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 137 138 vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mPicParamBuf, 1); 139 CHECK_VA_STATUS_RETURN("vaRenderPicture"); 140 141 LOG_V( "End\n"); 142 return ret; 143} 144 145Encode_Status VideoEncoderVP8::renderRCParams(uint32_t layer_id, bool total_bitrate) 146{ 147 VABufferID rc_param_buf; 148 VAStatus vaStatus = VA_STATUS_SUCCESS; 149 VAEncMiscParameterBuffer *misc_param; 150 VAEncMiscParameterRateControl *misc_rate_ctrl; 151 152 vaStatus = vaCreateBuffer(mVADisplay, mVAContext, 153 VAEncMiscParameterBufferType, 154 sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterRateControl), 155 1,NULL,&rc_param_buf); 156 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 157 158 vaMapBuffer(mVADisplay, rc_param_buf,(void **)&misc_param); 159 160 misc_param->type = VAEncMiscParameterTypeRateControl; 161 misc_rate_ctrl = (VAEncMiscParameterRateControl *)misc_param->data; 162 memset(misc_rate_ctrl, 0, sizeof(*misc_rate_ctrl)); 163 164 if(total_bitrate) 165 misc_rate_ctrl->bits_per_second = mComParams.rcParams.bitRate; 166 else 167 { 168 misc_rate_ctrl->rc_flags.bits.temporal_id = layer_id; 169 if(mTemporalLayerBitrateFramerate[layer_id].bitRate != 0) 170 misc_rate_ctrl->bits_per_second = mTemporalLayerBitrateFramerate[layer_id].bitRate; 171 } 172 173 misc_rate_ctrl->target_percentage = 100; 174 misc_rate_ctrl->window_size = 1000; 175 misc_rate_ctrl->initial_qp = mVideoParamsVP8.init_qp; 176 misc_rate_ctrl->min_qp = mVideoParamsVP8.min_qp; 177 misc_rate_ctrl->basic_unit_size = 0; 178 misc_rate_ctrl->max_qp = mVideoParamsVP8.max_qp; 179 180 vaUnmapBuffer(mVADisplay, rc_param_buf); 181 182 vaStatus = vaRenderPicture(mVADisplay,mVAContext, &rc_param_buf, 1); 183 CHECK_VA_STATUS_RETURN("vaRenderPicture");; 184 return 0; 185} 186 187Encode_Status VideoEncoderVP8::renderFrameRateParams(uint32_t layer_id, bool total_framerate) 188{ 189 VABufferID framerate_param_buf; 190 VAStatus vaStatus = VA_STATUS_SUCCESS; 191 VAEncMiscParameterBuffer *misc_param; 192 VAEncMiscParameterFrameRate * misc_framerate; 193 uint32_t frameRateNum = mComParams.frameRate.frameRateNum; 194 uint32_t frameRateDenom = mComParams.frameRate.frameRateDenom; 195 196 vaStatus = vaCreateBuffer(mVADisplay, mVAContext, 197 VAEncMiscParameterBufferType, 198 sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterFrameRate), 199 1,NULL,&framerate_param_buf); 200 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 201 202 vaMapBuffer(mVADisplay, framerate_param_buf,(void **)&misc_param); 203 misc_param->type = VAEncMiscParameterTypeFrameRate; 204 misc_framerate = (VAEncMiscParameterFrameRate *)misc_param->data; 205 memset(misc_framerate, 0, sizeof(*misc_framerate)); 206 207 if(total_framerate) 208 misc_framerate->framerate = (unsigned int) (frameRateNum + frameRateDenom /2) / frameRateDenom; 209 else 210 { 211 misc_framerate->framerate_flags.bits.temporal_id = layer_id; 212 if(mTemporalLayerBitrateFramerate[layer_id].frameRate != 0) 213 misc_framerate->framerate = mTemporalLayerBitrateFramerate[layer_id].frameRate; 214 } 215 216 vaUnmapBuffer(mVADisplay, framerate_param_buf); 217 218 vaStatus = vaRenderPicture(mVADisplay,mVAContext, &framerate_param_buf, 1); 219 CHECK_VA_STATUS_RETURN("vaRenderPicture");; 220 221 return 0; 222} 223 224Encode_Status VideoEncoderVP8::renderHRDParams(void) 225{ 226 VABufferID hrd_param_buf; 227 VAStatus vaStatus = VA_STATUS_SUCCESS; 228 VAEncMiscParameterBuffer *misc_param; 229 VAEncMiscParameterHRD * misc_hrd; 230 vaStatus = vaCreateBuffer(mVADisplay, mVAContext, 231 VAEncMiscParameterBufferType, 232 sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterHRD), 233 1,NULL,&hrd_param_buf); 234 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 235 236 vaMapBuffer(mVADisplay, hrd_param_buf,(void **)&misc_param); 237 misc_param->type = VAEncMiscParameterTypeHRD; 238 misc_hrd = (VAEncMiscParameterHRD *)misc_param->data; 239 memset(misc_hrd, 0, sizeof(*misc_hrd)); 240 misc_hrd->buffer_size = 1000; 241 misc_hrd->initial_buffer_fullness = 500; 242 misc_hrd->optimal_buffer_fullness = 600; 243 vaUnmapBuffer(mVADisplay, hrd_param_buf); 244 245 vaStatus = vaRenderPicture(mVADisplay,mVAContext, &hrd_param_buf, 1); 246 CHECK_VA_STATUS_RETURN("vaRenderPicture");; 247 248 return 0; 249} 250 251Encode_Status VideoEncoderVP8::renderMaxFrameSizeParams(void) 252{ 253 VABufferID max_frame_size_param_buf; 254 VAStatus vaStatus = VA_STATUS_SUCCESS; 255 VAEncMiscParameterBuffer *misc_param; 256 VAEncMiscParameterBufferMaxFrameSize * misc_maxframesize; 257 unsigned int frameRateNum = mComParams.frameRate.frameRateNum; 258 unsigned int frameRateDenom = mComParams.frameRate.frameRateDenom; 259 unsigned int frameRate = (unsigned int)(frameRateNum + frameRateDenom /2); 260 unsigned int bitRate = mComParams.rcParams.bitRate; 261 262 vaStatus = vaCreateBuffer(mVADisplay, mVAContext, 263 VAEncMiscParameterBufferType, 264 sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterHRD), 265 1,NULL,&max_frame_size_param_buf); 266 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 267 268 vaMapBuffer(mVADisplay, max_frame_size_param_buf,(void **)&misc_param); 269 misc_param->type = VAEncMiscParameterTypeMaxFrameSize; 270 misc_maxframesize = (VAEncMiscParameterBufferMaxFrameSize *)misc_param->data; 271 memset(misc_maxframesize, 0, sizeof(*misc_maxframesize)); 272 misc_maxframesize->max_frame_size = (unsigned int)((bitRate/frameRate) * mVideoParamsVP8.max_frame_size_ratio); 273 vaUnmapBuffer(mVADisplay, max_frame_size_param_buf); 274 275 vaStatus = vaRenderPicture(mVADisplay,mVAContext, &max_frame_size_param_buf, 1); 276 CHECK_VA_STATUS_RETURN("vaRenderPicture");; 277 278 return 0; 279} 280 281Encode_Status VideoEncoderVP8::renderLayerStructureParam(void) 282{ 283 VABufferID layer_struc_buf; 284 VAStatus vaStatus = VA_STATUS_SUCCESS; 285 VAEncMiscParameterBuffer *misc_param; 286 VAEncMiscParameterTemporalLayerStructure *misc_layer_struc; 287 uint32_t i; 288 289 vaStatus = vaCreateBuffer(mVADisplay, mVAContext, 290 VAEncMiscParameterBufferType, 291 sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterTemporalLayerStructure), 292 1, NULL, &layer_struc_buf); 293 294 CHECK_VA_STATUS_RETURN("vaCreateBuffer"); 295 vaMapBuffer(mVADisplay, layer_struc_buf, (void **)&misc_param); 296 misc_param->type = VAEncMiscParameterTypeTemporalLayerStructure; 297 misc_layer_struc = (VAEncMiscParameterTemporalLayerStructure *)misc_param->data; 298 memset(misc_layer_struc, 0, sizeof(*misc_layer_struc)); 299 300 misc_layer_struc->number_of_layers = mComParams.numberOfLayer; 301 misc_layer_struc->periodicity = mComParams.nPeriodicity; 302 LOGE("renderLayerStructureParam misc_layer_struc->number_of_layers is %d",misc_layer_struc->number_of_layers); 303 304 for(i=0;i<mComParams.nPeriodicity;i++) 305 { 306 misc_layer_struc->layer_id[i] = mComParams.nLayerID[i]; 307 } 308 309 vaUnmapBuffer(mVADisplay, layer_struc_buf); 310 311 vaStatus = vaRenderPicture(mVADisplay, mVAContext, &layer_struc_buf, 1); 312 CHECK_VA_STATUS_RETURN("vaRenderPicture");; 313 314 return 0; 315} 316 317 318Encode_Status VideoEncoderVP8::sendEncodeCommand(EncodeTask *task) { 319 320 Encode_Status ret = ENCODE_SUCCESS; 321 uint32_t i; 322 323 if (mFrameNum == 0) { 324 ret = renderSequenceParams(); 325 ret = renderFrameRateParams(0,true); 326 ret = renderRCParams(0,true); 327 ret = renderHRDParams(); 328 ret = renderMaxFrameSizeParams(); 329 if(mRenderMultiTemporal) 330 { 331 ret = renderLayerStructureParam(); 332 mRenderMultiTemporal = false; 333 334 } 335 336 if(mComParams.numberOfLayer > 1) 337 for(i=0;i<mComParams.numberOfLayer;i++) 338 { 339 ret = renderFrameRateParams(i, false); 340 ret = renderRCParams(i, false); 341 } 342 343 CHECK_ENCODE_STATUS_RETURN("renderSequenceParams"); 344 } 345 346 if (mRenderBitRate){ 347 ret = renderRCParams(0,true); 348 CHECK_ENCODE_STATUS_RETURN("renderRCParams"); 349 350 mRenderBitRate = false; 351 } 352 353 if (mRenderFrameRate) { 354 ret = renderFrameRateParams(0,true); 355 CHECK_ENCODE_STATUS_RETURN("renderFrameRateParams"); 356 357 mRenderFrameRate = false; 358 } 359 360 if (mRenderMaxFrameSize) { 361 ret = renderMaxFrameSizeParams(); 362 CHECK_ENCODE_STATUS_RETURN("renderMaxFrameSizeParams"); 363 364 mRenderMaxFrameSize = false; 365 } 366 367 ret = renderPictureParams(task); 368 CHECK_ENCODE_STATUS_RETURN("renderPictureParams"); 369 370 if(mForceKFrame) { 371 mVideoConfigVP8.force_kf = 0;//rest it as default value 372 mForceKFrame = false; 373 } 374 375 LOG_V( "End\n"); 376 return ret; 377} 378 379 380Encode_Status VideoEncoderVP8::derivedSetParams(VideoParamConfigSet *videoEncParams) { 381 382 CHECK_NULL_RETURN_IFFAIL(videoEncParams); 383 VideoParamsVP8 *encParamsVP8 = reinterpret_cast <VideoParamsVP8*> (videoEncParams); 384 385 if (encParamsVP8->size != sizeof(VideoParamsVP8)) { 386 return ENCODE_INVALID_PARAMS; 387 } 388 389 mVideoParamsVP8 = *encParamsVP8; 390 return ENCODE_SUCCESS; 391} 392 393Encode_Status VideoEncoderVP8::derivedGetParams(VideoParamConfigSet *videoEncParams) { 394 395 CHECK_NULL_RETURN_IFFAIL(videoEncParams); 396 VideoParamsVP8 *encParamsVP8 = reinterpret_cast <VideoParamsVP8*> (videoEncParams); 397 398 if (encParamsVP8->size != sizeof(VideoParamsVP8)) { 399 return ENCODE_INVALID_PARAMS; 400 } 401 402 *encParamsVP8 = mVideoParamsVP8; 403 return ENCODE_SUCCESS; 404} 405 406Encode_Status VideoEncoderVP8::derivedGetConfig(VideoParamConfigSet *videoEncConfig) { 407 408 int layer_id; 409 CHECK_NULL_RETURN_IFFAIL(videoEncConfig); 410 411 switch (videoEncConfig->type) 412 { 413 case VideoConfigTypeVP8:{ 414 VideoConfigVP8 *encConfigVP8 = 415 reinterpret_cast<VideoConfigVP8*> (videoEncConfig); 416 417 if (encConfigVP8->size != sizeof(VideoConfigVP8)) { 418 return ENCODE_INVALID_PARAMS; 419 } 420 421 *encConfigVP8 = mVideoConfigVP8; 422 } 423 break; 424 425 case VideoConfigTypeVP8ReferenceFrame:{ 426 427 VideoConfigVP8ReferenceFrame *encConfigVP8ReferenceFrame = 428 reinterpret_cast<VideoConfigVP8ReferenceFrame*> (videoEncConfig); 429 430 if (encConfigVP8ReferenceFrame->size != sizeof(VideoConfigVP8ReferenceFrame)) { 431 return ENCODE_INVALID_PARAMS; 432 } 433 434 *encConfigVP8ReferenceFrame = mVideoConfigVP8ReferenceFrame; 435 436 } 437 break; 438 439 case VideoConfigTypeVP8MaxFrameSizeRatio :{ 440 441 VideoConfigVP8MaxFrameSizeRatio *encConfigVP8MaxFrameSizeRatio = 442 reinterpret_cast<VideoConfigVP8MaxFrameSizeRatio*> (videoEncConfig); 443 444 if (encConfigVP8MaxFrameSizeRatio->size != sizeof(VideoConfigVP8MaxFrameSizeRatio)) { 445 return ENCODE_INVALID_PARAMS; 446 } 447 448 encConfigVP8MaxFrameSizeRatio->max_frame_size_ratio = mVideoParamsVP8.max_frame_size_ratio; 449 } 450 break; 451 452 default: { 453 LOG_E ("Invalid Config Type"); 454 break; 455 } 456 } 457 458 return ENCODE_SUCCESS; 459} 460 461Encode_Status VideoEncoderVP8::derivedSetConfig(VideoParamConfigSet *videoEncConfig) { 462 463 int layer_id; 464 CHECK_NULL_RETURN_IFFAIL(videoEncConfig); 465 466 switch (videoEncConfig->type) 467 { 468 case VideoConfigTypeVP8:{ 469 VideoConfigVP8 *encConfigVP8 = 470 reinterpret_cast<VideoConfigVP8*> (videoEncConfig); 471 472 if (encConfigVP8->size != sizeof(VideoConfigVP8)) { 473 return ENCODE_INVALID_PARAMS; 474 } 475 476 mVideoConfigVP8 = *encConfigVP8; 477 } 478 break; 479 480 case VideoConfigTypeVP8ReferenceFrame:{ 481 VideoConfigVP8ReferenceFrame *encConfigVP8ReferenceFrame = 482 reinterpret_cast<VideoConfigVP8ReferenceFrame*> (videoEncConfig); 483 484 if (encConfigVP8ReferenceFrame->size != sizeof(VideoConfigVP8ReferenceFrame)) { 485 return ENCODE_INVALID_PARAMS; 486 } 487 488 mVideoConfigVP8ReferenceFrame = *encConfigVP8ReferenceFrame; 489 490 } 491 break; 492 493 case VideoConfigTypeVP8MaxFrameSizeRatio:{ 494 VideoConfigVP8MaxFrameSizeRatio *encConfigVP8MaxFrameSizeRatio = 495 reinterpret_cast<VideoConfigVP8MaxFrameSizeRatio*> (videoEncConfig); 496 497 if (encConfigVP8MaxFrameSizeRatio->size != sizeof(VideoConfigVP8MaxFrameSizeRatio)) { 498 return ENCODE_INVALID_PARAMS; 499 } 500 501 mVideoParamsVP8.max_frame_size_ratio = encConfigVP8MaxFrameSizeRatio->max_frame_size_ratio; 502 mRenderMaxFrameSize = true; 503 } 504 break; 505 506 case VideoConfigTypeIDRRequest:{ 507 VideoParamConfigSet *encConfigVP8KFrameRequest = 508 reinterpret_cast<VideoParamConfigSet*> (videoEncConfig); 509 510 mVideoConfigVP8.force_kf = 1; 511 mForceKFrame = true; 512 } 513 break; 514 515 default: { 516 LOG_E ("Invalid Config Type"); 517 break; 518 } 519 } 520 return ENCODE_SUCCESS; 521} 522