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
VideoEncoderVP8()24 VideoEncoderVP8::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
~VideoEncoderVP8()58 VideoEncoderVP8::~VideoEncoderVP8() {
59 }
60
start()61 Encode_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
renderSequenceParams()78 Encode_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
renderPictureParams(EncodeTask * task)109 Encode_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
renderRCParams(uint32_t layer_id,bool total_bitrate)145 Encode_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
renderFrameRateParams(uint32_t layer_id,bool total_framerate)187 Encode_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
renderHRDParams(void)224 Encode_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
renderMaxFrameSizeParams(void)251 Encode_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
renderLayerStructureParam(void)281 Encode_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
sendEncodeCommand(EncodeTask * task)318 Encode_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
derivedSetParams(VideoParamConfigSet * videoEncParams)380 Encode_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
derivedGetParams(VideoParamConfigSet * videoEncParams)393 Encode_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
derivedGetConfig(VideoParamConfigSet * videoEncConfig)406 Encode_Status VideoEncoderVP8::derivedGetConfig(VideoParamConfigSet *videoEncConfig) {
407
408 CHECK_NULL_RETURN_IFFAIL(videoEncConfig);
409
410 switch (videoEncConfig->type)
411 {
412 case VideoConfigTypeVP8:{
413 VideoConfigVP8 *encConfigVP8 =
414 reinterpret_cast<VideoConfigVP8*> (videoEncConfig);
415
416 if (encConfigVP8->size != sizeof(VideoConfigVP8)) {
417 return ENCODE_INVALID_PARAMS;
418 }
419
420 *encConfigVP8 = mVideoConfigVP8;
421 }
422 break;
423
424 case VideoConfigTypeVP8ReferenceFrame:{
425
426 VideoConfigVP8ReferenceFrame *encConfigVP8ReferenceFrame =
427 reinterpret_cast<VideoConfigVP8ReferenceFrame*> (videoEncConfig);
428
429 if (encConfigVP8ReferenceFrame->size != sizeof(VideoConfigVP8ReferenceFrame)) {
430 return ENCODE_INVALID_PARAMS;
431 }
432
433 *encConfigVP8ReferenceFrame = mVideoConfigVP8ReferenceFrame;
434
435 }
436 break;
437
438 case VideoConfigTypeVP8MaxFrameSizeRatio :{
439
440 VideoConfigVP8MaxFrameSizeRatio *encConfigVP8MaxFrameSizeRatio =
441 reinterpret_cast<VideoConfigVP8MaxFrameSizeRatio*> (videoEncConfig);
442
443 if (encConfigVP8MaxFrameSizeRatio->size != sizeof(VideoConfigVP8MaxFrameSizeRatio)) {
444 return ENCODE_INVALID_PARAMS;
445 }
446
447 encConfigVP8MaxFrameSizeRatio->max_frame_size_ratio = mVideoParamsVP8.max_frame_size_ratio;
448 }
449 break;
450
451 default: {
452 LOG_E ("Invalid Config Type");
453 break;
454 }
455 }
456
457 return ENCODE_SUCCESS;
458 }
459
derivedSetConfig(VideoParamConfigSet * videoEncConfig)460 Encode_Status VideoEncoderVP8::derivedSetConfig(VideoParamConfigSet *videoEncConfig) {
461
462 CHECK_NULL_RETURN_IFFAIL(videoEncConfig);
463
464 switch (videoEncConfig->type)
465 {
466 case VideoConfigTypeVP8:{
467 VideoConfigVP8 *encConfigVP8 =
468 reinterpret_cast<VideoConfigVP8*> (videoEncConfig);
469
470 if (encConfigVP8->size != sizeof(VideoConfigVP8)) {
471 return ENCODE_INVALID_PARAMS;
472 }
473
474 mVideoConfigVP8 = *encConfigVP8;
475 }
476 break;
477
478 case VideoConfigTypeVP8ReferenceFrame:{
479 VideoConfigVP8ReferenceFrame *encConfigVP8ReferenceFrame =
480 reinterpret_cast<VideoConfigVP8ReferenceFrame*> (videoEncConfig);
481
482 if (encConfigVP8ReferenceFrame->size != sizeof(VideoConfigVP8ReferenceFrame)) {
483 return ENCODE_INVALID_PARAMS;
484 }
485
486 mVideoConfigVP8ReferenceFrame = *encConfigVP8ReferenceFrame;
487
488 }
489 break;
490
491 case VideoConfigTypeVP8MaxFrameSizeRatio:{
492 VideoConfigVP8MaxFrameSizeRatio *encConfigVP8MaxFrameSizeRatio =
493 reinterpret_cast<VideoConfigVP8MaxFrameSizeRatio*> (videoEncConfig);
494
495 if (encConfigVP8MaxFrameSizeRatio->size != sizeof(VideoConfigVP8MaxFrameSizeRatio)) {
496 return ENCODE_INVALID_PARAMS;
497 }
498
499 mVideoParamsVP8.max_frame_size_ratio = encConfigVP8MaxFrameSizeRatio->max_frame_size_ratio;
500 mRenderMaxFrameSize = true;
501 }
502 break;
503
504 case VideoConfigTypeIDRRequest:{
505 mVideoConfigVP8.force_kf = 1;
506 mForceKFrame = true;
507 }
508 break;
509
510 default: {
511 LOG_E ("Invalid Config Type");
512 break;
513 }
514 }
515 return ENCODE_SUCCESS;
516 }
517