2 * Copyright 2011-2013 Maarten Lankhorst
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * 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.
23 #include "nouveau_vp3_video.h"
26 uint32_t w0
[4]; // bits 0-23 length, bits 24-31 addr_hi
27 uint32_t w1
[4]; // bit 8-24 addr_lo
28 uint32_t unk20
; // should be idx * 0x8000000, bitstream offset
29 uint32_t do_crypto_crap
; // set to 0
32 struct mpeg12_picparm_bsp
{
35 uint8_t picture_structure
;
36 uint8_t picture_coding_type
;
37 uint8_t intra_dc_precision
;
38 uint8_t frame_pred_frame_dct
;
39 uint8_t concealment_motion_vectors
;
40 uint8_t intra_vlc_format
;
45 struct mpeg4_picparm_bsp
{
48 uint8_t vop_time_increment_size
;
50 uint8_t resync_marker_disable
;
53 struct vc1_picparm_bsp
{
56 uint8_t profile
; // 04 0 simple, 1 main, 2 advanced
57 uint8_t postprocflag
; // 05
58 uint8_t pulldown
; // 06
59 uint8_t interlaced
; // 07
60 uint8_t tfcntrflag
; // 08
61 uint8_t finterpflag
; // 09
64 uint8_t multires
; // 0c
65 uint8_t syncmarker
; // 0d
66 uint8_t rangered
; // 0e
67 uint8_t maxbframes
; // 0f
69 uint8_t panscan_flag
; // 11
70 uint8_t refdist_flag
; // 12
71 uint8_t quantizer
; // 13
72 uint8_t extended_mv
; // 14
73 uint8_t extended_dmv
; // 15
74 uint8_t overlap
; // 16
75 uint8_t vstransform
; // 17
78 struct h264_picparm_bsp
{
82 uint32_t log2_max_frame_num_minus4
; // 04 checked
83 uint32_t pic_order_cnt_type
; // 08 checked
84 uint32_t log2_max_pic_order_cnt_lsb_minus4
; // 0c checked
85 uint32_t delta_pic_order_always_zero_flag
; // 10, or unknown
87 uint32_t frame_mbs_only_flag
; // 14, always 1?
88 uint32_t direct_8x8_inference_flag
; // 18, always 1?
89 uint32_t width_mb
; // 1c checked
90 uint32_t height_mb
; // 20 checked
93 uint32_t entropy_coding_mode_flag
; // 00, checked
94 uint32_t pic_order_present_flag
; // 04 checked
95 uint32_t unk
; // 08 seems to be 0?
96 uint32_t pad1
; // 0c seems to be 0?
97 uint32_t pad2
; // 10 always 0 ?
98 uint32_t num_ref_idx_l0_active_minus1
; // 14 always 0?
99 uint32_t num_ref_idx_l1_active_minus1
; // 18 always 0?
100 uint32_t weighted_pred_flag
; // 1c checked
101 uint32_t weighted_bipred_idc
; // 20 checked
102 uint32_t pic_init_qp_minus26
; // 24 checked
103 uint32_t deblocking_filter_control_present_flag
; // 28 always 1?
104 uint32_t redundant_pic_cnt_present_flag
; // 2c always 0?
105 uint32_t transform_8x8_mode_flag
; // 30 checked
106 uint32_t mb_adaptive_frame_field_flag
; // 34 checked-ish
107 uint8_t field_pic_flag
; // 38 checked
108 uint8_t bottom_field_flag
; // 39 checked
109 uint8_t real_pad
[0x1b]; // XX why?
113 nouveau_vp3_fill_picparm_mpeg12_bsp(struct nouveau_vp3_decoder
*dec
,
114 struct pipe_mpeg12_picture_desc
*desc
,
117 struct mpeg12_picparm_bsp
*pic_bsp
= (struct mpeg12_picparm_bsp
*)map
;
119 pic_bsp
->width
= dec
->base
.width
;
120 pic_bsp
->height
= dec
->base
.height
;
121 pic_bsp
->picture_structure
= desc
->picture_structure
;
122 pic_bsp
->picture_coding_type
= desc
->picture_coding_type
;
123 pic_bsp
->intra_dc_precision
= desc
->intra_dc_precision
;
124 pic_bsp
->frame_pred_frame_dct
= desc
->frame_pred_frame_dct
;
125 pic_bsp
->concealment_motion_vectors
= desc
->concealment_motion_vectors
;
126 pic_bsp
->intra_vlc_format
= desc
->intra_vlc_format
;
128 for (i
= 0; i
< 4; ++i
)
129 pic_bsp
->f_code
[i
/2][i
%2] = desc
->f_code
[i
/2][i
%2] + 1; // FU
131 return (desc
->num_slices
<< 4) | (dec
->base
.profile
!= PIPE_VIDEO_PROFILE_MPEG1
);
135 nouveau_vp3_fill_picparm_mpeg4_bsp(struct nouveau_vp3_decoder
*dec
,
136 struct pipe_mpeg4_picture_desc
*desc
,
139 struct mpeg4_picparm_bsp
*pic_bsp
= (struct mpeg4_picparm_bsp
*)map
;
140 uint32_t t
, bits
= 0;
141 pic_bsp
->width
= dec
->base
.width
;
142 pic_bsp
->height
= dec
->base
.height
;
143 assert(desc
->vop_time_increment_resolution
> 0);
145 t
= desc
->vop_time_increment_resolution
- 1;
152 t
= desc
->vop_time_increment_resolution
- 1;
153 pic_bsp
->vop_time_increment_size
= bits
;
154 pic_bsp
->interlaced
= desc
->interlaced
;
155 pic_bsp
->resync_marker_disable
= desc
->resync_marker_disable
;
160 nouveau_vp3_fill_picparm_vc1_bsp(struct nouveau_vp3_decoder
*dec
,
161 struct pipe_vc1_picture_desc
*d
,
164 struct vc1_picparm_bsp
*vc
= (struct vc1_picparm_bsp
*)map
;
165 uint32_t caps
= (d
->slice_count
<< 4)&0xfff0;
166 vc
->width
= dec
->base
.width
;
167 vc
->height
= dec
->base
.height
;
168 vc
->profile
= dec
->base
.profile
- PIPE_VIDEO_PROFILE_VC1_SIMPLE
; // 04
169 vc
->postprocflag
= d
->postprocflag
;
170 vc
->pulldown
= d
->pulldown
;
171 vc
->interlaced
= d
->interlace
;
172 vc
->tfcntrflag
= d
->tfcntrflag
; // 08
173 vc
->finterpflag
= d
->finterpflag
;
176 vc
->multires
= d
->multires
; // 0c
177 vc
->syncmarker
= d
->syncmarker
;
178 vc
->rangered
= d
->rangered
;
179 vc
->maxbframes
= d
->maxbframes
;
180 vc
->dquant
= d
->dquant
; // 10
181 vc
->panscan_flag
= d
->panscan_flag
;
182 vc
->refdist_flag
= d
->refdist_flag
;
183 vc
->quantizer
= d
->quantizer
;
184 vc
->extended_mv
= d
->extended_mv
; // 14
185 vc
->extended_dmv
= d
->extended_dmv
;
186 vc
->overlap
= d
->overlap
;
187 vc
->vstransform
= d
->vstransform
;
192 nouveau_vp3_fill_picparm_h264_bsp(struct nouveau_vp3_decoder
*dec
,
193 struct pipe_h264_picture_desc
*d
,
196 struct h264_picparm_bsp stub_h
= {}, *h
= &stub_h
;
197 uint32_t caps
= (d
->slice_count
<< 4)&0xfff0;
199 assert(!(d
->slice_count
& ~0xfff));
200 if (d
->slice_count
& 0x1000)
203 assert(offsetof(struct h264_picparm_bsp
, bottom_field_flag
) == (0x39 + 0x24));
205 h
->pad1
= h
->pad2
= 0;
207 h
->log2_max_frame_num_minus4
= d
->pps
->sps
->log2_max_frame_num_minus4
;
208 h
->frame_mbs_only_flag
= d
->pps
->sps
->frame_mbs_only_flag
;
209 h
->direct_8x8_inference_flag
= d
->pps
->sps
->direct_8x8_inference_flag
;
210 h
->width_mb
= mb(dec
->base
.width
);
211 h
->height_mb
= mb(dec
->base
.height
);
212 h
->entropy_coding_mode_flag
= d
->pps
->entropy_coding_mode_flag
;
213 h
->pic_order_present_flag
= d
->pps
->bottom_field_pic_order_in_frame_present_flag
;
214 h
->pic_order_cnt_type
= d
->pps
->sps
->pic_order_cnt_type
;
215 h
->log2_max_pic_order_cnt_lsb_minus4
= d
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
216 h
->delta_pic_order_always_zero_flag
= d
->pps
->sps
->delta_pic_order_always_zero_flag
;
217 h
->num_ref_idx_l0_active_minus1
= d
->num_ref_idx_l0_active_minus1
;
218 h
->num_ref_idx_l1_active_minus1
= d
->num_ref_idx_l1_active_minus1
;
219 h
->weighted_pred_flag
= d
->pps
->weighted_pred_flag
;
220 h
->weighted_bipred_idc
= d
->pps
->weighted_bipred_idc
;
221 h
->pic_init_qp_minus26
= d
->pps
->pic_init_qp_minus26
;
222 h
->deblocking_filter_control_present_flag
= d
->pps
->deblocking_filter_control_present_flag
;
223 h
->redundant_pic_cnt_present_flag
= d
->pps
->redundant_pic_cnt_present_flag
;
224 h
->transform_8x8_mode_flag
= d
->pps
->transform_8x8_mode_flag
;
225 h
->mb_adaptive_frame_field_flag
= d
->pps
->sps
->mb_adaptive_frame_field_flag
;
226 h
->field_pic_flag
= d
->field_pic_flag
;
227 h
->bottom_field_flag
= d
->bottom_field_flag
;
228 memset(h
->real_pad
, 0, sizeof(h
->real_pad
));
229 *(struct h264_picparm_bsp
*)map
= *h
;
234 nouveau_vp3_bsp(struct nouveau_vp3_decoder
*dec
, union pipe_desc desc
,
235 struct nouveau_vp3_video_buffer
*target
,
236 unsigned comm_seq
, unsigned num_buffers
,
237 const void *const *data
, const unsigned *num_bytes
)
239 enum pipe_video_format codec
= u_reduce_video_profile(dec
->base
.profile
);
240 struct nouveau_bo
*bsp_bo
= dec
->bsp_bo
[comm_seq
% NOUVEAU_VP3_VIDEO_QDEPTH
];
242 uint32_t endmarker
, caps
;
243 struct strparm_bsp
*str_bsp
;
248 * 0x000..0x100: picparm_bsp
249 * 0x200..0x500: picparm_vp
251 * 0x700..onward: raw bitstream
255 case PIPE_VIDEO_FORMAT_MPEG12
:
256 endmarker
= 0xb7010000;
257 caps
= nouveau_vp3_fill_picparm_mpeg12_bsp(dec
, desc
.mpeg12
, bsp
);
259 case PIPE_VIDEO_FORMAT_MPEG4
:
260 endmarker
= 0xb1010000;
261 caps
= nouveau_vp3_fill_picparm_mpeg4_bsp(dec
, desc
.mpeg4
, bsp
);
263 case PIPE_VIDEO_FORMAT_VC1
: {
264 endmarker
= 0x0a010000;
265 caps
= nouveau_vp3_fill_picparm_vc1_bsp(dec
, desc
.vc1
, bsp
);
268 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
269 endmarker
= 0x0b010000;
270 caps
= nouveau_vp3_fill_picparm_h264_bsp(dec
, desc
.h264
, bsp
);
273 default: assert(0); return -1;
276 caps
|= 0 << 16; // reset struct comm if flag is set
277 caps
|= 1 << 17; // enable watchdog
278 caps
|= 0 << 18; // do not report error to VP, so it can continue decoding what we have
279 caps
|= 0 << 19; // if enabled, use crypto crap?
282 str_bsp
= (struct strparm_bsp
*)bsp
;
283 memset(str_bsp
, 0, 0x80);
285 str_bsp
->w1
[0] = 0x1;
287 /* Reserved for picparm_vp */
289 /* Reserved for comm */
290 #if !NOUVEAU_VP3_DEBUG_FENCE
291 memset(bsp
, 0, 0x200);
294 for (i
= 0; i
< num_buffers
; ++i
) {
295 memcpy(bsp
, data
[i
], num_bytes
[i
]);
297 str_bsp
->w0
[0] += num_bytes
[i
];
300 /* Append end sequence */
301 *(uint32_t *)bsp
= endmarker
;
303 *(uint32_t *)bsp
= 0x00000000;
305 *(uint32_t *)bsp
= endmarker
;
307 *(uint32_t *)bsp
= 0x00000000;