1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file media_libvpx_vp9.cpp
24 //! \brief Defines the VP9 structure/function that is from libvpx
25 //!
26
27 /*
28 * This file defines some functions related with vp9 enc, and
29 * they are ported from libvpx (https://github.com/webmproject/libvpx/).
30 * The original copyright and licence statement as below.
31 */
32
33 /*
34 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
35 *
36 * Use of this source code is governed by a BSD-style license
37 * that can be found in the media_libvpx.LICENSE file in the root of the source
38 * tree. An additional intellectual property rights grant can be found
39 * in the file media_libvpx.PATENTS. All contributing project authors may
40 * be found in the media_libvpx.AUTHORS file in the root of the source tree.
41 */
42
43 #include <stdio.h>
44 #include <stdint.h>
45 #include "media_libva_encoder.h"
46 #include "media_libvpx_vp9.h"
47
48 struct vp9_write_bit_buffer {
49 uint8_t *bit_buffer;
50 int bit_offset;
51 };
52
53 static
vp9_wb_write_bit(struct vp9_write_bit_buffer * wb,int bit)54 void vp9_wb_write_bit(struct vp9_write_bit_buffer *wb, int bit)
55 {
56 const int off = wb->bit_offset;
57 const int p = off / 8;
58 const int q = 7 - off % 8;
59
60 if (q == 7)
61 {
62 wb->bit_buffer[p] = bit << q;
63 }
64 else
65 {
66 wb->bit_buffer[p] &= ~(1 << q);
67 wb->bit_buffer[p] |= bit << q;
68 }
69 wb->bit_offset = off + 1;
70 }
71
72 static
vp9_wb_write_literal(struct vp9_write_bit_buffer * wb,int data,int bits)73 void vp9_wb_write_literal(struct vp9_write_bit_buffer *wb, int data, int bits)
74 {
75 int bit;
76 for (bit = bits - 1; bit >= 0; bit--)
77 vp9_wb_write_bit(wb, (data >> bit) & 1);
78 }
79
80 static
write_bitdepth_colorspace_sampling(uint32_t codecProfile,struct vp9_write_bit_buffer * wb)81 void write_bitdepth_colorspace_sampling(uint32_t codecProfile,
82 struct vp9_write_bit_buffer *wb)
83 {
84
85 if (codecProfile >= VP9_PROFILE_2)
86 {
87 /* Profile 2 can support 10/12 bits */
88 /* Currently it is 10 bits */
89 vp9_wb_write_literal(wb, 0, 1);
90 }
91
92 /* Add the default color-space */
93 vp9_wb_write_literal(wb, 0, 3);
94 vp9_wb_write_bit(wb, 0); // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
95
96 if ((codecProfile == VP9_PROFILE_1) ||
97 (codecProfile == VP9_PROFILE_3))
98 {
99 /* sub_sampling_x/y */
100 /* Currently the sub_sampling_x = 0, sub_sampling_y = 0 */
101 vp9_wb_write_bit(wb, 0);
102 vp9_wb_write_bit(wb, 0);
103 vp9_wb_write_bit(wb, 0); // unused
104 }
105 }
106
107 #define MAX_TILE_WIDTH_B64 64
108 #define MIN_TILE_WIDTH_B64 4
109
get_min_log2_tile_cols(const int sb_cols)110 static int get_min_log2_tile_cols(const int sb_cols)
111 {
112 int min_log2 = 0;
113
114 while ((MAX_TILE_WIDTH_B64 << min_log2) < sb_cols)
115 ++min_log2;
116
117 return min_log2;
118 }
119
get_max_log2_tile_cols(const int sb_cols)120 static int get_max_log2_tile_cols(const int sb_cols)
121 {
122 int max_log2 = 1;
123
124 while ((sb_cols >> max_log2) >= MIN_TILE_WIDTH_B64)
125 ++max_log2;
126
127 return max_log2 - 1;
128 }
129
Vp9WriteUncompressHeader(struct _DDI_ENCODE_CONTEXT * ddiEncContext,uint32_t codecProfile,uint8_t * headerData,uint32_t * headerLen,vp9_header_bitoffset * headerBitoffset)130 bool Vp9WriteUncompressHeader(struct _DDI_ENCODE_CONTEXT *ddiEncContext,
131 uint32_t codecProfile,
132 uint8_t *headerData,
133 uint32_t *headerLen,
134 vp9_header_bitoffset *headerBitoffset)
135 {
136 #define VP9_SYNC_CODE_0 0x49
137 #define VP9_SYNC_CODE_1 0x83
138 #define VP9_SYNC_CODE_2 0x42
139
140 #define VP9_FRAME_MARKER 0x2
141
142 #define REFS_PER_FRAME 3
143
144 #define REF_FRAMES_LOG2 3
145 #define REF_FRAMES (1 << REF_FRAMES_LOG2)
146
147 #define VP9_KEY_FRAME 0
148
149 if ((ddiEncContext == nullptr) ||
150 (headerData == nullptr) ||
151 (headerLen == nullptr) ||
152 (headerBitoffset == nullptr))
153 return false;
154
155 CODEC_VP9_ENCODE_PIC_PARAMS *picParam = (CODEC_VP9_ENCODE_PIC_PARAMS *)ddiEncContext->pPicParams;
156 CODEC_VP9_ENCODE_SEGMENT_PARAMS *segParams = (CODEC_VP9_ENCODE_SEGMENT_PARAMS *)ddiEncContext->pVpxSegParams;
157
158 if (picParam == nullptr)
159 return false;
160
161 struct vp9_write_bit_buffer *wb, vp9_wb;
162
163 memset(headerBitoffset, 0, sizeof(vp9_header_bitoffset));
164
165 vp9_wb.bit_buffer = (uint8_t *)headerData;
166 vp9_wb.bit_offset = 0;
167 wb = &vp9_wb;
168 vp9_wb_write_literal(wb, VP9_FRAME_MARKER, 2);
169
170 /* Only Profile0/1/2/3 is supported */
171 if (codecProfile > VP9_PROFILE_3)
172 codecProfile = VP9_PROFILE_0;
173
174 switch(codecProfile)
175 {
176 case VP9_PROFILE_0:
177 //Profile 0
178 vp9_wb_write_literal(wb, 0, 2);
179 break;
180 case VP9_PROFILE_1:
181 //Profile 1
182 vp9_wb_write_literal(wb, 2, 2);
183 break;
184 case VP9_PROFILE_2:
185 //Profile 2
186 vp9_wb_write_literal(wb, 1, 2);
187 break;
188 case VP9_PROFILE_3:
189 vp9_wb_write_literal(wb, 6, 3);
190 break;
191 default:
192 break;
193 }
194
195 vp9_wb_write_bit(wb, 0); // show_existing_frame
196 vp9_wb_write_bit(wb, picParam->PicFlags.fields.frame_type);
197 vp9_wb_write_bit(wb, picParam->PicFlags.fields.show_frame);
198 vp9_wb_write_bit(wb, picParam->PicFlags.fields.error_resilient_mode);
199
200 if (picParam->PicFlags.fields.frame_type == VP9_KEY_FRAME)
201 {
202 vp9_wb_write_literal(wb, VP9_SYNC_CODE_0, 8);
203 vp9_wb_write_literal(wb, VP9_SYNC_CODE_1, 8);
204 vp9_wb_write_literal(wb, VP9_SYNC_CODE_2, 8);
205
206 write_bitdepth_colorspace_sampling(codecProfile, wb);
207
208 /* write the encoded frame size */
209 vp9_wb_write_literal(wb, picParam->DstFrameWidthMinus1, 16);
210 vp9_wb_write_literal(wb, picParam->DstFrameHeightMinus1, 16);
211 /* write display size */
212 if ((picParam->DstFrameWidthMinus1 != picParam->SrcFrameWidthMinus1) ||
213 (picParam->DstFrameHeightMinus1 != picParam->SrcFrameHeightMinus1))
214 {
215 vp9_wb_write_bit(wb, 1);
216 vp9_wb_write_literal(wb, picParam->SrcFrameWidthMinus1, 16);
217 vp9_wb_write_literal(wb, picParam->SrcFrameHeightMinus1, 16);
218 }
219 else
220 {
221 vp9_wb_write_bit(wb, 0);
222 }
223 }
224 else
225 {
226 /* for the non-Key frame */
227 if (!picParam->PicFlags.fields.show_frame)
228 {
229 vp9_wb_write_bit(wb, picParam->PicFlags.fields.intra_only);
230 }
231
232 if (!picParam->PicFlags.fields.error_resilient_mode)
233 {
234 vp9_wb_write_literal(wb, picParam->PicFlags.fields.reset_frame_context, 2);
235 }
236
237 if (picParam->PicFlags.fields.intra_only)
238 {
239 vp9_wb_write_literal(wb, VP9_SYNC_CODE_0, 8);
240 vp9_wb_write_literal(wb, VP9_SYNC_CODE_1, 8);
241 vp9_wb_write_literal(wb, VP9_SYNC_CODE_2, 8);
242
243 /* Add the bit_depth for VP9Profile1/2/3 */
244 if (codecProfile)
245 write_bitdepth_colorspace_sampling(codecProfile, wb);
246
247 /* write the refreshed_frame_flags */
248 vp9_wb_write_literal(wb, picParam->RefFlags.fields.refresh_frame_flags, REF_FRAMES);
249 /* write the encoded frame size */
250 vp9_wb_write_literal(wb, picParam->DstFrameWidthMinus1, 16);
251 vp9_wb_write_literal(wb, picParam->DstFrameHeightMinus1, 16);
252 /* write display size */
253 if ((picParam->DstFrameWidthMinus1 != picParam->SrcFrameWidthMinus1) ||
254 (picParam->DstFrameHeightMinus1 != picParam->SrcFrameHeightMinus1))
255 {
256 vp9_wb_write_bit(wb, 1);
257 vp9_wb_write_literal(wb, picParam->SrcFrameWidthMinus1, 16);
258 vp9_wb_write_literal(wb, picParam->SrcFrameHeightMinus1, 16);
259 }
260 else
261 {
262 vp9_wb_write_bit(wb, 0);
263 }
264 }
265 else
266 {
267 /* The refresh_frame_map is for the next frame so that it can select Last/Godlen/Alt ref_index */
268 /*
269 if ((picParam->RefFlags.fields.ref_frame_ctrl_l0) & (1 << 0))
270 refresh_flags = 1 << picParam->RefFlags.fields.ref_last_idx;
271 if ((picParam->RefFlags.fields.ref_frame_ctrl_l0) & (1 << 0))
272 refresh_flags = 1 << picParam->RefFlags.fields.ref_last_idx;
273 if ((picParam->RefFlags.fields.ref_frame_ctrl_l0) & (1 << 0))
274 refresh_flags = 1 << picParam->RefFlags.fields.ref_last_idx;
275 */
276 vp9_wb_write_literal(wb, picParam->RefFlags.fields.refresh_frame_flags, REF_FRAMES);
277
278 vp9_wb_write_literal(wb, picParam->RefFlags.fields.LastRefIdx, REF_FRAMES_LOG2);
279 vp9_wb_write_bit(wb, picParam->RefFlags.fields.LastRefSignBias);
280 vp9_wb_write_literal(wb, picParam->RefFlags.fields.GoldenRefIdx, REF_FRAMES_LOG2);
281 vp9_wb_write_bit(wb, picParam->RefFlags.fields.GoldenRefSignBias);
282 vp9_wb_write_literal(wb, picParam->RefFlags.fields.AltRefIdx, REF_FRAMES_LOG2);
283 vp9_wb_write_bit(wb, picParam->RefFlags.fields.AltRefSignBias);
284
285 /* write three bits with zero so that it can parse width/height directly */
286 vp9_wb_write_literal(wb, 0, 3);
287 vp9_wb_write_literal(wb, picParam->DstFrameWidthMinus1, 16);
288 vp9_wb_write_literal(wb, picParam->DstFrameHeightMinus1, 16);
289
290 /* write display size */
291 if ((picParam->DstFrameWidthMinus1 != picParam->SrcFrameWidthMinus1) ||
292 (picParam->DstFrameHeightMinus1 != picParam->SrcFrameHeightMinus1))
293 {
294 vp9_wb_write_bit(wb, 1);
295 vp9_wb_write_literal(wb, picParam->SrcFrameWidthMinus1, 16);
296 vp9_wb_write_literal(wb, picParam->SrcFrameHeightMinus1, 16);
297 }
298 else
299 {
300 vp9_wb_write_bit(wb, 0);
301 }
302
303 vp9_wb_write_bit(wb, picParam->PicFlags.fields.allow_high_precision_mv);
304
305 #define SWITCHABLE_FILTER 4
306 #define FILTER_MASK 3
307
308 if (picParam->PicFlags.fields.mcomp_filter_type == SWITCHABLE_FILTER)
309 {
310 vp9_wb_write_bit(wb, 1);
311 }
312 else
313 {
314 const int filter_to_literal[4] = { 1, 0, 2, 3 };
315 uint8_t filter_flag = picParam->PicFlags.fields.mcomp_filter_type;
316 filter_flag = filter_flag & FILTER_MASK;
317 vp9_wb_write_bit(wb, 0);
318 vp9_wb_write_literal(wb, filter_to_literal[filter_flag], 2);
319 }
320 }
321 }
322
323 /* write refresh_frame_context/paralle frame_decoding */
324 if (!picParam->PicFlags.fields.error_resilient_mode)
325 {
326 vp9_wb_write_bit(wb, picParam->PicFlags.fields.refresh_frame_context);
327 vp9_wb_write_bit(wb, picParam->PicFlags.fields.frame_parallel_decoding_mode);
328 }
329
330 vp9_wb_write_literal(wb, picParam->PicFlags.fields.frame_context_idx, 2);
331
332 /* write loop filter */
333 headerBitoffset->bit_offset_lf_level = wb->bit_offset;
334 vp9_wb_write_literal(wb, picParam->filter_level, 6);
335 vp9_wb_write_literal(wb, picParam->sharpness_level, 3);
336
337 {
338 int i, mode_flag;
339
340 vp9_wb_write_bit(wb, 1);
341 vp9_wb_write_bit(wb, 1);
342 headerBitoffset->bit_offset_ref_lf_delta = wb->bit_offset;
343 for (i = 0; i < 4; i++)
344 {
345 /*
346 * This check is skipped to prepare the bit_offset_lf_ref
347 if (picParam->LFRefDelta[i] == 0) {
348 vp9_wb_write_bit(wb, 0);
349 continue;
350 }
351 */
352 vp9_wb_write_bit(wb, 1);
353 mode_flag = picParam->LFRefDelta[i];
354 if (mode_flag >= 0)
355 {
356 vp9_wb_write_literal(wb, mode_flag & (0x3F), 6);
357 vp9_wb_write_bit(wb, 0);
358 }
359 else
360 {
361 mode_flag = -mode_flag;
362 vp9_wb_write_literal(wb, mode_flag & (0x3F), 6);
363 vp9_wb_write_bit(wb, 1);
364 }
365 }
366
367 headerBitoffset->bit_offset_mode_lf_delta = wb->bit_offset;
368 for (i = 0; i < 2; i++)
369 {
370 /*
371 * This check is skipped to prepare the bit_offset_lf_mode
372 if (picParam->LFModeDelta[i] == 0) {
373 vp9_wb_write_bit(wb, 0);
374 continue;
375 }
376 */
377 vp9_wb_write_bit(wb, 1);
378 mode_flag = picParam->LFRefDelta[i];
379 if (mode_flag >= 0)
380 {
381 vp9_wb_write_literal(wb, mode_flag & (0x3F), 6);
382 vp9_wb_write_bit(wb, 0);
383 }
384 else
385 {
386 mode_flag = -mode_flag;
387 vp9_wb_write_literal(wb, mode_flag & (0x3F), 6);
388 vp9_wb_write_bit(wb, 1);
389 }
390 }
391 }
392
393 /* write basic quantizer */
394 headerBitoffset->bit_offset_qindex = wb->bit_offset;
395 vp9_wb_write_literal(wb, picParam->LumaACQIndex, 8);
396 if (picParam->LumaDCQIndexDelta)
397 {
398 int delta_q = picParam->LumaDCQIndexDelta;
399 vp9_wb_write_bit(wb, 1);
400 vp9_wb_write_literal(wb, abs(delta_q), 4);
401 vp9_wb_write_bit(wb, delta_q < 0);
402 }
403 else
404 {
405 vp9_wb_write_bit(wb, 0);
406 }
407
408 if (picParam->ChromaDCQIndexDelta)
409 {
410 int delta_q = picParam->ChromaDCQIndexDelta;
411 vp9_wb_write_bit(wb, 1);
412 vp9_wb_write_literal(wb, abs(delta_q), 4);
413 vp9_wb_write_bit(wb, delta_q < 0);
414 }
415 else
416 {
417 vp9_wb_write_bit(wb, 0);
418 }
419
420 if (picParam->ChromaACQIndexDelta)
421 {
422 int delta_q = picParam->ChromaACQIndexDelta;
423 vp9_wb_write_bit(wb, 1);
424 vp9_wb_write_literal(wb, abs(delta_q), 4);
425 vp9_wb_write_bit(wb, delta_q < 0);
426 }
427 else
428 {
429 vp9_wb_write_bit(wb, 0);
430 }
431
432 headerBitoffset->bit_offset_segmentation = wb->bit_offset;
433 vp9_wb_write_bit(wb, picParam->PicFlags.fields.segmentation_enabled);
434 if (picParam->PicFlags.fields.segmentation_enabled)
435 {
436 // Segmentation syntax will be filled by HW, need leave dummy here.
437 vp9_wb_write_bit(wb, 0);
438 vp9_wb_write_bit(wb, 0);
439 }
440 headerBitoffset->bit_size_segmentation = wb->bit_offset - headerBitoffset->bit_offset_segmentation;
441
442 /* write tile info */
443 {
444 int sb_cols = (picParam->DstFrameWidthMinus1 + 64) / 64;
445 int min_log2_tile_cols, max_log2_tile_cols;
446 int col_data;
447
448 /* write tile column info */
449 min_log2_tile_cols = get_min_log2_tile_cols(sb_cols);
450 max_log2_tile_cols = get_max_log2_tile_cols(sb_cols);
451
452 col_data = picParam->log2_tile_columns - min_log2_tile_cols;
453 while (col_data--)
454 {
455 vp9_wb_write_bit(wb, 1);
456 }
457 if (picParam->log2_tile_columns < max_log2_tile_cols)
458 {
459 vp9_wb_write_bit(wb, 0);
460 }
461
462 /* write tile row info */
463 vp9_wb_write_bit(wb, picParam->log2_tile_rows);
464 if (picParam->log2_tile_rows)
465 {
466 vp9_wb_write_bit(wb, (picParam->log2_tile_rows != 1));
467 }
468 }
469
470 /* get the bit_offset of the first partition size */
471 headerBitoffset->bit_offset_first_partition_size = wb->bit_offset;
472
473 /* reserve the space for writing the first partitions ize */
474 vp9_wb_write_literal(wb, 0, 16);
475
476 *headerLen = (wb->bit_offset + 7) / 8;
477
478 return true;
479 }
480