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