Rev 6121 | Rev 6135 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6121 | Rev 6133 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | #include |
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | #include |
6 | #include |
7 | #include |
7 | #include |
8 | #include |
8 | #include |
9 | #include |
9 | #include |
10 | #include |
10 | #include |
11 | #include |
11 | #include |
12 | #include |
12 | #include |
13 | #include "winlib/winlib.h" |
13 | #include "winlib/winlib.h" |
14 | #include "fplay.h" |
14 | #include "fplay.h" |
15 | 15 | ||
16 | struct hw_profile |
16 | struct hw_profile |
17 | { |
17 | { |
18 | enum AVCodecID av_codec; |
18 | enum AVCodecID av_codec; |
19 | int ff_profile; |
19 | int ff_profile; |
20 | uint64_t va_profile; |
20 | VAProfile va_profile; |
21 | }; |
21 | }; |
22 | 22 | ||
23 | 23 | ||
24 | #define ENTER() printf("enter %s\n",__FUNCTION__) |
24 | #define ENTER() printf("enter %s\n",__FUNCTION__) |
25 | #define LEAVE() printf("leave %s\n",__FUNCTION__) |
25 | #define LEAVE() printf("leave %s\n",__FUNCTION__) |
26 | #define FAIL() printf("fail %s\n",__FUNCTION__) |
26 | #define FAIL() printf("fail %s\n",__FUNCTION__) |
27 | 27 | ||
28 | 28 | ||
29 | #if DEBUG |
29 | #if DEBUG |
30 | # define D(x) x |
30 | # define D(x) x |
31 | # define bug printf |
31 | # define bug printf |
32 | #else |
32 | #else |
33 | # define D(x) |
33 | # define D(x) |
34 | #endif |
34 | #endif |
35 | 35 | ||
36 | #undef ARRAY_ELEMS |
36 | #undef ARRAY_ELEMS |
37 | #define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) |
37 | #define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) |
38 | 38 | ||
39 | static int drm_fd = 0; |
39 | static int drm_fd = 0; |
40 | static struct vaapi_context *v_context; |
40 | static struct vaapi_context *v_context; |
41 | 41 | ||
42 | static VASurfaceID v_surface_id[4]; |
42 | static VASurfaceID v_surface_id[HWDEC_NUM_SURFACES]; |
43 | 43 | ||
44 | #define HAS_HEVC VA_CHECK_VERSION(0, 38, 0) |
44 | #define HAS_HEVC VA_CHECK_VERSION(0, 38, 0) |
45 | #define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0)) |
45 | #define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0)) |
46 | 46 | ||
47 | #define PE(av_codec_id, ff_profile, vdp_profile) \ |
47 | #define PE(av_codec_id, ff_profile, vdp_profile) \ |
48 | {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile, \ |
48 | {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile, \ |
49 | VAProfile ## vdp_profile} |
49 | VAProfile ## vdp_profile} |
50 | 50 | ||
51 | static const struct hw_profile profiles[] = { |
51 | static const struct hw_profile hw_profiles[] = { |
52 | PE(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main), |
52 | PE(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main), |
53 | PE(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple), |
53 | PE(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple), |
54 | PE(MPEG4, MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple), |
54 | PE(MPEG4, MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple), |
55 | PE(MPEG4, MPEG4_MAIN, MPEG4Main), |
55 | PE(MPEG4, MPEG4_MAIN, MPEG4Main), |
56 | PE(MPEG4, MPEG4_SIMPLE, MPEG4Simple), |
56 | PE(MPEG4, MPEG4_SIMPLE, MPEG4Simple), |
57 | PE(H264, H264_HIGH, H264High), |
57 | PE(H264, H264_HIGH, H264High), |
58 | PE(H264, H264_MAIN, H264Main), |
58 | PE(H264, H264_MAIN, H264Main), |
59 | PE(H264, H264_BASELINE, H264Baseline), |
59 | PE(H264, H264_BASELINE, H264Baseline), |
60 | PE(VC1, VC1_ADVANCED, VC1Advanced), |
60 | PE(VC1, VC1_ADVANCED, VC1Advanced), |
61 | PE(VC1, VC1_MAIN, VC1Main), |
61 | PE(VC1, VC1_MAIN, VC1Main), |
62 | PE(VC1, VC1_SIMPLE, VC1Simple), |
62 | PE(VC1, VC1_SIMPLE, VC1Simple), |
63 | PE(WMV3, VC1_ADVANCED, VC1Advanced), |
63 | PE(WMV3, VC1_ADVANCED, VC1Advanced), |
64 | PE(WMV3, VC1_MAIN, VC1Main), |
64 | PE(WMV3, VC1_MAIN, VC1Main), |
65 | PE(WMV3, VC1_SIMPLE, VC1Simple), |
65 | PE(WMV3, VC1_SIMPLE, VC1Simple), |
66 | #if HAS_HEVC |
66 | #if HAS_HEVC |
67 | PE(HEVC, HEVC_MAIN, HEVCMain), |
67 | PE(HEVC, HEVC_MAIN, HEVCMain), |
68 | PE(HEVC, HEVC_MAIN_10, HEVCMain10), |
68 | PE(HEVC, HEVC_MAIN_10, HEVCMain10), |
69 | #endif |
69 | #endif |
70 | #if HAS_VP9 |
70 | #if HAS_VP9 |
71 | PE(VP9, VP9_0, VP9Profile0), |
71 | PE(VP9, VP9_0, VP9Profile0), |
72 | #endif |
72 | #endif |
73 | {0} |
73 | {0} |
74 | }; |
74 | }; |
75 | 75 | ||
76 | int va_check_codec_support(enum AVCodecID id) |
76 | int va_check_codec_support(enum AVCodecID id) |
77 | { |
77 | { |
78 | for (int n = 0; profiles[n].av_codec; n++) { |
78 | for (int n = 0; hw_profiles[n].av_codec; n++) { |
79 | if (profiles[n].av_codec == id) |
79 | if (hw_profiles[n].av_codec == id) |
80 | return 1; |
80 | return 1; |
81 | } |
81 | } |
82 | return 0; |
82 | return 0; |
83 | } |
83 | } |
84 | 84 | ||
85 | static int vaapi_check_status(VAStatus status, const char *msg) |
85 | static int vaapi_check_status(VAStatus status, const char *msg) |
86 | { |
86 | { |
87 | if (status != VA_STATUS_SUCCESS) { |
87 | if (status != VA_STATUS_SUCCESS) { |
88 | fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status)); |
88 | fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status)); |
89 | return 0; |
89 | return 0; |
90 | } |
90 | } |
91 | return 1; |
91 | return 1; |
92 | }; |
92 | }; |
93 | 93 | ||
94 | static const char *string_of_VADisplayAttribType(VADisplayAttribType type) |
94 | static const char *string_of_VADisplayAttribType(VADisplayAttribType type) |
95 | { |
95 | { |
96 | switch (type) { |
96 | switch (type) { |
97 | #define TYPE(type) \ |
97 | #define TYPE(type) \ |
98 | case VADisplayAttrib##type: return "VADisplayAttrib" #type |
98 | case VADisplayAttrib##type: return "VADisplayAttrib" #type |
99 | TYPE(Brightness); |
99 | TYPE(Brightness); |
100 | TYPE(Contrast); |
100 | TYPE(Contrast); |
101 | TYPE(Hue); |
101 | TYPE(Hue); |
102 | TYPE(Saturation); |
102 | TYPE(Saturation); |
103 | TYPE(BackgroundColor); |
103 | TYPE(BackgroundColor); |
104 | #if !VA_CHECK_VERSION(0,34,0) |
104 | #if !VA_CHECK_VERSION(0,34,0) |
105 | TYPE(DirectSurface); |
105 | TYPE(DirectSurface); |
106 | #endif |
106 | #endif |
107 | #if VA_CHECK_VERSION(0,32,0) |
107 | #if VA_CHECK_VERSION(0,32,0) |
108 | TYPE(Rotation); |
108 | TYPE(Rotation); |
109 | #endif |
109 | #endif |
110 | #undef TYPE |
110 | #undef TYPE |
111 | default: break; |
111 | default: break; |
112 | } |
112 | } |
113 | return " |
113 | return " |
114 | } |
114 | } |
115 | 115 | ||
116 | static const char *string_of_VAProfile(VAProfile profile) |
116 | static const char *string_of_VAProfile(VAProfile profile) |
117 | { |
117 | { |
118 | switch (profile) { |
118 | switch (profile) { |
119 | #define PROFILE(profile) \ |
119 | #define PROFILE(profile) \ |
120 | case VAProfile##profile: return "VAProfile" #profile |
120 | case VAProfile##profile: return "VAProfile" #profile |
121 | PROFILE(MPEG2Simple); |
121 | PROFILE(MPEG2Simple); |
122 | PROFILE(MPEG2Main); |
122 | PROFILE(MPEG2Main); |
123 | PROFILE(MPEG4Simple); |
123 | PROFILE(MPEG4Simple); |
124 | PROFILE(MPEG4AdvancedSimple); |
124 | PROFILE(MPEG4AdvancedSimple); |
125 | PROFILE(MPEG4Main); |
125 | PROFILE(MPEG4Main); |
126 | #if VA_CHECK_VERSION(0,32,0) |
126 | #if VA_CHECK_VERSION(0,32,0) |
127 | PROFILE(JPEGBaseline); |
127 | PROFILE(JPEGBaseline); |
128 | PROFILE(H263Baseline); |
128 | PROFILE(H263Baseline); |
129 | PROFILE(H264ConstrainedBaseline); |
129 | PROFILE(H264ConstrainedBaseline); |
130 | #endif |
130 | #endif |
131 | PROFILE(H264Baseline); |
131 | PROFILE(H264Baseline); |
132 | PROFILE(H264Main); |
132 | PROFILE(H264Main); |
133 | PROFILE(H264High); |
133 | PROFILE(H264High); |
134 | PROFILE(VC1Simple); |
134 | PROFILE(VC1Simple); |
135 | PROFILE(VC1Main); |
135 | PROFILE(VC1Main); |
136 | PROFILE(VC1Advanced); |
136 | PROFILE(VC1Advanced); |
137 | #undef PROFILE |
137 | #undef PROFILE |
138 | default: break; |
138 | default: break; |
139 | } |
139 | } |
140 | return " |
140 | return " |
141 | } |
141 | } |
142 | 142 | ||
143 | static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) |
143 | static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) |
144 | { |
144 | { |
145 | switch (entrypoint) { |
145 | switch (entrypoint) { |
146 | #define ENTRYPOINT(entrypoint) \ |
146 | #define ENTRYPOINT(entrypoint) \ |
147 | case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint |
147 | case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint |
148 | ENTRYPOINT(VLD); |
148 | ENTRYPOINT(VLD); |
149 | ENTRYPOINT(IZZ); |
149 | ENTRYPOINT(IZZ); |
150 | ENTRYPOINT(IDCT); |
150 | ENTRYPOINT(IDCT); |
151 | ENTRYPOINT(MoComp); |
151 | ENTRYPOINT(MoComp); |
152 | ENTRYPOINT(Deblocking); |
152 | ENTRYPOINT(Deblocking); |
153 | #if VA_CHECK_VERSION(0,32,0) |
153 | #if VA_CHECK_VERSION(0,32,0) |
154 | ENTRYPOINT(EncSlice); |
154 | ENTRYPOINT(EncSlice); |
155 | ENTRYPOINT(EncPicture); |
155 | ENTRYPOINT(EncPicture); |
156 | #endif |
156 | #endif |
157 | #undef ENTRYPOINT |
157 | #undef ENTRYPOINT |
158 | default: break; |
158 | default: break; |
159 | } |
159 | } |
160 | return " |
160 | return " |
161 | } |
161 | } |
162 | 162 | ||
163 | VADisplay va_open_display(void) |
163 | VADisplay va_open_display(void) |
164 | { |
164 | { |
165 | VADisplay va_dpy; |
165 | VADisplay va_dpy; |
166 | 166 | ||
167 | drm_fd = get_service("DISPLAY"); |
167 | drm_fd = get_service("DISPLAY"); |
168 | if (drm_fd == 0) |
168 | if (drm_fd == 0) |
169 | return NULL; |
169 | return NULL; |
170 | 170 | ||
171 | va_dpy = vaGetDisplayDRM(drm_fd); |
171 | va_dpy = vaGetDisplayDRM(drm_fd); |
172 | if (va_dpy) |
172 | if (va_dpy) |
173 | return va_dpy; |
173 | return va_dpy; |
174 | 174 | ||
175 | drm_fd = 0; |
175 | drm_fd = 0; |
176 | return NULL; |
176 | return NULL; |
177 | }; |
177 | }; |
178 | 178 | ||
179 | void *vaapi_init(VADisplay display) |
179 | void *vaapi_init(VADisplay display) |
180 | { |
180 | { |
181 | struct vaapi_context *vaapi; |
181 | struct vaapi_context *vaapi; |
182 | int major_version, minor_version; |
182 | int major_version, minor_version; |
183 | int i, num_display_attrs, max_display_attrs; |
183 | int i, num_display_attrs, max_display_attrs; |
184 | VADisplayAttribute *display_attrs = NULL; |
184 | VADisplayAttribute *display_attrs = NULL; |
185 | VAStatus status; |
185 | VAStatus status; |
186 | 186 | ||
187 | if (v_context) |
187 | if (v_context) |
188 | return 0; |
188 | return 0; |
189 | 189 | ||
190 | if (!display) |
190 | if (!display) |
191 | goto error; |
191 | goto error; |
192 | D(bug("VA display %p\n", display)); |
192 | D(bug("VA display %p\n", display)); |
193 | 193 | ||
194 | status = vaInitialize(display, &major_version, &minor_version); |
194 | status = vaInitialize(display, &major_version, &minor_version); |
195 | if (!vaapi_check_status(status, "vaInitialize()")) |
195 | if (!vaapi_check_status(status, "vaInitialize()")) |
196 | goto error; |
196 | goto error; |
197 | D(bug("VA API version %d.%d\n", major_version, minor_version)); |
197 | D(bug("VA API version %d.%d\n", major_version, minor_version)); |
198 | 198 | ||
199 | max_display_attrs = vaMaxNumDisplayAttributes(display); |
199 | max_display_attrs = vaMaxNumDisplayAttributes(display); |
200 | display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0])); |
200 | display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0])); |
201 | if (!display_attrs) |
201 | if (!display_attrs) |
202 | goto error; |
202 | goto error; |
203 | 203 | ||
204 | num_display_attrs = 0; /* XXX: workaround old GMA500 bug */ |
204 | num_display_attrs = 0; /* XXX: workaround old GMA500 bug */ |
205 | status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs); |
205 | status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs); |
206 | if (!vaapi_check_status(status, "vaQueryDisplayAttributes()")) |
206 | if (!vaapi_check_status(status, "vaQueryDisplayAttributes()")) |
207 | goto error; |
207 | goto error; |
208 | D(bug("%d display attributes available\n", num_display_attrs)); |
208 | D(bug("%d display attributes available\n", num_display_attrs)); |
209 | for (i = 0; i < num_display_attrs; i++) { |
209 | for (i = 0; i < num_display_attrs; i++) { |
210 | VADisplayAttribute * const display_attr = &display_attrs[i]; |
210 | VADisplayAttribute * const display_attr = &display_attrs[i]; |
211 | D(bug(" %-32s (%s/%s) min %d max %d value 0x%x\n", |
211 | D(bug(" %-32s (%s/%s) min %d max %d value 0x%x\n", |
212 | string_of_VADisplayAttribType(display_attr->type), |
212 | string_of_VADisplayAttribType(display_attr->type), |
213 | (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---", |
213 | (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---", |
214 | (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---", |
214 | (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---", |
215 | display_attr->min_value, |
215 | display_attr->min_value, |
216 | display_attr->max_value, |
216 | display_attr->max_value, |
217 | display_attr->value)); |
217 | display_attr->value)); |
218 | } |
218 | } |
219 | 219 | ||
220 | if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL) |
220 | if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL) |
221 | goto error; |
221 | goto error; |
222 | vaapi->display = display; |
222 | vaapi->display = display; |
223 | vaapi->config_id = VA_INVALID_ID; |
223 | vaapi->config_id = VA_INVALID_ID; |
224 | vaapi->context_id = VA_INVALID_ID; |
224 | vaapi->context_id = VA_INVALID_ID; |
225 | 225 | ||
226 | v_context = vaapi; |
226 | v_context = vaapi; |
227 | 227 | ||
228 | return vaapi; |
228 | return vaapi; |
229 | 229 | ||
230 | error: |
230 | error: |
231 | free(display_attrs); |
231 | free(display_attrs); |
232 | return NULL; |
232 | return NULL; |
233 | } |
233 | } |
234 | 234 | ||
235 | static int has_profile(struct vaapi_context *vaapi, VAProfile profile) |
235 | static int has_profile(struct vaapi_context *vaapi, VAProfile profile) |
236 | { |
236 | { |
237 | VAProfile *profiles; |
237 | VAProfile *profiles; |
238 | int n_profiles; |
238 | int n_profiles; |
239 | VAStatus status; |
239 | VAStatus status; |
240 | int i; |
240 | int i; |
241 | 241 | ||
242 | profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0])); |
242 | profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0])); |
243 | 243 | ||
244 | status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles); |
244 | status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles); |
245 | 245 | ||
246 | if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) |
246 | if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) |
247 | return 0; |
247 | return 0; |
248 | 248 | ||
249 | D(bug("%d profiles available\n", n_profiles)); |
249 | D(bug("%d profiles available\n", n_profiles)); |
250 | 250 | ||
251 | for (i = 0; i < n_profiles; i++) |
251 | for (i = 0; i < n_profiles; i++) |
252 | { |
252 | { |
253 | if (profiles[i] == profile) |
253 | if (profiles[i] == profile) |
254 | return 1; |
254 | return 1; |
255 | } |
255 | } |
256 | return 0; |
256 | return 0; |
257 | } |
257 | } |
258 | 258 | ||
259 | static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint) |
259 | static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint) |
260 | { |
260 | { |
261 | VAEntrypoint *entrypoints; |
261 | VAEntrypoint *entrypoints; |
262 | int n_entrypoints; |
262 | int n_entrypoints; |
263 | VAStatus status; |
263 | VAStatus status; |
264 | int i; |
264 | int i; |
265 | 265 | ||
266 | entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0])); |
266 | entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0])); |
267 | 267 | ||
268 | status = vaQueryConfigEntrypoints(vaapi->display, profile, |
268 | status = vaQueryConfigEntrypoints(vaapi->display, profile, |
269 | entrypoints, &n_entrypoints); |
269 | entrypoints, &n_entrypoints); |
270 | if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()")) |
270 | if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()")) |
271 | return 0; |
271 | return 0; |
272 | 272 | ||
273 | D(bug("%d entrypoints available for %s\n", n_entrypoints, |
273 | D(bug("%d entrypoints available for %s\n", n_entrypoints, |
274 | string_of_VAProfile(profile))); |
274 | string_of_VAProfile(profile))); |
275 | 275 | ||
276 | for (i = 0; i < n_entrypoints; i++) |
276 | for (i = 0; i < n_entrypoints; i++) |
277 | { |
277 | { |
278 | if (entrypoints[i] == entrypoint) |
278 | if (entrypoints[i] == entrypoint) |
279 | return 1; |
279 | return 1; |
280 | } |
280 | } |
281 | return 0; |
281 | return 0; |
282 | } |
282 | } |
283 | 283 | ||
284 | static int vaapi_init_decoder(VAProfile profile, |
284 | static int vaapi_init_decoder(VAProfile profile, |
285 | VAEntrypoint entrypoint, |
285 | VAEntrypoint entrypoint, |
286 | unsigned int picture_width, |
286 | unsigned int picture_width, |
287 | unsigned int picture_height) |
287 | unsigned int picture_height) |
288 | { |
288 | { |
289 | struct vaapi_context* const vaapi = v_context; |
289 | struct vaapi_context* const vaapi = v_context; |
290 | VAConfigAttrib attrib; |
290 | VAConfigAttrib attrib; |
291 | VAConfigID config_id = VA_INVALID_ID; |
291 | VAConfigID config_id = VA_INVALID_ID; |
292 | VAContextID context_id = VA_INVALID_ID; |
292 | VAContextID context_id = VA_INVALID_ID; |
293 | VAStatus status; |
293 | VAStatus status; |
294 | 294 | ||
295 | ENTER(); |
295 | ENTER(); |
296 | if (!vaapi) |
296 | if (!vaapi) |
297 | { |
297 | { |
298 | FAIL(); |
298 | FAIL(); |
299 | return -1; |
299 | return -1; |
300 | }; |
300 | }; |
301 | 301 | ||
302 | if (!has_profile(vaapi, profile)) |
302 | if (!has_profile(vaapi, profile)) |
303 | { |
303 | { |
304 | FAIL(); |
304 | FAIL(); |
305 | return -1; |
305 | return -1; |
306 | }; |
306 | }; |
307 | 307 | ||
308 | if (!has_entrypoint(vaapi, profile, entrypoint)) |
308 | if (!has_entrypoint(vaapi, profile, entrypoint)) |
309 | { |
309 | { |
310 | FAIL(); |
310 | FAIL(); |
311 | return -1; |
311 | return -1; |
312 | }; |
312 | }; |
313 | 313 | ||
314 | if (vaapi->config_id != VA_INVALID_ID) |
314 | if (vaapi->config_id != VA_INVALID_ID) |
315 | vaDestroyConfig(vaapi->display, vaapi->config_id); |
315 | vaDestroyConfig(vaapi->display, vaapi->config_id); |
316 | 316 | ||
317 | attrib.type = VAConfigAttribRTFormat; |
317 | attrib.type = VAConfigAttribRTFormat; |
318 | 318 | ||
319 | printf("vaGetConfigAttributes\n"); |
319 | printf("vaGetConfigAttributes\n"); |
320 | status = vaGetConfigAttributes(vaapi->display, profile, entrypoint, |
320 | status = vaGetConfigAttributes(vaapi->display, profile, entrypoint, |
321 | &attrib, 1); |
321 | &attrib, 1); |
322 | if (!vaapi_check_status(status, "vaGetConfigAttributes()")) |
322 | if (!vaapi_check_status(status, "vaGetConfigAttributes()")) |
323 | { |
323 | { |
324 | FAIL(); |
324 | FAIL(); |
325 | return -1; |
325 | return -1; |
326 | } |
326 | } |
327 | 327 | ||
328 | if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) |
328 | if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) |
329 | { |
329 | { |
330 | printf("Chroma format not supported.\n"); |
330 | printf("Chroma format not supported.\n"); |
331 | FAIL(); |
331 | FAIL(); |
332 | return -1; |
332 | return -1; |
333 | }; |
333 | }; |
334 | 334 | ||
335 | printf("vaCreateConfig\n"); |
335 | printf("vaCreateConfig\n"); |
336 | status = vaCreateConfig(vaapi->display, profile, entrypoint, |
336 | status = vaCreateConfig(vaapi->display, profile, entrypoint, |
337 | &attrib, 1, &config_id); |
337 | &attrib, 1, &config_id); |
338 | if (!vaapi_check_status(status, "vaCreateConfig()")) |
338 | if (!vaapi_check_status(status, "vaCreateConfig()")) |
339 | { |
339 | { |
340 | FAIL(); |
340 | FAIL(); |
341 | return -1; |
341 | return -1; |
342 | } |
342 | } |
343 | 343 | ||
344 | printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height); |
344 | printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height); |
345 | status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height, |
345 | status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height, |
346 | v_surface_id,4,NULL,0); |
346 | v_surface_id,HWDEC_NUM_SURFACES,NULL,0); |
347 | printf("v_surface_id_3 %x\n", v_surface_id[3]); |
- | |
348 | if (!vaapi_check_status(status, "vaCreateSurfaces()")) |
347 | if (!vaapi_check_status(status, "vaCreateSurfaces()")) |
349 | { |
348 | { |
350 | FAIL(); |
349 | FAIL(); |
351 | return -1; |
350 | return -1; |
352 | }; |
351 | }; |
353 | { |
352 | { |
354 | VAImage vaimage; |
353 | VAImage vaimage; |
355 | VABufferInfo info = {0}; |
354 | VABufferInfo info = {0}; |
356 | 355 | ||
357 | vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage); |
356 | vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage); |
358 | printf("vaDeriveImage: %x fourcc: %x\n" |
357 | printf("vaDeriveImage: %x fourcc: %x\n" |
359 | "offset0: %d pitch0: %d\n" |
358 | "offset0: %d pitch0: %d\n" |
360 | "offset1: %d pitch1: %d\n" |
359 | "offset1: %d pitch1: %d\n" |
361 | "offset2: %d pitch2: %d\n", |
360 | "offset2: %d pitch2: %d\n", |
362 | vaimage.buf, vaimage.format.fourcc, |
361 | vaimage.buf, vaimage.format.fourcc, |
363 | vaimage.offsets[0],vaimage.pitches[0], |
362 | vaimage.offsets[0],vaimage.pitches[0], |
364 | vaimage.offsets[1],vaimage.pitches[1], |
363 | vaimage.offsets[1],vaimage.pitches[1], |
365 | vaimage.offsets[2],vaimage.pitches[2]); |
364 | vaimage.offsets[2],vaimage.pitches[2]); |
366 | 365 | ||
367 | info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; |
366 | info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; |
368 | vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info); |
367 | vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info); |
369 | printf("vaAcquireBufferHandle: %x type: %x\n" |
368 | printf("vaAcquireBufferHandle: %x type: %x\n" |
370 | "mem type: %x mem size: %x\n", |
369 | "mem type: %x mem size: %x\n", |
371 | info.handle, info.type, info.mem_type, info.mem_size); |
370 | info.handle, info.type, info.mem_type, info.mem_size); |
372 | 371 | ||
373 | vaReleaseBufferHandle(vaapi->display, vaimage.buf); |
372 | vaReleaseBufferHandle(vaapi->display, vaimage.buf); |
374 | 373 | ||
375 | vaDestroyImage(vaapi->display,vaimage.image_id); |
374 | vaDestroyImage(vaapi->display,vaimage.image_id); |
376 | }; |
375 | }; |
377 | 376 | ||
378 | printf("vaCreateContext %dx%d\n",picture_width,picture_height); |
377 | printf("vaCreateContext %dx%d\n",picture_width,picture_height); |
379 | status = vaCreateContext(vaapi->display, config_id, |
378 | status = vaCreateContext(vaapi->display, config_id, |
380 | picture_width, picture_height, |
379 | picture_width, picture_height, |
381 | VA_PROGRESSIVE, |
380 | VA_PROGRESSIVE, |
382 | v_surface_id, 4, |
381 | v_surface_id, HWDEC_NUM_SURFACES, |
383 | &context_id); |
382 | &context_id); |
384 | if (!vaapi_check_status(status, "vaCreateContext()")) |
383 | if (!vaapi_check_status(status, "vaCreateContext()")) |
385 | { |
384 | { |
386 | FAIL(); |
385 | FAIL(); |
387 | return -1; |
386 | return -1; |
388 | }; |
387 | }; |
389 | 388 | ||
390 | vaapi->config_id = config_id; |
389 | vaapi->config_id = config_id; |
391 | vaapi->context_id = context_id; |
390 | vaapi->context_id = context_id; |
392 | LEAVE(); |
391 | LEAVE(); |
393 | return 0; |
392 | return 0; |
394 | } |
393 | } |
395 | 394 | ||
396 | 395 | ||
397 | static enum PixelFormat get_format(struct AVCodecContext *avctx, |
396 | static enum PixelFormat get_format(struct AVCodecContext *avctx, |
398 | const enum AVPixelFormat *fmt) |
397 | const enum AVPixelFormat *fmt) |
399 | { |
398 | { |
400 | int i, profile; |
399 | VAProfile profile = VAProfileNone; |
401 | 400 | ||
402 | ENTER(); |
401 | ENTER(); |
403 | 402 | ||
- | 403 | for (int i = 0; fmt[i] != PIX_FMT_NONE; i++) |
|
404 | // for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) |
404 | { |
405 | // printf(" %s", av_get_pix_fmt_name(fmt[i])); |
- | |
406 | - | ||
407 | for (i = 0; fmt[i] != PIX_FMT_NONE; i++) { |
405 | enum AVCodecID codec = avctx->codec_id; |
408 | printf("pixformat %x\n", fmt[i]); |
406 | |
409 | if (fmt[i] != AV_PIX_FMT_VAAPI_VLD) |
407 | if (fmt[i] != AV_PIX_FMT_VAAPI_VLD) |
410 | continue; |
408 | continue; |
411 | 409 | ||
412 | switch (avctx->codec_id) |
410 | if (codec == AV_CODEC_ID_H264) |
413 | { |
411 | { |
414 | case CODEC_ID_MPEG2VIDEO: |
412 | if (profile == FF_PROFILE_H264_CONSTRAINED_BASELINE) |
415 | profile = VAProfileMPEG2Main; |
413 | profile = FF_PROFILE_H264_MAIN; |
416 | break; |
- | |
417 | case CODEC_ID_MPEG4: |
- | |
- | 414 | }; |
|
418 | case CODEC_ID_H263: |
415 | |
419 | profile = VAProfileMPEG4AdvancedSimple; |
416 | for (int n = 0; hw_profiles[n].av_codec; n++) |
420 | break; |
- | |
421 | case CODEC_ID_H264: |
417 | { |
422 | profile = VAProfileH264High; |
- | |
423 | break; |
- | |
424 | case CODEC_ID_WMV3: |
418 | if (hw_profiles[n].av_codec == codec && |
425 | profile = VAProfileVC1Main; |
419 | hw_profiles[n].ff_profile == avctx->profile) |
426 | break; |
- | |
427 | case CODEC_ID_VC1: |
420 | { |
428 | profile = VAProfileVC1Advanced; |
- | |
429 | break; |
- | |
430 | default: |
- | |
431 | profile = -1; |
- | |
432 | break; |
- | |
433 | } |
- | |
434 | if (profile >= 0) { |
421 | profile = hw_profiles[n].va_profile; |
435 | if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0) |
422 | if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0) |
436 | { |
423 | { |
437 | avctx->hwaccel_context = v_context; |
424 | avctx->hwaccel_context = v_context; |
438 | LEAVE(); |
425 | LEAVE(); |
439 | return fmt[i]; ; |
426 | return fmt[i]; ; |
440 | } |
427 | } |
441 | } |
428 | } |
442 | } |
429 | } |
- | 430 | ||
- | 431 | } |
|
443 | FAIL(); |
432 | FAIL(); |
444 | return PIX_FMT_NONE; |
433 | return PIX_FMT_NONE; |
445 | } |
434 | } |
446 | 435 | ||
447 | struct av_surface |
436 | struct av_surface |
448 | { |
437 | { |
449 | int w; |
438 | int w; |
450 | int h; |
439 | int h; |
451 | VASurfaceID id; |
440 | VASurfaceID id; |
452 | }; |
441 | }; |
453 | 442 | ||
454 | static void av_release_buffer(void *opaque, uint8_t *data) |
443 | static void av_release_buffer(void *opaque, uint8_t *data) |
455 | { |
444 | { |
456 | struct av_surface surface = *(struct av_surface*)data; |
445 | struct av_surface surface = *(struct av_surface*)data; |
457 | // VDPAUContext *ctx = opaque; |
- | |
458 | - | ||
459 | // ctx->video_surface_destroy(surface); |
- | |
460 | av_freep(&data); |
446 | av_freep(&data); |
461 | } |
447 | } |
462 | 448 | ||
463 | static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) |
449 | static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) |
464 | { |
450 | { |
465 | vst_t *vst = (vst_t*)avctx->opaque; |
451 | vst_t *vst = (vst_t*)avctx->opaque; |
- | 452 | void *surface; |
|
- | 453 | ||
466 | void *surface = (void *)(uintptr_t)v_surface_id[vst->dfx]; |
454 | surface = (void *)(uintptr_t)v_surface_id[vst->decoder_frame->index]; |
467 | 455 | ||
468 | pic->data[3] = surface; |
456 | pic->data[3] = surface; |
469 | 457 | ||
470 | struct av_surface *avsurface; |
458 | struct av_surface *avsurface; |
471 | surface = av_malloc(sizeof(*avsurface)); |
459 | surface = av_malloc(sizeof(*avsurface)); |
472 | if (!surface) |
460 | if (!surface) |
473 | return AVERROR(ENOMEM); |
461 | return AVERROR(ENOMEM); |
474 | 462 | ||
475 | pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface), |
463 | pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface), |
476 | av_release_buffer, avctx, |
464 | av_release_buffer, avctx, |
477 | AV_BUFFER_FLAG_READONLY); |
465 | AV_BUFFER_FLAG_READONLY); |
478 | return 0; |
466 | return 0; |
479 | } |
467 | } |
480 | 468 | ||
481 | struct vaapi_context va_context_storage; |
469 | struct vaapi_context va_context_storage; |
482 | 470 | ||
483 | int fplay_init_context(vst_t *vst) |
471 | int fplay_init_context(vst_t *vst) |
484 | { |
472 | { |
485 | AVCodecContext *vCtx = vst->vCtx; |
473 | AVCodecContext *vCtx = vst->vCtx; |
486 | 474 | ||
487 | if(va_check_codec_support(vCtx->codec_id)) |
475 | if(va_check_codec_support(vCtx->codec_id)) |
488 | { |
476 | { |
489 | VADisplay dpy; |
477 | VADisplay dpy; |
490 | 478 | ||
491 | dpy = va_open_display(); |
479 | dpy = va_open_display(); |
492 | vst->hwCtx = vaapi_init(dpy); |
480 | vst->hwCtx = vaapi_init(dpy); |
493 | 481 | ||
494 | if(vst->hwCtx != NULL) |
482 | if(vst->hwCtx != NULL) |
495 | { |
483 | { |
496 | for(int i = 0; i < 4; i++) |
484 | for(int i = 0; i < HWDEC_NUM_SURFACES; i++) |
497 | { |
485 | { |
498 | int ret; |
486 | vframe_t *vframe = calloc(1, sizeof(*vframe)); |
499 | 487 | ||
500 | ret = avpicture_alloc(&vst->vframe[i].picture, AV_PIX_FMT_BGRA, |
- | |
501 | vst->vCtx->width, vst->vCtx->height); |
488 | vframe->format = AV_PIX_FMT_NONE; |
502 | if ( ret != 0 ) |
- | |
503 | { |
- | |
504 | printf("Cannot alloc video buffer\n\r"); |
489 | vframe->is_hw_pic = 1; |
505 | return ret; |
- | |
506 | }; |
490 | vframe->index = i; |
507 | vst->vframe[i].format = AV_PIX_FMT_BGRA; |
491 | vframe->pts = 0; |
508 | vst->vframe[i].pts = 0; |
492 | vframe->ready = 0; |
509 | vst->vframe[i].ready = 0; |
493 | list_add_tail(&vframe->list, &vst->input_list); |
510 | }; |
494 | }; |
511 | 495 | ||
512 | vst->hwdec = 1; |
496 | vst->hwdec = 1; |
513 | vCtx->opaque = vst; |
497 | vCtx->opaque = vst; |
514 | vCtx->thread_count = 1; |
498 | vCtx->thread_count = 1; |
515 | vCtx->get_format = get_format; |
499 | vCtx->get_format = get_format; |
516 | vCtx->get_buffer2 = get_buffer2; |
500 | vCtx->get_buffer2 = get_buffer2; |
517 | return 0; |
501 | return 0; |
518 | }; |
502 | }; |
519 | }; |
503 | }; |
520 | 504 | ||
521 | vst->hwdec = 0; |
505 | vst->hwdec = 0; |
522 | 506 | ||
523 | for(int i = 0; i < 4; i++) |
507 | for(int i = 0; i < HWDEC_NUM_SURFACES; i++) |
- | 508 | { |
|
524 | { |
509 | vframe_t *vframe; |
- | 510 | int ret; |
|
- | 511 | ||
525 | int ret; |
512 | vframe = calloc(1, sizeof(*vframe)); |
526 | 513 | ||
527 | ret = avpicture_alloc(&vst->vframe[i].picture, vst->vCtx->pix_fmt, |
514 | ret = avpicture_alloc(&vframe->picture, vst->vCtx->pix_fmt, |
528 | vst->vCtx->width, vst->vCtx->height); |
515 | vst->vCtx->width, vst->vCtx->height); |
529 | if ( ret != 0 ) |
516 | if ( ret != 0 ) |
530 | { |
517 | { |
531 | printf("Cannot alloc video buffer\n\r"); |
518 | printf("Cannot alloc video buffer\n\r"); |
532 | return ret; |
519 | return ret; |
533 | }; |
520 | }; |
534 | vst->vframe[i].format = vst->vCtx->pix_fmt; |
521 | vframe->format = vst->vCtx->pix_fmt; |
- | 522 | vframe->index = i; |
|
535 | vst->vframe[i].pts = 0; |
523 | vframe->pts = 0; |
536 | vst->vframe[i].ready = 0; |
524 | vframe->ready = 0; |
- | 525 | list_add_tail(&vframe->list, &vst->input_list); |
|
537 | }; |
526 | }; |
538 | 527 | ||
539 | return 0; |
528 | return 0; |
540 | } |
529 | } |
541 | 530 | ||
- | 531 | ||
- | 532 | #define EGL_TEXTURE_Y_U_V_WL 0x31D7 |
|
- | 533 | #define EGL_TEXTURE_Y_UV_WL 0x31D8 |
|
- | 534 | #define EGL_TEXTURE_Y_XUXV_WL 0x31D9 |
|
542 | 535 | ||
- | 536 | enum wl_drm_format { |
|
- | 537 | WL_DRM_FORMAT_C8 = 0x20203843, |
|
- | 538 | WL_DRM_FORMAT_RGB332 = 0x38424752, |
|
- | 539 | WL_DRM_FORMAT_BGR233 = 0x38524742, |
|
- | 540 | WL_DRM_FORMAT_XRGB4444 = 0x32315258, |
|
- | 541 | WL_DRM_FORMAT_XBGR4444 = 0x32314258, |
|
- | 542 | WL_DRM_FORMAT_RGBX4444 = 0x32315852, |
|
- | 543 | WL_DRM_FORMAT_BGRX4444 = 0x32315842, |
|
- | 544 | WL_DRM_FORMAT_ARGB4444 = 0x32315241, |
|
- | 545 | WL_DRM_FORMAT_ABGR4444 = 0x32314241, |
|
- | 546 | WL_DRM_FORMAT_RGBA4444 = 0x32314152, |
|
- | 547 | WL_DRM_FORMAT_BGRA4444 = 0x32314142, |
|
- | 548 | WL_DRM_FORMAT_XRGB1555 = 0x35315258, |
|
- | 549 | WL_DRM_FORMAT_XBGR1555 = 0x35314258, |
|
- | 550 | WL_DRM_FORMAT_RGBX5551 = 0x35315852, |
|
- | 551 | WL_DRM_FORMAT_BGRX5551 = 0x35315842, |
|
- | 552 | WL_DRM_FORMAT_ARGB1555 = 0x35315241, |
|
- | 553 | WL_DRM_FORMAT_ABGR1555 = 0x35314241, |
|
- | 554 | WL_DRM_FORMAT_RGBA5551 = 0x35314152, |
|
- | 555 | WL_DRM_FORMAT_BGRA5551 = 0x35314142, |
|
- | 556 | WL_DRM_FORMAT_RGB565 = 0x36314752, |
|
- | 557 | WL_DRM_FORMAT_BGR565 = 0x36314742, |
|
- | 558 | WL_DRM_FORMAT_RGB888 = 0x34324752, |
|
- | 559 | WL_DRM_FORMAT_BGR888 = 0x34324742, |
|
- | 560 | WL_DRM_FORMAT_XRGB8888 = 0x34325258, |
|
- | 561 | WL_DRM_FORMAT_XBGR8888 = 0x34324258, |
|
- | 562 | WL_DRM_FORMAT_RGBX8888 = 0x34325852, |
|
- | 563 | WL_DRM_FORMAT_BGRX8888 = 0x34325842, |
|
- | 564 | WL_DRM_FORMAT_ARGB8888 = 0x34325241, |
|
- | 565 | WL_DRM_FORMAT_ABGR8888 = 0x34324241, |
|
- | 566 | WL_DRM_FORMAT_RGBA8888 = 0x34324152, |
|
- | 567 | WL_DRM_FORMAT_BGRA8888 = 0x34324142, |
|
- | 568 | WL_DRM_FORMAT_XRGB2101010 = 0x30335258, |
|
- | 569 | WL_DRM_FORMAT_XBGR2101010 = 0x30334258, |
|
- | 570 | WL_DRM_FORMAT_RGBX1010102 = 0x30335852, |
|
- | 571 | WL_DRM_FORMAT_BGRX1010102 = 0x30335842, |
|
- | 572 | WL_DRM_FORMAT_ARGB2101010 = 0x30335241, |
|
- | 573 | WL_DRM_FORMAT_ABGR2101010 = 0x30334241, |
|
- | 574 | WL_DRM_FORMAT_RGBA1010102 = 0x30334152, |
|
- | 575 | WL_DRM_FORMAT_BGRA1010102 = 0x30334142, |
|
- | 576 | WL_DRM_FORMAT_YUYV = 0x56595559, |
|
- | 577 | WL_DRM_FORMAT_YVYU = 0x55595659, |
|
- | 578 | WL_DRM_FORMAT_UYVY = 0x59565955, |
|
- | 579 | WL_DRM_FORMAT_VYUY = 0x59555956, |
|
- | 580 | WL_DRM_FORMAT_AYUV = 0x56555941, |
|
- | 581 | WL_DRM_FORMAT_NV12 = 0x3231564e, |
|
- | 582 | WL_DRM_FORMAT_NV21 = 0x3132564e, |
|
- | 583 | WL_DRM_FORMAT_NV16 = 0x3631564e, |
|
- | 584 | WL_DRM_FORMAT_NV61 = 0x3136564e, |
|
- | 585 | WL_DRM_FORMAT_YUV410 = 0x39565559, |
|
- | 586 | WL_DRM_FORMAT_YVU410 = 0x39555659, |
|
- | 587 | WL_DRM_FORMAT_YUV411 = 0x31315559, |
|
- | 588 | WL_DRM_FORMAT_YVU411 = 0x31315659, |
|
- | 589 | WL_DRM_FORMAT_YUV420 = 0x32315559, |
|
- | 590 | WL_DRM_FORMAT_YVU420 = 0x32315659, |
|
- | 591 | WL_DRM_FORMAT_YUV422 = 0x36315559, |
|
- | 592 | WL_DRM_FORMAT_YVU422 = 0x36315659, |
|
- | 593 | WL_DRM_FORMAT_YUV444 = 0x34325559, |
|
- | 594 | WL_DRM_FORMAT_YVU444 = 0x34325659, |
|
543 | struct SwsContext *vacvt_ctx; |
595 | }; |
544 | 596 | ||
545 | void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic) |
597 | void va_create_planar(vst_t *vst, vframe_t *vframe) |
546 | { |
598 | { |
- | 599 | struct vaapi_context* const vaapi = v_context; |
|
547 | uint8_t *src_data[4]; |
600 | VABufferInfo info = {0}; |
548 | int src_linesize[4]; |
601 | |
549 | VAImage vaimage; |
602 | VAImage vaimage; |
550 | VAStatus status; |
- | |
551 | uint8_t *vdata; |
603 | VAStatus status; |
- | 604 | planar_t *planar; |
|
- | 605 | ||
- | 606 | vaSyncSurface(vaapi->display,v_surface_id[vframe->index]); |
|
- | 607 | ||
- | 608 | if(vframe->format != AV_PIX_FMT_NONE) |
|
552 | struct vaapi_context* const vaapi = v_context; |
609 | return; |
553 | 610 | ||
554 | vaSyncSurface(vaapi->display,v_surface_id[vst->dfx]); |
611 | ENTER(); |
555 | 612 | ||
556 | status = vaDeriveImage(vaapi->display,v_surface_id[vst->dfx],&vaimage); |
613 | status = vaDeriveImage(vaapi->display,v_surface_id[vframe->index],&vaimage); |
557 | if (!vaapi_check_status(status, "vaDeriveImage()")) |
614 | if (!vaapi_check_status(status, "vaDeriveImage()")) |
558 | { |
615 | { |
559 | FAIL(); |
616 | FAIL(); |
560 | return; |
617 | return; |
561 | }; |
618 | }; |
562 | - | ||
563 | static int once = 2; |
- | |
564 | - | ||
565 | if(once && vst->dfx == 0) |
- | |
566 | { |
- | |
567 | VABufferInfo info = {0}; |
- | |
568 | 619 | /* |
|
569 | printf("vaDeriveImage: %x fourcc: %x\n" |
620 | printf("vaDeriveImage: %x fourcc: %x\n" |
570 | "offset0: %d pitch0: %d\n" |
621 | "offset0: %d pitch0: %d\n" |
571 | "offset1: %d pitch1: %d\n" |
622 | "offset1: %d pitch1: %d\n" |
572 | "offset2: %d pitch2: %d\n", |
623 | "offset2: %d pitch2: %d\n", |
573 | vaimage.buf, vaimage.format.fourcc, |
624 | vaimage.buf, vaimage.format.fourcc, |
574 | vaimage.offsets[0],vaimage.pitches[0], |
625 | vaimage.offsets[0],vaimage.pitches[0], |
575 | vaimage.offsets[1],vaimage.pitches[1], |
626 | vaimage.offsets[1],vaimage.pitches[1], |
576 | vaimage.offsets[2],vaimage.pitches[2]); |
627 | vaimage.offsets[2],vaimage.pitches[2]); |
577 | 628 | */ |
|
578 | info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; |
629 | info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; |
579 | status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info); |
630 | status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info); |
580 | if (vaapi_check_status(status, "vaAcquireBufferHandle()")) |
631 | if (!vaapi_check_status(status, "vaAcquireBufferHandle()")) |
581 | { |
- | |
582 | printf("vaAcquireBufferHandle: %x type: %x\n" |
- | |
583 | "mem type: %x mem size: %d\n", |
- | |
584 | info.handle, info.type, info.mem_type, info.mem_size); |
- | |
585 | - | ||
586 | vaReleaseBufferHandle(vaapi->display, vaimage.buf); |
- | |
587 | } |
- | |
588 | once--; |
- | |
589 | }; |
- | |
590 | - | ||
591 | src_linesize[0] = vaimage.pitches[0]; |
- | |
592 | src_linesize[1] = vaimage.pitches[1]; |
- | |
593 | src_linesize[2] = vaimage.pitches[2]; |
- | |
594 | src_linesize[3] = 0; |
- | |
595 | - | ||
596 | status = vaMapBuffer(vaapi->display,vaimage.buf,(void **)&vdata); |
- | |
597 | if (!vaapi_check_status(status, "vaMapBuffer()")) |
- | |
598 | { |
632 | { |
- | 633 | vaDestroyImage(vaapi->display, vaimage.image_id); |
|
599 | FAIL(); |
634 | FAIL(); |
600 | return; |
635 | return; |
601 | }; |
636 | }; |
602 | 637 | /* |
|
603 | // printf("vdata: %x offset0: %d offset1: %d offset2: %d\n", vdata, |
638 | printf("vaAcquireBufferHandle: %x type: %x\n" |
604 | // vaimage.offsets[0], |
- | |
605 | // vaimage.offsets[1], |
639 | "mem type: %x mem size: %d\n", |
606 | // vaimage.offsets[2]); |
640 | info.handle, info.type, info.mem_type, info.mem_size); |
607 | 641 | */ |
|
608 | src_data[0] = vdata + vaimage.offsets[0]; |
642 | planar = pxCreatePlanar(info.handle, WL_DRM_FORMAT_NV12, |
609 | src_data[1] = vdata + vaimage.offsets[1]; |
643 | vaimage.width, vaimage.height, |
610 | src_data[2] = vdata + vaimage.offsets[2]; |
644 | vaimage.offsets[0],vaimage.pitches[0], |
611 | src_data[3] = 0; |
- | |
612 | - | ||
613 | vacvt_ctx = sws_getCachedContext(vacvt_ctx, width, height, AV_PIX_FMT_NV12, |
- | |
614 | width, height, AV_PIX_FMT_BGRA, |
645 | vaimage.offsets[1],vaimage.pitches[1], |
615 | SWS_FAST_BILINEAR, NULL, NULL, NULL); |
646 | vaimage.offsets[2],vaimage.pitches[2]); |
616 | if(vacvt_ctx == NULL) |
647 | if(planar != NULL) |
617 | { |
648 | { |
618 | printf("Cannot initialize the conversion context!\n"); |
649 | printf("create planar image\n",planar); |
619 | return ; |
650 | vframe->planar = planar; |
- | 651 | vframe->format = AV_PIX_FMT_NV12; |
|
620 | }; |
652 | }; |
621 | - | ||
622 | sws_scale(vacvt_ctx, (const uint8_t* const *)src_data, src_linesize, 0, height, pic->data, pic->linesize); |
- | |
623 | 653 | ||
624 | vaUnmapBuffer (vaapi->display, vaimage.buf); |
654 | vaReleaseBufferHandle(vaapi->display, vaimage.buf); |
- | 655 | vaDestroyImage(vaapi->display, vaimage.image_id); |
|
625 | vaDestroyImage(vaapi->display, vaimage.image_id); |
656 | LEAVE(); |
626 | }>>>>> |
657 | }>>>>> |