1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2014 Advanced Micro Devices, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "va_private.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_civoid vlVaHandlePictureParameterBufferMPEG4(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
31bf215546Sopenharmony_ci{
32bf215546Sopenharmony_ci   static const uint8_t default_intra_quant_matrix[64] = { 0 };
33bf215546Sopenharmony_ci   static const uint8_t default_non_intra_quant_matrix[64] = { 0 };
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci   VAPictureParameterBufferMPEG4 *mpeg4 = buf->data;
36bf215546Sopenharmony_ci   unsigned i;
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   assert(buf->size >= sizeof(VAPictureParameterBufferMPEG4) && buf->num_elements == 1);
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci   context->mpeg4.pps = *mpeg4;
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci   /* vop_width */
43bf215546Sopenharmony_ci   /* vop_height */
44bf215546Sopenharmony_ci   /* forward_reference_picture */
45bf215546Sopenharmony_ci   /* backward_reference_picture */
46bf215546Sopenharmony_ci   context->desc.mpeg4.short_video_header =
47bf215546Sopenharmony_ci         mpeg4->vol_fields.bits.short_video_header;
48bf215546Sopenharmony_ci   /* chroma_format */
49bf215546Sopenharmony_ci   context->desc.mpeg4.interlaced = mpeg4->vol_fields.bits.interlaced;
50bf215546Sopenharmony_ci   /* obmc_disable */
51bf215546Sopenharmony_ci   /* sprite_enable */
52bf215546Sopenharmony_ci   /* sprite_warping_accuracy */
53bf215546Sopenharmony_ci   context->desc.mpeg4.quant_type = mpeg4->vol_fields.bits.quant_type;
54bf215546Sopenharmony_ci   context->desc.mpeg4.quarter_sample = mpeg4->vol_fields.bits.quarter_sample;
55bf215546Sopenharmony_ci   /* data_partitioned */
56bf215546Sopenharmony_ci   /* reversible_vlc */
57bf215546Sopenharmony_ci   context->desc.mpeg4.resync_marker_disable =
58bf215546Sopenharmony_ci         mpeg4->vol_fields.bits.resync_marker_disable;
59bf215546Sopenharmony_ci   /* no_of_sprite_warping_points */
60bf215546Sopenharmony_ci   /* sprite_trajectory_du */
61bf215546Sopenharmony_ci   /* sprite_trajectory_dv */
62bf215546Sopenharmony_ci   /* quant_precision */
63bf215546Sopenharmony_ci   context->desc.mpeg4.vop_coding_type = mpeg4->vop_fields.bits.vop_coding_type;
64bf215546Sopenharmony_ci   /* backward_reference_vop_coding_type */
65bf215546Sopenharmony_ci   /* vop_rounding_type */
66bf215546Sopenharmony_ci   /* intra_dc_vlc_thr */
67bf215546Sopenharmony_ci   context->desc.mpeg4.top_field_first =
68bf215546Sopenharmony_ci         mpeg4->vop_fields.bits.top_field_first;
69bf215546Sopenharmony_ci   context->desc.mpeg4.alternate_vertical_scan_flag =
70bf215546Sopenharmony_ci         mpeg4->vop_fields.bits.alternate_vertical_scan_flag;
71bf215546Sopenharmony_ci   context->desc.mpeg4.vop_fcode_forward = mpeg4->vop_fcode_forward;
72bf215546Sopenharmony_ci   context->desc.mpeg4.vop_fcode_backward = mpeg4->vop_fcode_backward;
73bf215546Sopenharmony_ci   context->desc.mpeg4.vop_time_increment_resolution =
74bf215546Sopenharmony_ci         mpeg4->vop_time_increment_resolution;
75bf215546Sopenharmony_ci   /* num_gobs_in_vop */
76bf215546Sopenharmony_ci   /* num_macroblocks_in_gob */
77bf215546Sopenharmony_ci   context->desc.mpeg4.trb[0] = mpeg4->TRB;
78bf215546Sopenharmony_ci   context->desc.mpeg4.trb[1] = mpeg4->TRB;
79bf215546Sopenharmony_ci   context->desc.mpeg4.trd[0] = mpeg4->TRD;
80bf215546Sopenharmony_ci   context->desc.mpeg4.trd[1] = mpeg4->TRD;
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci   /* default [non-]intra quant matrix because mpv does not set these
83bf215546Sopenharmony_ci      matrices */
84bf215546Sopenharmony_ci   if (!context->desc.mpeg4.intra_matrix)
85bf215546Sopenharmony_ci      context->desc.mpeg4.intra_matrix = default_intra_quant_matrix;
86bf215546Sopenharmony_ci   if (!context->desc.mpeg4.non_intra_matrix)
87bf215546Sopenharmony_ci      context->desc.mpeg4.non_intra_matrix = default_non_intra_quant_matrix;
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   vlVaGetReferenceFrame(drv, mpeg4->forward_reference_picture, &context->desc.mpeg4.ref[0]);
90bf215546Sopenharmony_ci   vlVaGetReferenceFrame(drv, mpeg4->backward_reference_picture, &context->desc.mpeg4.ref[1]);
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   context->mpeg4.vti_bits = 0;
93bf215546Sopenharmony_ci   for (i = context->desc.mpeg4.vop_time_increment_resolution; i > 0; i /= 2)
94bf215546Sopenharmony_ci      ++context->mpeg4.vti_bits;
95bf215546Sopenharmony_ci}
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_civoid vlVaHandleIQMatrixBufferMPEG4(vlVaContext *context, vlVaBuffer *buf)
98bf215546Sopenharmony_ci{
99bf215546Sopenharmony_ci   VAIQMatrixBufferMPEG4 *mpeg4 = buf->data;
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   assert(buf->size >= sizeof(VAIQMatrixBufferMPEG4) && buf->num_elements == 1);
102bf215546Sopenharmony_ci   if (mpeg4->load_intra_quant_mat)
103bf215546Sopenharmony_ci      context->desc.mpeg4.intra_matrix = mpeg4->intra_quant_mat;
104bf215546Sopenharmony_ci   else
105bf215546Sopenharmony_ci      context->desc.mpeg4.intra_matrix = NULL;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   if (mpeg4->load_non_intra_quant_mat)
108bf215546Sopenharmony_ci      context->desc.mpeg4.non_intra_matrix = mpeg4->non_intra_quant_mat;
109bf215546Sopenharmony_ci   else
110bf215546Sopenharmony_ci      context->desc.mpeg4.non_intra_matrix = NULL;
111bf215546Sopenharmony_ci}
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_civoid vlVaHandleSliceParameterBufferMPEG4(vlVaContext *context, vlVaBuffer *buf)
114bf215546Sopenharmony_ci{
115bf215546Sopenharmony_ci   VASliceParameterBufferMPEG4 *mpeg4 = buf->data;
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   assert(buf->size >= sizeof(VASliceParameterBufferMPEG4) && buf->num_elements == 1);
118bf215546Sopenharmony_ci   context->mpeg4.quant_scale = mpeg4->quant_scale;
119bf215546Sopenharmony_ci}
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_cistruct bit_stream
122bf215546Sopenharmony_ci{
123bf215546Sopenharmony_ci   uint8_t *data;
124bf215546Sopenharmony_ci   unsigned int length; /* bits */
125bf215546Sopenharmony_ci   unsigned int pos;    /* bits */
126bf215546Sopenharmony_ci};
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_cistatic inline void
129bf215546Sopenharmony_ciwrite_bit(struct bit_stream *writer, unsigned int bit)
130bf215546Sopenharmony_ci{
131bf215546Sopenharmony_ci   assert(writer->length > (writer)->pos);
132bf215546Sopenharmony_ci   writer->data[writer->pos>>3] |= ((bit & 1)<<(7 - (writer->pos & 7)));
133bf215546Sopenharmony_ci   writer->pos++;
134bf215546Sopenharmony_ci}
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_cistatic inline void
137bf215546Sopenharmony_ciwrite_bits(struct bit_stream *writer, unsigned int bits, unsigned int len)
138bf215546Sopenharmony_ci{
139bf215546Sopenharmony_ci   int i;
140bf215546Sopenharmony_ci   assert(len <= sizeof(bits)*8);
141bf215546Sopenharmony_ci   for (i = len - 1; i >= 0; i--)
142bf215546Sopenharmony_ci      write_bit(writer, bits>>i);
143bf215546Sopenharmony_ci}
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_civoid vlVaDecoderFixMPEG4Startcode(vlVaContext *context)
146bf215546Sopenharmony_ci{
147bf215546Sopenharmony_ci   uint8_t vop[] = { 0x00, 0x00, 0x01, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00 };
148bf215546Sopenharmony_ci   struct bit_stream bs_vop = {vop, sizeof(vop)*8, 32};
149bf215546Sopenharmony_ci   unsigned int vop_time_inc;
150bf215546Sopenharmony_ci   int mod_time;
151bf215546Sopenharmony_ci   unsigned int vop_size;
152bf215546Sopenharmony_ci   unsigned int vop_coding_type = context->desc.mpeg4.vop_coding_type;
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   context->mpeg4.start_code_size = 0;
155bf215546Sopenharmony_ci   memset(context->mpeg4.start_code, 0, sizeof(context->mpeg4.start_code));
156bf215546Sopenharmony_ci   if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_I) {
157bf215546Sopenharmony_ci      unsigned int vop_time = context->mpeg4.frame_num/
158bf215546Sopenharmony_ci            context->desc.mpeg4.vop_time_increment_resolution;
159bf215546Sopenharmony_ci      unsigned int vop_hour = vop_time / 3600;
160bf215546Sopenharmony_ci      unsigned int vop_minute = (vop_time / 60) % 60;
161bf215546Sopenharmony_ci      unsigned int vop_second = vop_time % 60;
162bf215546Sopenharmony_ci      uint8_t group_of_vop[] = { 0x00, 0x00, 0x01, 0xb3, 0x00, 0x00, 0x00 };
163bf215546Sopenharmony_ci      struct bit_stream bs_gvop = {group_of_vop, sizeof(group_of_vop)*8, 32};
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci      write_bits(&bs_gvop, vop_hour, 5);
166bf215546Sopenharmony_ci      write_bits(&bs_gvop, vop_minute, 6);
167bf215546Sopenharmony_ci      write_bit(&bs_gvop, 1); /* marker_bit */
168bf215546Sopenharmony_ci      write_bits(&bs_gvop, vop_second, 6);
169bf215546Sopenharmony_ci      write_bit(&bs_gvop, 0); /* closed_gov */ /* TODO replace magic */
170bf215546Sopenharmony_ci      write_bit(&bs_gvop, 0); /* broken_link */
171bf215546Sopenharmony_ci      write_bit(&bs_gvop, 0); /* padding */
172bf215546Sopenharmony_ci      write_bits(&bs_gvop, 7, 3); /* padding */
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci      memcpy(context->mpeg4.start_code, group_of_vop, sizeof(group_of_vop));
175bf215546Sopenharmony_ci      context->mpeg4.start_code_size += sizeof(group_of_vop);
176bf215546Sopenharmony_ci   }
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   write_bits(&bs_vop, vop_coding_type, 2);
179bf215546Sopenharmony_ci   mod_time = context->mpeg4.frame_num %
180bf215546Sopenharmony_ci         context->desc.mpeg4.vop_time_increment_resolution == 0 &&
181bf215546Sopenharmony_ci         vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I;
182bf215546Sopenharmony_ci   while (mod_time--)
183bf215546Sopenharmony_ci      write_bit(&bs_vop, 1); /* modulo_time_base */
184bf215546Sopenharmony_ci   write_bit(&bs_vop, 0); /* modulo_time_base */
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci   write_bit(&bs_vop, 1); /* marker_bit */
187bf215546Sopenharmony_ci   vop_time_inc = context->mpeg4.frame_num %
188bf215546Sopenharmony_ci         context->desc.mpeg4.vop_time_increment_resolution;
189bf215546Sopenharmony_ci   write_bits(&bs_vop, vop_time_inc, context->mpeg4.vti_bits);
190bf215546Sopenharmony_ci   write_bit(&bs_vop, 1); /* marker_bit */
191bf215546Sopenharmony_ci   write_bit(&bs_vop, 1); /* vop_coded */
192bf215546Sopenharmony_ci   if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_P)
193bf215546Sopenharmony_ci      write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.vop_rounding_type);
194bf215546Sopenharmony_ci   write_bits(&bs_vop, context->mpeg4.pps.vop_fields.bits.intra_dc_vlc_thr, 3);
195bf215546Sopenharmony_ci   if (context->mpeg4.pps.vol_fields.bits.interlaced) {
196bf215546Sopenharmony_ci      write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.top_field_first);
197bf215546Sopenharmony_ci      write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.alternate_vertical_scan_flag);
198bf215546Sopenharmony_ci   }
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   write_bits(&bs_vop, context->mpeg4.quant_scale, context->mpeg4.pps.quant_precision);
201bf215546Sopenharmony_ci   if (vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I)
202bf215546Sopenharmony_ci      write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_forward, 3);
203bf215546Sopenharmony_ci   if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_B)
204bf215546Sopenharmony_ci      write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_backward, 3);
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ci   vop_size = bs_vop.pos/8;
207bf215546Sopenharmony_ci   memcpy(context->mpeg4.start_code + context->mpeg4.start_code_size, vop, vop_size);
208bf215546Sopenharmony_ci   context->mpeg4.start_code_size += vop_size;
209bf215546Sopenharmony_ci}
210