1 /*
2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3  * Copyright (c) Imagination Technologies Limited, UK
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Elaine Wang <elaine.wang@intel.com>
27  *    Zeng Li <zeng.li@intel.com>
28  *    Edward Lin <edward.lin@intel.com>
29  *    Zhaohan Ren<zhaohan.ren@intel.com>
30  *
31  */
32 
33 
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <stdint.h>
38 #include <string.h>
39 
40 #include "psb_def.h"
41 #include "psb_surface.h"
42 #include "tng_cmdbuf.h"
43 #include "tng_hostcode.h"
44 #include "tng_hostheader.h"
45 #include "tng_H263ES.h"
46 #include "psb_drv_debug.h"
47 
48 #include "hwdefs/coreflags.h"
49 #include "hwdefs/topaz_vlc_regs.h"
50 #include "hwdefs/topaz_db_regs.h"
51 #include "hwdefs/topazhp_default_params.h"
52 
53 #define TOPAZ_H263_MAX_BITRATE 16000000
54 
55 #define INIT_CONTEXT_H263ES     context_ENC_p ctx = (context_ENC_p) obj_context->format_data
56 #define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
57 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id ))
58 
tng_H263ES_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib * attrib_list,int num_attribs)59 static void tng_H263ES_QueryConfigAttributes(
60     VAProfile __maybe_unused profile,
61     VAEntrypoint __maybe_unused entrypoint,
62     VAConfigAttrib *attrib_list,
63     int num_attribs)
64 {
65     int i;
66 
67     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
68 
69     /* RateControl attributes */
70     for (i = 0; i < num_attribs; i++) {
71         switch (attrib_list[i].type) {
72             case VAConfigAttribRTFormat:
73         break;
74 
75         case VAConfigAttribEncAutoReference:
76             attrib_list[i].value = 1;
77             break;
78 
79         case VAConfigAttribEncMaxRefFrames:
80             attrib_list[i].value = 2;
81             break;
82 
83         case VAConfigAttribRateControl:
84             attrib_list[i].value = VA_RC_NONE | VA_RC_CBR | VA_RC_VBR;
85             break;
86 
87         default:
88             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
89             break;
90         }
91     }
92 }
93 
94 
tng_H263ES_ValidateConfig(object_config_p obj_config)95 static VAStatus tng_H263ES_ValidateConfig(
96     object_config_p obj_config)
97 {
98     int i;
99     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
100     /* Check all attributes */
101     for (i = 0; i < obj_config->attrib_count; i++) {
102         switch (obj_config->attrib_list[i].type) {
103         case VAConfigAttribRTFormat:
104             /* Ignore */
105             break;
106         case VAConfigAttribRateControl:
107             break;
108         case VAConfigAttribEncAutoReference:
109             break;
110         case VAConfigAttribEncMaxRefFrames:
111             break;
112         default:
113             return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
114         }
115     }
116 
117     return VA_STATUS_SUCCESS;
118 }
119 
tng_H263ES_CreateContext(object_context_p obj_context,object_config_p obj_config)120 static VAStatus tng_H263ES_CreateContext(
121     object_context_p obj_context,
122     object_config_p obj_config)
123 {
124     VAStatus vaStatus = VA_STATUS_SUCCESS;
125     context_ENC_p ctx;
126 
127     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
128 
129     vaStatus = tng_CreateContext(obj_context, obj_config, 0);
130 
131     if (VA_STATUS_SUCCESS != vaStatus)
132         return VA_STATUS_ERROR_ALLOCATION_FAILED;
133 
134     ctx = (context_ENC_p) obj_context->format_data;
135     ctx->eStandard = IMG_STANDARD_H263;
136     ctx->eFormat = IMG_CODEC_PL12;                          // use default
137     ctx->bNoOffscreenMv = IMG_TRUE; //Default Value ?? Extended Parameter and bUseOffScreenMVUserSetting
138 
139     switch(ctx->sRCParams.eRCMode) {
140        case IMG_RCMODE_NONE:
141            ctx->eCodec = IMG_CODEC_H263_NO_RC;
142            break;
143        case IMG_RCMODE_VBR:
144            ctx->eCodec = IMG_CODEC_H263_VBR;
145            break;
146        case IMG_RCMODE_CBR:
147            ctx->eCodec = IMG_CODEC_H263_CBR;
148            break;
149        default:
150            drv_debug_msg(VIDEO_DEBUG_ERROR, "Unknown RCMode %08x\n", ctx->sRCParams.eRCMode);
151            break;
152     }
153 
154     ctx->bIsInterlaced = IMG_FALSE;
155     ctx->bIsInterleaved = IMG_FALSE;
156     ctx->ui16PictureHeight = ctx->ui16FrameHeight;
157 
158     //This parameter need not be exposed
159     ctx->ui8InterIntraIndex = 3;
160     ctx->ui8CodedSkippedIndex = 3;
161     ctx->bEnableHostQP = IMG_FALSE;
162     ctx->uMaxChunks = 0xA0;
163     ctx->uChunksPerMb = 0x40;
164     ctx->uPriorityChunks = (0xA0 - 0x60);
165     ctx->ui32FCode = 4;
166     ctx->iFineYSearchSize = 2;
167 
168     //This parameter need not be exposed
169     //host to control the encoding process
170     ctx->bEnableInpCtrl = IMG_FALSE;
171     ctx->bEnableHostBias = IMG_FALSE;
172     //By default false Newly Added
173     ctx->bEnableCumulativeBiases = IMG_FALSE;
174 
175     //Weighted Prediction is not supported in TopazHP Version 3.0
176     ctx->bWeightedPrediction = IMG_FALSE;
177     ctx->ui8VPWeightedImplicitBiPred = 0;
178     ctx->bInsertHRDParams = 0;
179 
180 
181     ctx->bArbitrarySO = IMG_FALSE;
182     ctx->ui32BasicUnit = 0;
183 
184     return vaStatus;
185 }
186 
tng_H263ES_DestroyContext(object_context_p obj_context)187 static void tng_H263ES_DestroyContext(
188     object_context_p obj_context)
189 {
190     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
191     tng_DestroyContext(obj_context, 0);
192 }
193 
tng_H263ES_BeginPicture(object_context_p obj_context)194 static VAStatus tng_H263ES_BeginPicture(
195     object_context_p obj_context)
196 {
197     INIT_CONTEXT_H263ES;
198     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
199 	context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
200 	VAStatus vaStatus = VA_STATUS_SUCCESS;
201 
202 
203     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
204     vaStatus = tng_BeginPicture(ctx);
205 
206     return vaStatus;
207 }
208 
tng__H263ES_process_sequence_param(context_ENC_p ctx,object_buffer_p obj_buffer)209 static VAStatus tng__H263ES_process_sequence_param(context_ENC_p ctx, object_buffer_p obj_buffer)
210 {
211     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
212     VAEncSequenceParameterBufferH263 *psSeqParams;
213     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
214     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
215 //    IMG_UINT32 ClippedPictureHeight;
216 //    IMG_UINT32 ClippedPictureWidth;
217 
218     ASSERT(obj_buffer->type == VAEncSequenceParameterBufferType);
219     ASSERT(obj_buffer->size == sizeof(VAEncSequenceParameterBufferH263));
220 
221     if (obj_buffer->size != sizeof(VAEncSequenceParameterBufferH263)) {
222         return VA_STATUS_ERROR_UNKNOWN;
223     }
224     ctx->obj_context->frame_count = 0;
225     psSeqParams = (VAEncSequenceParameterBufferH263 *) obj_buffer->buffer_data;
226     obj_buffer->buffer_data = NULL;
227     obj_buffer->size = 0;
228 
229     /********************************/
230     ctx->ui32IdrPeriod = psSeqParams->intra_period;
231     ctx->ui32IntraCnt = psSeqParams->intra_period;
232 
233     if (ctx->ui32IntraCnt == 0) {
234             ctx->ui32IntraCnt = INT_MAX;
235         ctx->ui32IdrPeriod = 1;
236         drv_debug_msg(VIDEO_DEBUG_GENERAL,
237             "%s: only ONE I frame in the sequence, %d\n",
238             __FUNCTION__, ctx->ui32IdrPeriod);
239     }
240 
241     ctx->bCustomScaling = IMG_FALSE;
242     ctx->bUseDefaultScalingList = IMG_FALSE;
243 
244 
245     //set MV limit infor
246     ctx->ui32VertMVLimit = 255 ;//(63.75 in qpel increments)
247     ctx->bLimitNumVectors = IMG_TRUE;
248 
249     /**************set rc params ****************/
250     if (psSeqParams->bits_per_second > TOPAZ_H263_MAX_BITRATE) {
251         ctx->sRCParams.ui32BitsPerSecond = TOPAZ_H263_MAX_BITRATE;
252         drv_debug_msg(VIDEO_DEBUG_GENERAL, " bits_per_second(%d) exceeds \
253 		the maximum bitrate, set it with %d\n",
254                                  psSeqParams->bits_per_second,
255                                  TOPAZ_H263_MAX_BITRATE);
256     } else
257         ctx->sRCParams.ui32BitsPerSecond = psSeqParams->bits_per_second;
258 
259     //FIXME: Zhaohan, this should be figured out in testsuite?
260     if (!ctx->uiCbrBufferTenths)
261 	ctx->uiCbrBufferTenths = TOPAZHP_DEFAULT_uiCbrBufferTenths;
262 
263     if (ctx->uiCbrBufferTenths) {
264         psRCParams->ui32BufferSize      = (IMG_UINT32)(psRCParams->ui32BitsPerSecond * ctx->uiCbrBufferTenths / 10.0);
265     } else {
266         if (psRCParams->ui32BitsPerSecond < 256000)
267             psRCParams->ui32BufferSize = ((9 * psRCParams->ui32BitsPerSecond) >> 1);
268         else
269             psRCParams->ui32BufferSize = ((5 * psRCParams->ui32BitsPerSecond) >> 1);
270     }
271 
272     psRCParams->i32InitialDelay = (13 * psRCParams->ui32BufferSize) >> 4;
273     psRCParams->i32InitialLevel = (3 * psRCParams->ui32BufferSize) >> 4;
274     psRCParams->ui32IntraFreq = psSeqParams->intra_period;
275     psRCParams->ui32InitialQp = psSeqParams->initial_qp;
276     psRCParams->iMinQP = psSeqParams->min_qp;
277     //psRCParams->ui32BUSize = psSeqParams->basic_unit_size;
278     //ctx->ui32KickSize = psRCParams->ui32BUSize;
279     psRCParams->ui32FrameRate = psSeqParams->frame_rate;
280 
281     //B-frames are not supported for non-H.264 streams
282     ctx->sRCParams.ui16BFrames = 0;
283     ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
284 
285     cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
286 
287     free(psSeqParams);
288 
289     return VA_STATUS_SUCCESS;
290 }
291 
tng__H263ES_process_picture_param(context_ENC_p ctx,object_buffer_p obj_buffer)292 static VAStatus tng__H263ES_process_picture_param(context_ENC_p ctx, object_buffer_p obj_buffer)
293 {
294     VAStatus vaStatus = VA_STATUS_SUCCESS;
295     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
296     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
297     VAEncPictureParameterBufferH263 *psPicParams;
298     IMG_BOOL bDepViewPPS = IMG_FALSE;
299 	void* pTmpBuf = NULL;
300 
301     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start\n",__FUNCTION__);
302     ASSERT(obj_buffer->type == VAEncPictureParameterBufferType);
303     if (obj_buffer->size != sizeof(VAEncPictureParameterBufferH263)) {
304         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
305         return VA_STATUS_ERROR_UNKNOWN;
306     }
307 
308     /* Transfer ownership of VAEncPictureParameterBufferH263 data */
309     psPicParams = (VAEncPictureParameterBufferH263 *) obj_buffer->buffer_data;
310     obj_buffer->buffer_data = NULL;
311     obj_buffer->size = 0;
312 
313     /* Save the actual width/height for picture header template */
314     ctx->h263_actual_width = psPicParams->picture_width;
315     ctx->h263_actual_height = psPicParams->picture_height;
316 
317     ASSERT(ctx->ui16Width == psPicParams->picture_width);
318     ASSERT(ctx->ui16PictureHeight == psPicParams->picture_height);
319 #ifndef _TNG_FRAMES_
320     ps_buf->ref_surface[0] = ps_buf->ref_surface[2] = SURFACE(psPicParams->reference_picture);
321     ps_buf->ref_surface[1] = ps_buf->ref_surface[3] = SURFACE(psPicParams->reconstructed_picture);
322 
323     ps_buf->ref_surface[0]->is_ref_surface = ps_buf->ref_surface[2]->is_ref_surface = 1;
324     ps_buf->ref_surface[1]->is_ref_surface = ps_buf->ref_surface[3]->is_ref_surface = 1;
325 #else
326     ps_buf->ref_surface = SURFACE(psPicParams->reference_picture);
327     ps_buf->rec_surface = SURFACE(psPicParams->reconstructed_picture);
328 #endif
329     ps_buf->coded_buf = BUFFER(psPicParams->coded_buf);
330 
331     if (NULL == ps_buf->coded_buf) {
332         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
333         free(psPicParams);
334         return VA_STATUS_ERROR_INVALID_BUFFER;
335     }
336 
337     if ((ctx->ui16Width == 128) && (ctx->ui16FrameHeight == 96))
338         ctx->ui8H263SourceFormat = _128x96_SubQCIF;
339     else if ((ctx->ui16Width == 176) && (ctx->ui16FrameHeight == 144))
340         ctx->ui8H263SourceFormat = _176x144_QCIF;
341     else if ((ctx->ui16Width == 352) && (ctx->ui16FrameHeight == 288))
342         ctx->ui8H263SourceFormat = _352x288_CIF;
343     else if ((ctx->ui16Width == 704) && (ctx->ui16FrameHeight == 576))
344         ctx->ui8H263SourceFormat = _704x576_4CIF;
345     else if ((ctx->ui16Width <= 2048) && (ctx->ui16FrameHeight <= 1152))
346         ctx->ui8H263SourceFormat = 7;
347     else {
348         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Unsupported resolution!\n");
349         return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
350     }
351 
352     free(psPicParams);
353     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n",__FUNCTION__);
354 
355     return vaStatus;
356 }
357 
tng__H263ES_process_slice_param(context_ENC_p ctx,object_buffer_p obj_buffer)358 static VAStatus tng__H263ES_process_slice_param(context_ENC_p ctx, object_buffer_p obj_buffer)
359 {
360     VAStatus vaStatus = VA_STATUS_SUCCESS;
361     VAEncSliceParameterBuffer *psSliceParams;
362 
363     ASSERT(obj_buffer->type == VAEncSliceParameterBufferType);
364     /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */
365 
366     /* Transfer ownership of VAEncPictureParameterBufferH263 data */
367     psSliceParams = (VAEncSliceParameterBuffer*) obj_buffer->buffer_data;
368     obj_buffer->size = 0;
369 
370     //deblocking behaviour
371     ctx->bArbitrarySO = IMG_FALSE;
372     ctx->ui8DeblockIDC = psSliceParams->slice_flags.bits.disable_deblocking_filter_idc;
373     ++ctx->ui8SlicesPerPicture;
374     return vaStatus;
375 }
376 
tng__H263ES_process_misc_param(context_ENC_p ctx,object_buffer_p obj_buffer)377 static VAStatus tng__H263ES_process_misc_param(context_ENC_p ctx, object_buffer_p obj_buffer)
378 {
379     VAStatus vaStatus = VA_STATUS_SUCCESS;
380     VAEncMiscParameterBuffer *pBuffer;
381     VAEncMiscParameterFrameRate *frame_rate_param;
382     VAEncMiscParameterRateControl *rate_control_param;
383     IMG_RC_PARAMS   *psRCParams = &(ctx->sRCParams);
384 
385     ASSERT(obj_buffer->type == VAEncMiscParameterBufferType);
386 
387     /* Transfer ownership of VAEncMiscParameterBuffer data */
388     pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
389     obj_buffer->size = 0;
390 
391     switch (pBuffer->type) {
392     case VAEncMiscParameterTypeRateControl:
393         rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data;
394 
395         if (rate_control_param->initial_qp > 51 || rate_control_param->min_qp > 51) {
396             drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp(%d) and min_qpinitial_qp(%d) "
397                                "are invalid.\nQP shouldn't be larger than 51 for H263\n",
398                                rate_control_param->initial_qp, rate_control_param->min_qp);
399             vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
400             break;
401         }
402 
403         drv_debug_msg(VIDEO_DEBUG_GENERAL, "rate control changed from %d to %d\n",
404                                  psRCParams->ui32BitsPerSecond,
405                                  rate_control_param->bits_per_second);
406 
407         if ((rate_control_param->bits_per_second == psRCParams->ui32BitsPerSecond) &&
408             (psRCParams->ui32BufferSize == psRCParams->ui32BitsPerSecond / 1000 * rate_control_param->window_size) &&
409             (psRCParams->iMinQP == rate_control_param->min_qp) &&
410             (psRCParams->ui32InitialQp == rate_control_param->initial_qp))
411             break;
412 
413         if (rate_control_param->bits_per_second > TOPAZ_H263_MAX_BITRATE) {
414             psRCParams->ui32BitsPerSecond = TOPAZ_H263_MAX_BITRATE;
415             drv_debug_msg(VIDEO_DEBUG_GENERAL, " bits_per_second(%d) exceeds \
416 				the maximum bitrate, set it with %d\n",
417                                      rate_control_param->bits_per_second,
418                                      TOPAZ_H263_MAX_BITRATE);
419         } else
420             psRCParams->ui32BitsPerSecond = rate_control_param->bits_per_second;
421 
422         if (rate_control_param->window_size != 0)
423             psRCParams->ui32BufferSize = psRCParams->ui32BitsPerSecond * rate_control_param->window_size / 1000;
424         if (rate_control_param->initial_qp != 0)
425             psRCParams->ui32InitialQp = rate_control_param->initial_qp;
426         if (rate_control_param->min_qp != 0)
427             psRCParams->iMinQP = rate_control_param->min_qp;
428         break;
429     default:
430         break;
431     }
432 #if 0
433     /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */
434     VAEncMiscParameterBuffer *pBuffer;
435     VAEncMiscParameterRateControl *rate_control_param;
436     VAEncMiscParameterAIR *air_param;
437     VAEncMiscParameterMaxSliceSize *max_slice_size_param;
438     VAEncMiscParameterFrameRate *frame_rate_param;
439 
440 
441     ASSERT(obj_buffer->type == VAEncMiscParameterBufferType);
442 
443     /* Transfer ownership of VAEncMiscParameterBuffer data */
444     pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
445     obj_buffer->size = 0;
446 
447     switch (pBuffer->type) {
448     case VAEncMiscParameterTypeFrameRate:
449         frame_rate_param = (VAEncMiscParameterFrameRate *)pBuffer->data;
450 
451         if (frame_rate_param->framerate > 65535) {
452             vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
453             break;
454         }
455 
456         if (ctx->sRCParams.FrameRate == frame_rate_param->framerate)
457             break;
458 
459         drv_debug_msg(VIDEO_DEBUG_GENERAL, "frame rate changed from %d to %d\n",
460                                  ctx->sRCParams.FrameRate,
461                                  frame_rate_param->framerate);
462         ctx->sRCParams.FrameRate = frame_rate_param->framerate;
463         ctx->sRCParams.bBitrateChanged = IMG_TRUE;
464         break;
465 
466     case VAEncMiscParameterTypeRateControl:
467         rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data;
468 
469         if (rate_control_param->initial_qp > 51 ||
470             rate_control_param->min_qp > 51) {
471             drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp(%d) and min_qpinitial_qp(%d) "
472                                "are invalid.\nQP shouldn't be larger than 51 for H264\n",
473                                rate_control_param->initial_qp, rate_control_param->min_qp);
474             vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
475             break;
476         }
477 
478         drv_debug_msg(VIDEO_DEBUG_GENERAL, "rate control changed from %d to %d\n",
479                                  ctx->sRCParams.ui32BitsPerSecond,
480                                  rate_control_param->bits_per_second);
481 
482         if ((rate_control_param->bits_per_second == ctx->sRCParams.ui32BitsPerSecond) &&
483             (ctx->sRCParams.ui32BufferSize == ctx->sRCParams.ui32BitsPerSecond / 1000 * rate_control_param->window_size) &&
484             (ctx->sRCParams.iMinQP == rate_control_param->min_qp) &&
485             (ctx->sRCParams.ui32InitialQp == rate_control_param->initial_qp))
486             break;
487         else
488             ctx->sRCParams.bBitrateChanged = IMG_TRUE;
489 
490         if (rate_control_param->bits_per_second > TOPAZ_H264_MAX_BITRATE) {
491             ctx->sRCParams.ui32BitsPerSecond = TOPAZ_H264_MAX_BITRATE;
492             drv_debug_msg(VIDEO_DEBUG_GENERAL, " bits_per_second(%d) exceeds \
493 			the maximum bitrate, set it with %d\n",
494                                      rate_control_param->bits_per_second,
495                                      TOPAZ_H264_MAX_BITRATE);
496         } else
497             ctx->sRCParams.ui32BitsPerSecond = rate_control_param->bits_per_second;
498 
499         if (rate_control_param->window_size != 0)
500             ctx->sRCParams.ui32BufferSize = ctx->sRCParams.ui32BitsPerSecond * rate_control_param->window_size / 1000;
501         if (rate_control_param->initial_qp != 0)
502             ctx->sRCParams.ui32InitialQp = rate_control_param->initial_qp;
503         if (rate_control_param->min_qp != 0)
504             ctx->sRCParams.iMinQP = rate_control_param->min_qp;
505         break;
506 
507     case VAEncMiscParameterTypeMaxSliceSize:
508         max_slice_size_param = (VAEncMiscParameterMaxSliceSize *)pBuffer->data;
509 
510         if (ctx->max_slice_size == max_slice_size_param->max_slice_size)
511             break;
512 
513         drv_debug_msg(VIDEO_DEBUG_GENERAL, "max slice size changed to %d\n",
514                                  max_slice_size_param->max_slice_size);
515 
516         ctx->max_slice_size = max_slice_size_param->max_slice_size;
517 
518         break;
519 
520     case VAEncMiscParameterTypeAIR:
521         air_param = (VAEncMiscParameterAIR *)pBuffer->data;
522 
523         if (air_param->air_num_mbs > 65535 ||
524             air_param->air_threshold > 65535) {
525             vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
526             break;
527         }
528 
529         drv_debug_msg(VIDEO_DEBUG_GENERAL, "air slice size changed to num_air_mbs %d "
530                                  "air_threshold %d, air_auto %d\n",
531                                  air_param->air_num_mbs, air_param->air_threshold,
532                                  air_param->air_auto);
533 
534         if (((ctx->ui16PictureHeight * ctx->ui16Width) >> 8) < air_param->air_num_mbs)
535             air_param->air_num_mbs = ((ctx->ui16PictureHeight * ctx->ui16Width) >> 8);
536         if (air_param->air_threshold == 0)
537             drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: air threshold is set to zero\n",
538                                      __func__);
539         ctx->num_air_mbs = air_param->air_num_mbs;
540         ctx->air_threshold = air_param->air_threshold;
541         //ctx->autotune_air_flag = air_param->air_auto;
542 
543         break;
544 
545     default:
546         vaStatus = VA_STATUS_ERROR_UNKNOWN;
547         DEBUG_FAILURE;
548         break;
549     }
550 
551     free(obj_buffer->buffer_data);
552     obj_buffer->buffer_data = NULL;
553 #endif
554     return vaStatus;
555 }
556 
557 
558 
tng_H263ES_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)559 static VAStatus tng_H263ES_RenderPicture(
560     object_context_p obj_context,
561     object_buffer_p *buffers,
562     int num_buffers)
563 {
564     INIT_CONTEXT_H263ES;
565     VAStatus vaStatus = VA_STATUS_SUCCESS;
566     int i;
567 
568     drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_H263ES_RenderPicture\n");
569     for (i = 0; i < num_buffers; i++) {
570         object_buffer_p obj_buffer = buffers[i];
571 
572         switch (obj_buffer->type) {
573         case VAEncSequenceParameterBufferType:
574             drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_H263_RenderPicture got VAEncSequenceParameterBufferType\n");
575             vaStatus = tng__H263ES_process_sequence_param(ctx, obj_buffer);
576             DEBUG_FAILURE;
577             break;
578         case VAEncPictureParameterBufferType:
579             drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_H263_RenderPicture got VAEncPictureParameterBuffer\n");
580             vaStatus = tng__H263ES_process_picture_param(ctx, obj_buffer);
581             DEBUG_FAILURE;
582             break;
583 
584         case VAEncSliceParameterBufferType:
585             drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_H263_RenderPicture got VAEncSliceParameterBufferType\n");
586             vaStatus = tng__H263ES_process_slice_param(ctx, obj_buffer);
587             DEBUG_FAILURE;
588             break;
589 
590         case VAEncMiscParameterBufferType:
591             drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_H263_RenderPicture got VAEncMiscParameterBufferType\n");
592             vaStatus = tng__H263ES_process_misc_param(ctx, obj_buffer);
593             DEBUG_FAILURE;
594             break;
595         default:
596             vaStatus = VA_STATUS_ERROR_UNKNOWN;
597             DEBUG_FAILURE;
598         }
599         if (vaStatus != VA_STATUS_SUCCESS) {
600             break;
601         }
602     }
603 
604     return vaStatus;
605 }
606 
tng_H263ES_EndPicture(object_context_p obj_context)607 static VAStatus tng_H263ES_EndPicture(
608     object_context_p obj_context)
609 {
610     INIT_CONTEXT_H263ES;
611     VAStatus vaStatus = VA_STATUS_SUCCESS;
612     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s start\n", __FUNCTION__);
613     vaStatus = tng_EndPicture(ctx);
614     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
615 
616     return vaStatus;
617 }
618 
619 struct format_vtable_s tng_H263ES_vtable = {
620 queryConfigAttributes:
621     tng_H263ES_QueryConfigAttributes,
622 validateConfig:
623     tng_H263ES_ValidateConfig,
624 createContext:
625     tng_H263ES_CreateContext,
626 destroyContext:
627     tng_H263ES_DestroyContext,
628 beginPicture:
629     tng_H263ES_BeginPicture,
630 renderPicture:
631     tng_H263ES_RenderPicture,
632 endPicture:
633     tng_H263ES_EndPicture
634 };
635 
636 /*EOF*/
637