vaapi: fix VC-1 decoding on Sandy Bridge (propagate profile).
[hwdecode-demos:vj-hwdecode-demos.git] / src / vaapi_vc1.c
1 /*
2  *  vaapi_vc1.c - VC-1 decoding through VA API
3  *
4  *  hwdecode-demos (C) 2009-2010 Splitted-Desktop Systems
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "sysdeps.h"
22 #include "vaapi.h"
23 #include "vaapi_compat.h"
24 #include "vc1.h"
25
26 #ifdef USE_OLD_VAAPI
27 #define V_raw_coding       raw_coding_flag
28 #define M_raw_coding       raw_coding
29 #define V_bitplane_present bitplane_present_flag
30 #define M_bitplane_present bitplane_present
31 #else
32 #define V_raw_coding       raw_coding
33 #define M_raw_coding       raw_coding
34 #define V_bitplane_present bitplane_present
35 #define M_bitplane_present bitplane_present
36 #endif
37
38 int decode(void)
39 {
40     VAAPIContext * const vaapi = vaapi_get_context();
41     VAPictureParameterBufferVC1 *pic_param;
42     VASliceParameterBufferVC1 *slice_param;
43     uint8_t *bitplane;
44     int i, slice_count;
45
46     VC1PictureInfo vc1_pic_info;
47     VC1SliceInfo vc1_slice_info;
48     const uint8_t *vc1_bitplane;
49     unsigned int vc1_bitplane_size;
50     const uint8_t *vc1_slice_data;
51     unsigned int vc1_slice_data_size;
52
53     if (!vaapi)
54         return -1;
55
56     vc1_get_picture_info(&vc1_pic_info);
57
58     if (vaapi_init_decoder(VAProfileVC1Advanced, VAEntrypointVLD,
59                            vc1_pic_info.width, vc1_pic_info.height) < 0)
60         return -1;
61
62     if ((pic_param = vaapi_alloc_picture(sizeof(*pic_param))) == NULL)
63         return -1;
64
65 #define COPY(field) \
66     pic_param->field = vc1_pic_info.field
67 #define COPY_BFM(a,b,c) \
68     pic_param->BFM(a,b,c) = vc1_pic_info.a.b.c
69 #define COPY_BFMP(p,a,b,c) \
70     pic_param->BFMP(p,a,b,c) = vc1_pic_info.a.b.c
71     pic_param->forward_reference_picture = 0xffffffff;
72     pic_param->backward_reference_picture = 0xffffffff;
73     pic_param->inloop_decoded_picture = 0xffffffff;
74     pic_param->BFV(sequence_fields, value) = 0; /* reset all bits */
75     COPY_BFM(sequence_fields, bits, interlace);
76     COPY_BFM(sequence_fields, bits, syncmarker);
77     COPY_BFM(sequence_fields, bits, overlap);
78     NEW(COPY_BFM(sequence_fields, bits, pulldown));
79     NEW(COPY_BFM(sequence_fields, bits, tfcntrflag));
80     NEW(COPY_BFM(sequence_fields, bits, finterpflag));
81     NEW(COPY_BFM(sequence_fields, bits, psf));
82     NEW(COPY_BFM(sequence_fields, bits, multires));
83     NEW(COPY_BFM(sequence_fields, bits, rangered));
84     NEW(COPY_BFM(sequence_fields, bits, max_b_frames));
85 #if VA_CHECK_VERSION(0,32,0)
86     pic_param->BFM(sequence_fields, bits, profile) = vc1_pic_info.profile;
87 #endif
88     pic_param->coded_width = vc1_pic_info.width;
89     pic_param->coded_height = vc1_pic_info.height;
90     NEW(pic_param->BFV(entrypoint_fields, value) = 0); /* reset all bits */
91     COPY_BFM(entrypoint_fields, bits, broken_link);
92     COPY_BFM(entrypoint_fields, bits, closed_entry);
93     NEW(COPY_BFM(entrypoint_fields, bits, panscan_flag));
94     COPY_BFM(entrypoint_fields, bits, loopfilter);
95     COPY(conditional_overlap_flag);
96     COPY(fast_uvmc_flag);
97     pic_param->BFV(range_mapping_fields, value) = 0; /* reset all bits */
98     COPY_BFMP(range_mapping, range_mapping_fields, bits, luma_flag);
99     COPY_BFMP(range_mapping, range_mapping_fields, bits, luma);
100     COPY_BFMP(range_mapping, range_mapping_fields, bits, chroma_flag);
101     COPY_BFMP(range_mapping, range_mapping_fields, bits, chroma);
102     COPY(b_picture_fraction);
103     COPY(cbp_table);
104     COPY(mb_mode_table);
105     COPY(range_reduction_frame);
106     COPY(rounding_control);
107     COPY(post_processing);
108     COPY(picture_resolution_index);
109     COPY(luma_scale);
110     COPY(luma_shift);
111     pic_param->BFV(picture_fields, value) = 0; /* reset all bits */
112     COPY_BFM(picture_fields, bits, picture_type);
113     COPY_BFM(picture_fields, bits, frame_coding_mode);
114     COPY_BFM(picture_fields, bits, top_field_first);
115     COPY_BFM(picture_fields, bits, is_first_field);
116     COPY_BFM(picture_fields, bits, intensity_compensation);
117     pic_param->BFV(V_raw_coding, value) = 0; /* reset all bits */
118     COPY_BFM(M_raw_coding, flags, mv_type_mb);
119     COPY_BFM(M_raw_coding, flags, direct_mb);
120     COPY_BFM(M_raw_coding, flags, skip_mb);
121     COPY_BFM(M_raw_coding, flags, field_tx);
122     COPY_BFM(M_raw_coding, flags, forward_mb);
123     COPY_BFM(M_raw_coding, flags, ac_pred);
124     COPY_BFM(M_raw_coding, flags, overflags);
125     pic_param->BFV(V_bitplane_present, value) = 0; /* reset all bits */
126     COPY_BFM(M_bitplane_present, flags, bp_mv_type_mb);
127     COPY_BFM(M_bitplane_present, flags, bp_direct_mb);
128     COPY_BFM(M_bitplane_present, flags, bp_skip_mb);
129     COPY_BFM(M_bitplane_present, flags, bp_field_tx);
130     COPY_BFM(M_bitplane_present, flags, bp_forward_mb);
131     COPY_BFM(M_bitplane_present, flags, bp_ac_pred);
132     COPY_BFM(M_bitplane_present, flags, bp_overflags);
133     pic_param->BFV(reference_fields, value) = 0; /* reset all bits */
134     COPY_BFM(reference_fields, bits, reference_distance_flag);
135     COPY_BFM(reference_fields, bits, reference_distance);
136     COPY_BFM(reference_fields, bits, num_reference_pictures);
137     COPY_BFM(reference_fields, bits, reference_field_pic_indicator);
138     pic_param->BFV(mv_fields, value) = 0; /* reset all bits */
139     COPY_BFM(mv_fields, bits, mv_mode);
140     COPY_BFM(mv_fields, bits, mv_mode2);
141     COPY_BFM(mv_fields, bits, mv_table);
142     COPY_BFM(mv_fields, bits, two_mv_block_pattern_table);
143     COPY_BFM(mv_fields, bits, four_mv_switch);
144     COPY_BFM(mv_fields, bits, four_mv_block_pattern_table);
145     COPY_BFM(mv_fields, bits, extended_mv_flag);
146     COPY_BFM(mv_fields, bits, extended_mv_range);
147     COPY_BFM(mv_fields, bits, extended_dmv_flag);
148     COPY_BFM(mv_fields, bits, extended_dmv_range);
149     pic_param->BFV(pic_quantizer_fields, value) = 0; /* reset all bits */
150     COPY_BFM(pic_quantizer_fields, bits, dquant);
151     COPY_BFM(pic_quantizer_fields, bits, quantizer);
152     COPY_BFM(pic_quantizer_fields, bits, half_qp);
153     COPY_BFM(pic_quantizer_fields, bits, pic_quantizer_scale);
154     COPY_BFM(pic_quantizer_fields, bits, pic_quantizer_type);
155     COPY_BFM(pic_quantizer_fields, bits, dq_frame);
156     COPY_BFM(pic_quantizer_fields, bits, dq_profile);
157     COPY_BFM(pic_quantizer_fields, bits, dq_sb_edge);
158     COPY_BFM(pic_quantizer_fields, bits, dq_db_edge);
159     COPY_BFM(pic_quantizer_fields, bits, dq_binary_level);
160     COPY_BFM(pic_quantizer_fields, bits, alt_pic_quantizer);
161     pic_param->BFV(transform_fields, value) = 0; /* reset all bits */
162     COPY_BFM(transform_fields, bits, variable_sized_transform_flag);
163     COPY_BFM(transform_fields, bits, mb_level_transform_type_flag);
164     COPY_BFM(transform_fields, bits, frame_level_transform_type);
165     COPY_BFM(transform_fields, bits, transform_ac_codingset_idx1);
166     COPY_BFM(transform_fields, bits, transform_ac_codingset_idx2);
167     COPY_BFM(transform_fields, bits, intra_transform_dc_table);
168 #undef COPY_BFMP
169 #undef COPY_BFM
170 #undef COPY
171
172     if (pic_param->BFV(V_bitplane_present, value)) {
173         vc1_get_bitplane(&vc1_bitplane, &vc1_bitplane_size);
174         if ((bitplane = vaapi_alloc_bitplane(vc1_bitplane_size)) == NULL)
175             return -1;
176         memcpy(bitplane, vc1_bitplane, vc1_bitplane_size);
177     }
178
179     slice_count = vc1_get_slice_count();
180     for (i = 0; i < slice_count; i++) {
181         if (vc1_get_slice_info(i, &vc1_slice_info) < 0)
182             return -1;
183         if (vc1_get_slice_data(i, &vc1_slice_data, &vc1_slice_data_size) < 0)
184             return -1;
185         if (vc1_slice_data_size != vc1_slice_info.slice_data_size)
186             return -1;
187         if ((slice_param = vaapi_alloc_slice(sizeof(*slice_param),
188                                              vc1_slice_data,
189                                              vc1_slice_data_size)) == NULL)
190             return -1;
191
192 #define COPY(field) slice_param->field = vc1_slice_info.field
193         COPY(macroblock_offset);
194         COPY(slice_vertical_position);
195 #undef COPY
196     }
197
198     return vaapi_decode();
199 }