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
59static 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
95static 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
120static 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
187static 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
194static 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
209static 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
292static 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
358static 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
377static 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
559static 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
607static 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
619struct format_vtable_s tng_H263ES_vtable = {
620queryConfigAttributes:
621    tng_H263ES_QueryConfigAttributes,
622validateConfig:
623    tng_H263ES_ValidateConfig,
624createContext:
625    tng_H263ES_CreateContext,
626destroyContext:
627    tng_H263ES_DestroyContext,
628beginPicture:
629    tng_H263ES_BeginPicture,
630renderPicture:
631    tng_H263ES_RenderPicture,
632endPicture:
633    tng_H263ES_EndPicture
634};
635
636/*EOF*/
637