1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
|
/*
* Copyright (c) 2011 Intel Corporation. All Rights Reserved.
* Copyright (c) Imagination Technologies Limited, UK
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Zeng Li <zeng.li@intel.com>
* Shengquan Yuan <shengquan.yuan@intel.com>
* Binglin Chen <binglin.chen@intel.com>
*
*/
#include "img_types.h"
#include "psb_drv_video.h"
#include "psb_surface.h"
#include "lnc_cmdbuf.h"
#define MAX_SLICES_PER_PICTURE 72
#define CODED_BUFFER_EOSEQ_FLAG (0x1u<<0)
#define CODED_BUFFER_EOSTREAM_FLAG (0x1u<<1)
/* commands for topaz,shared with user space driver */
enum drm_lnc_topaz_cmd {
MTX_CMDID_NULL = 0,
MTX_CMDID_DO_HEADER = 1,
MTX_CMDID_ENCODE_SLICE = 2,
MTX_CMDID_WRITEREG = 3,
MTX_CMDID_START_PIC = 4,
MTX_CMDID_END_PIC = 5,
MTX_CMDID_SYNC = 6,
MTX_CMDID_ENCODE_ONE_ROW = 7,
MTX_CMDID_FLUSH = 8,
MTX_CMDID_SW_LEAVE_LOWPOWER = 0x7c,
MTX_CMDID_SW_ENTER_LOWPOWER = 0x7e,
MTX_CMDID_SW_NEW_CODEC = 0x7f
};
/* codecs topaz supports,shared with user space driver */
enum drm_lnc_topaz_codec {
IMG_CODEC_JPEG = 0,
IMG_CODEC_H264_NO_RC,
IMG_CODEC_H264_VBR,
IMG_CODEC_H264_CBR,
IMG_CODEC_H264_VCM,
IMG_CODEC_H263_NO_RC,
IMG_CODEC_H263_VBR,
IMG_CODEC_H263_CBR,
IMG_CODEC_MPEG4_NO_RC,
IMG_CODEC_MPEG4_VBR,
IMG_CODEC_MPEG4_CBR,
IMG_CODEC_NUM
};
typedef enum _img_format_ {
IMG_CODEC_IYUV, /* IYUV */
IMG_CODEC_IMC2, /* IMC2 */
IMG_CODEC_PL8,
IMG_CODEC_PL12,
IMG_CODEC_NV12,
} IMG_FORMAT;
typedef struct _RC_PARAMS_ {
IMG_UINT32 BitsPerSecond;
IMG_UINT32 InitialQp;
IMG_UINT32 BUSize;
IMG_UINT32 FrameRate;
IMG_UINT32 BufferSize;
IMG_UINT32 BitsConsumed;
IMG_UINT32 IntraFreq;
IMG_UINT16 IDRFreq;
IMG_UINT16 MinQP;
IMG_BOOL RCEnable;
IMG_BOOL FrameSkip;
IMG_UINT8 Slices;
IMG_UINT8 VCMBitrateMargin;
IMG_UINT32 InitialLevel;
IMG_UINT32 InitialDelay;
} IMG_RC_PARAMS;
/*!
*****************************************************************************
*
* @Description Struct describing rate control input parameters
*
* @Brief Rate control input parameters
*
****************************************************************************/
typedef struct {
IMG_UINT8 SeInitQP; //!< Initial QP for Sequence
IMG_UINT8 MinQPVal; //!< Minimum QP value to use
IMG_UINT8 MaxQPVal; //!< Maximum QP value to use
IMG_UINT8 MBPerRow; /* Number of MBs Per Row */
IMG_UINT16 MBPerFrm; /* Number of MBs Per Frame */
IMG_UINT16 MBPerBU; /* Number of MBs Per BU */
IMG_UINT16 BUPerFrm; /* Number of BUs Per Frame */
IMG_UINT16 IntraPeriod; /* Intra frame frequency */
IMG_INT32 BitsPerFrm; /* Bits Per Frame */
IMG_INT32 BitsPerBU; /* Bits Per BU */
IMG_INT32 BitsPerMB; /* Bits Per MB */
IMG_INT32 BitRate; /* Bit Rate (bps) */
IMG_INT32 BufferSize; /* Size of Buffer */
IMG_UINT32 InitialLevel; /* Initial Level of Buffer */
IMG_INT32 InitialDelay; /* Initial Delay of Buffer */
IMG_UINT8 ScaleFactor; /* Scale Factor (H264 only) */
IMG_UINT8 VCMBitrateMargin; /* Bitrate that should be
targetted as a fraction of
128 relative to maximum bitrate
i32BitRate (VCM mode only) */
IMG_UINT8 HalfFrameRate; /* Half Frame Rate (MP4 only) */
IMG_UINT8 FCode; /* F Code (MP4 only) */
/* TO BE DELETED -- ONCE MP4 RC CODE IS OPTIMISED */
IMG_INT32 BitsPerGOP; /* Bits Per GOP (MP4 only) */
IMG_UINT16 AvQPVal; /* Average QP in Current Picture */
IMG_UINT16 MyInitQP; /* Initial Quantizer */
IMG_INT32 ForceSkipMargin; /* The number of bits of margin
to leave before forcing skipped
macroblocks (VCM mode only) */
IMG_UINT32 RCScaleFactor; /* A constant used in rate control = (GopSize/(BufferSize-InitialLevel))*256 */
} IN_RC_PARAMS;
struct coded_buf_aux_info {
object_buffer_p buf;
uint32_t aux_flag; /*Indicate which operation should be applied when map coded buffer.*/
struct coded_buf_aux_info *next;
};
struct context_ENC_s {
object_context_p obj_context; /* back reference */
IMG_UINT32 Width;
IMG_UINT32 Height;
IMG_UINT16 RawWidth;
IMG_UINT16 RawHeight;
IMG_UINT16 Slices;
enum drm_lnc_topaz_codec eCodec;
IMG_FORMAT eFormat;
unsigned int FCode;
IMG_RC_PARAMS sRCParams;
IMG_INT16 HeightMinus16MinusLRBTopOffset;
IMG_INT16 HeightMinus32MinusLRBTopOffset;
IMG_INT16 HeightMinusLRB_TopAndBottom_OffsetsPlus16;
IMG_INT16 HeightMinusLRBSearchHeight;
IMG_UINT32 IPEControl;
object_surface_p src_surface;
object_surface_p ref_surface;
object_surface_p dest_surface;/* reconstructed surface */
object_buffer_p coded_buf;
/* save previous settings */
object_surface_p previous_src_surface;
object_surface_p previous_ref_surface;
object_surface_p previous_dest_surface; /* reconstructed surface */
object_buffer_p previous_coded_buf;
object_buffer_p pprevious_coded_buf;
/* point to the place in cmdbuf following START_PIC, the initial_qp will fill into it later */
uint32_t *initial_qp_in_cmdbuf;
/* global topaz_params buffer shared by every cmdbuffer
* it is because filling InParams for every MB is very time-consuming
* and in most cases, we can reuse previous frames buffer
*/
/* 0 and 1 are for in_parms, 2 is for bellow and above params*/
struct psb_buffer_s topaz_in_params_I;
struct psb_buffer_s topaz_in_params_P;
struct psb_buffer_s topaz_above_bellow_params;
uint32_t topaz_buffer_size;
uint32_t in_params_size;
uint32_t bellow_params_size;
uint32_t above_params_size;
/* offset in topaz_param buffer */
uint32_t in_params_ofs;
uint32_t bellow_params_ofs;
uint32_t above_params_ofs;
uint32_t pic_params_size;
uint32_t header_buffer_size;
uint32_t seq_header_ofs;
uint32_t pic_header_ofs;
uint32_t eoseq_header_ofs;
uint32_t eostream_header_ofs;
uint32_t slice_header_ofs;
uint32_t sliceparam_buffer_size;
IN_RC_PARAMS in_params_cache; /* following frames reuse the first frame's IN_RC_PARAMS, cache it */
VAEncSliceParameterBuffer *slice_param_cache;
uint16_t slice_param_num;
IMG_UINT16 MPEG4_vop_time_increment_resolution;
/* saved information for FrameSkip redo */
uint32_t MPEG4_vop_time_increment_frameskip;
uint32_t MPEG4_picture_type_frameskip;
uint8_t profile_idc;
uint8_t force_idr_h264;
uint32_t update_rc_control;
uint8_t OptionalCustomPCF;
uint32_t max_slice_size;
uint16_t num_air_mbs;
uint16_t air_threshold;
uint32_t autotune_air_flag;
uint32_t delta_change;
struct coded_buf_aux_info *p_coded_buf_info;
unsigned char *save_seq_header_p;
/*For H264 only.*/
uint16_t idr_pic_id;
};
typedef struct context_ENC_s *context_ENC_p;
/*#define BELOW_PARAMS_SIZE 8*/
#define HEADER_SIZE 128
#define BELOW_PARAMS_SIZE 16
#define REGION_TYPE_2D 1
#define REGION_TYPE_LINEAR 0
#define REGION_TYPE_2DREF 3
#define MAX_RESIDUAL_PER_MB_H264 1260
#define ISINTER_FLAGS 0x1
#define ISH264_FLAGS 0x2
#define ISMPEG4_FLAGS 0x4
#define ISH263_FLAGS 0x8
#define DEBLOCK_FRAME 0x10
#define ISRC_FLAGS 0x20
#define ISCBR_FLAGS 0x40
#define ISVBR_FLAGS 0x80
#define ISRC_I16BIAS 0x100
#define INTERLEAVE_TARGET 0x200
#define ISVCM_FLAGS 0x400
#define AUTOTUNE_AIR 0x800
#define SPE_EDGE_LEFT 1 /* ->bMinXRealEdge*/
#define SPE_EDGE_RIGHT 2 /* ->bMaxXRealEdge*/
#define SPE_EDGE_TOP 4 /* ->bMinYRealEdge*/
#define SPE_EDGE_BOTTOM 8 /* ->bMaxYRealEdge*/
typedef struct {
/* Transferred into the input params area of the macroblock parameter structure*/
IMG_BYTE CurBlockAddr;
IMG_BYTE IPEMin[2];
IMG_BYTE IPEMax[2];
IMG_BYTE RealEdge; /*bMinXRealEdge, bMaxXRealEdge, bMinXRealEdge and bMinYRealEdge*/
/* Surrounding block availability */
IMG_BYTE MVValid;
IMG_BYTE ParamsValid;
IMG_BYTE bySliceQP;
IMG_BYTE bySliceQPC;
IMG_BYTE Reserved[6]; /* This is padding to make the transfers 16 bytes aligned*/
/* Transferred into the SW communication section of the macroblock
* parameter structure We shall EDMA the whole lot of this into eiob
* in one go, and then use two TDMA's to put it into seperate locations
* within the macroblock structure
*/
IMG_UINT32 IPEControl;
IMG_UINT32 SPEControl;
IMG_UINT32 JMCompControl;
IMG_UINT32 VLCControl;
} MTX_CURRENT_IN_PARAMS;
typedef struct { /* corresponding bytes inside the MB_IN structure: */
IMG_BYTE BlockSizes; /****************/
IMG_BYTE IntraMode; /* */
IMG_BYTE Intra4x4ModesBottom[2]; /* */
IMG_BYTE CodeType; /* [64 : 71] */
IMG_BYTE Reserved2; /* */
/*IMG_BYTE SAD;*/
IMG_BYTE QPy; /* */
IMG_BYTE QPc; /****************/
IMG_BYTE Reserved3[8]; /* This is padding to make the transfers 16 byte aligned*/
IMG_UINT16 LumaSubBlockCoded; /****************/
IMG_BYTE ChromaSubBlockCoded; /* */
IMG_BYTE LumaChromaDCCoded; /* */
/* [129 : 143] */
IMG_BYTE Lambda; /* */
IMG_BYTE Reserved[3]; /* */
/* */
IMG_BYTE Intra4x4ModeDeltas[8]; /****************/
/* Motion vectors */
IMG_UINT16 IntegerMV[16][2]; /* [207 : 144] */
/* input region from host */
} MTX_CURRENT_OUT_PARAMS;
typedef enum _TH_SKIP_SCALE_ {
TH_SKIP_0 = 0,
TH_SKIP_12 = 1,
TH_SKIP_24 = 2
} TH_SKIP_SCALE;
typedef struct _PIC_PARAMS_ {
IMG_UINT32 SrcYBase;
IMG_UINT32 SrcUBase;
IMG_UINT32 SrcVBase;
IMG_UINT32 DstYBase;
IMG_UINT32 DstUVBase;
IMG_UINT16 SrcYStride;
IMG_UINT16 SrcUVStride;
IMG_UINT16 SrcYRowStride;
IMG_UINT16 SrcUVRowStride;
IMG_UINT16 DstYStride;
IMG_UINT16 DstUVStride;
IMG_UINT16 DstYRowStride;
IMG_UINT16 DstUVRowStride;
IMG_UINT32 InParamsBase;
IMG_UINT32 InParamsRowStride;
IMG_UINT32 OutParamsBase;
IMG_UINT32 CodedBase;
IMG_UINT32 BelowParamsBase;
IMG_UINT32 BelowParamRowStride;
IMG_UINT32 AboveParamsBase;
IMG_UINT32 AboveParamRowStride;
IMG_UINT16 Width;
IMG_UINT16 Height;
IMG_UINT16 Flags;
IN_RC_PARAMS sInParams;
TH_SKIP_SCALE THSkip;
IMG_UINT16 NumSlices; //!< Number of slices in the picture
} PIC_PARAMS;
/* This holds the data that is needed at the start of a slice
*/
typedef struct _SLICE_PARAMS_ {
IMG_UINT16 SliceStartRowNum;
IMG_UINT16 SliceHeight;
IMG_UINT32 RefYBase;
IMG_UINT32 RefUVBase;
IMG_UINT16 RefYStride;
IMG_UINT16 RefUVStride;
IMG_UINT16 RefYRowStride;
IMG_UINT16 RefUVRowStride;
IMG_UINT32 CodedData;
IMG_UINT32 Flags;
IMG_UINT32 CodedDataPos;
IMG_UINT32 TotalCoded;
IMG_UINT32 FCode;
IMG_UINT32 MaxSliceSize;
IMG_INT16 NumAirMBs; //!< Maximum number of Adaptive intra refresh macroblocks for this slice
IMG_INT16 AirThreshold; //!< Theshold value used in Adaptive intra refresh calculation.
} SLICE_PARAMS;
typedef struct _ROW_PARAMS_ {
IMG_UINT32 TargetYBase;
IMG_UINT32 TargetYStride;
IMG_UINT32 TargetUBase;
IMG_UINT32 TargetVBase;
IMG_UINT32 TargetUVStride;
IMG_UINT32 ReferenceYBase;
IMG_UINT32 ReferenceYStride;
IMG_UINT32 ReferenceUVBase;
IMG_UINT32 ReferenceUVStride;
IMG_UINT32 ReconstructedYBase;
IMG_UINT32 ReconstructedYStride;
IMG_UINT32 ReconstructedUVBase;
IMG_UINT32 ReconstructedUVStride;
IMG_UINT32 AboveParamsBase;
IMG_UINT32 OutAboveParamsBase;
IMG_UINT32 MacroblockInParamsBase;
IMG_UINT32 MacroblockOutParamsBase;
IMG_UINT32 BelowParamsBase;
IMG_UINT32 OutBelowParamsBase;
IMG_UINT32 CodedData;
IMG_UINT32 Flags;
IMG_UINT32 BlockWidth;
IMG_UINT32 BlockHeight;
IMG_UINT32 YPos;
IMG_UINT32 FrameNum;
IMG_INT BelowParamsOffset;
IMG_UINT32 CodedDataPos;
IMG_UINT32 BaseResidual;
IMG_UINT32 TotalCoded;
IMG_UINT32 PADDING[5];
IMG_UINT32 IPESkipVecBias;
IMG_UINT32 SPESkipVecBias;
IMG_INT32 InterMBBias;
IMG_INT32 Intra16Bias;
IMG_UINT32 SpeZeroThld;
IMG_UINT32 SpeZeroThreshold;
} ROW_PARAMS;
#define ROW_PARAMS_TDMA_DIMENSIONS 16,16,sizeof(ROW_PARAMS)
typedef struct _ENCODER_VARIABLES_ {
IMG_UINT32 ActionFlags;
IMG_UINT32 SrcYCurrent;
IMG_UINT32 SrcUCurrent;
IMG_UINT32 SrcVCurrent;
IMG_UINT32 DstYCurrent;
IMG_UINT32 DstUCurrent;
IMG_UINT32 DstVCurrent;
IMG_INT BelowParamsOffset;
IMG_UINT32 BaseResidual;
IMG_UINT32 CodedDataPos;
IMG_UINT32 TotalCoded;
IMG_UINT32 SrcYOffset;
IMG_UINT32 SrcUOffset;
IMG_UINT32 SrcVOffset;
IMG_UINT32 PADDING[2];
} ENCODER_VARIABLES;
#define SLICE_FLAGS_ISINTER 0x00000001
#define SLICE_FLAGS_DEBLOCK 0x00000002
#define SLICE_FLAGS_ISINTER 0x00000001
#define SLICE_FLAGS_DEBLOCK 0x00000002
#define RC_STATUS_FRAME_AVE_QP_MASK 0x0ff /* the average Qp used in this frame */
#define RC_STATUS_FLAG_LARGE_SLICE 0x100 /* At least one slice in this frame was large enough for the firmware to try to reduce it by increasing Qp or skipping MBs */
#define RC_STATUS_FLAG_SLICE_OVERFLOW 0x200 /* At least one slice in this frame was larger than the slice limit */
enum {
CBR = 0,
VBR,
VCM
} eRCMode;
enum {
EH263 = 0,
EMpeg4 = 1,
EH264 = 2,
EHJpeg = 3
} eEncodingFormat;
#define VAEncSliceParameter_Equal(src, dst) \
(((src)->start_row_number == (dst)->start_row_number) \
&& ((src)->slice_height == (dst)->slice_height) \
&& ((src)->slice_flags.bits.is_intra == (dst)->slice_flags.bits.is_intra) \
&& ((src)->slice_flags.bits.disable_deblocking_filter_idc == (dst)->slice_flags.bits.disable_deblocking_filter_idc))
#define VAEncSliceParameter_LightEqual(src, dst) \
(((src)->start_row_number == (dst)->start_row_number) \
&& ((src)->slice_height == (dst)->slice_height) \
&& ((src)->slice_flags.bits.disable_deblocking_filter_idc == (dst)->slice_flags.bits.disable_deblocking_filter_idc))
#define SURFACE_INFO_SKIP_FLAG_SETTLED 0X80000000
#define GET_SURFACE_INFO_skipped_flag(psb_surface) ((int) (psb_surface->extra_info[5]))
#define SET_SURFACE_INFO_skipped_flag(psb_surface, value) psb_surface->extra_info[5] = (SURFACE_INFO_SKIP_FLAG_SETTLED | value)
#define CLEAR_SURFACE_INFO_skipped_flag(psb_surface) psb_surface->extra_info[5] = 0
VAStatus lnc_CreateContext(object_context_p obj_context,
object_config_p obj_config);
void lnc__setup_rcdata(context_ENC_p ctx, PIC_PARAMS *psPicParams, IMG_RC_PARAMS *rc_params);
void lnc__update_rcdata(context_ENC_p ctx, PIC_PARAMS *psPicParams, IMG_RC_PARAMS *rc_params);
void lnc_DestroyContext(
object_context_p obj_context
);
VAStatus lnc_BeginPicture(context_ENC_p ctx);
VAStatus lnc_EndPicture(context_ENC_p ctx);
void lnc_setup_slice_params(
context_ENC_p ctx, IMG_UINT16 YSliceStartPos,
IMG_UINT16 SliceHeight, IMG_BOOL IsIntra,
IMG_BOOL VectorsValid, int bySliceQP);
IMG_UINT32 lnc__send_encode_slice_params(
context_ENC_p ctx,
IMG_BOOL IsIntra,
IMG_UINT16 CurrentRow,
IMG_BOOL DeblockSlice,
IMG_UINT32 FrameNum,
IMG_UINT16 SliceHeight,
IMG_UINT16 CurrentSlice,
IMG_UINT32 MaxSliceSize);
VAStatus lnc_RenderPictureParameter(context_ENC_p ctx);
void lnc_reset_encoder_params(context_ENC_p ctx);
unsigned int lnc__get_ipe_control(enum drm_lnc_topaz_codec eEncodingFormat);
|