2 * gstvaapiprofile.c - VA profile abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library 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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 * SECTION:gstvaapiprofile
24 * @short_description: VA profile abstraction
29 #include <gst/gstbuffer.h>
30 #include "gstvaapicompat.h"
31 #include "gstvaapiprofile.h"
32 #include "gstvaapiworkarounds.h"
34 typedef struct _GstVaapiProfileMap GstVaapiProfileMap;
35 typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap;
37 struct _GstVaapiProfileMap {
38 GstVaapiProfile profile;
41 const gchar *profile_str;
44 struct _GstVaapiEntrypointMap {
45 GstVaapiEntrypoint entrypoint;
46 VAEntrypoint va_entrypoint;
50 static const GstVaapiProfileMap gst_vaapi_profiles[] = {
51 { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple,
52 "video/mpeg, mpegversion=2", "simple"
54 { GST_VAAPI_PROFILE_MPEG2_MAIN, VAProfileMPEG2Main,
55 "video/mpeg, mpegversion=2", "main"
57 { GST_VAAPI_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple,
58 "video/mpeg, mpegversion=4", "simple"
60 { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple,
61 "video/mpeg, mpegversion=4", "advanced-simple"
63 { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main,
64 "video/mpeg, mpegversion=4", "main"
66 { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple,
67 "video/x-divx, divxversion=5", "advanced-simple"
69 { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple,
70 "video/x-xvid", "advanced-simple"
72 #if VA_CHECK_VERSION(0,30,0)
73 { GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline,
74 "video/x-h263, variant=itu, h263version=h263", "baseline"
77 { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline,
78 "video/x-h264", "baseline"
80 { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main,
81 "video/x-h264", "main"
83 { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High,
84 "video/x-h264", "high"
86 { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple,
87 "video/x-wmv, wmvversion=3", "simple"
89 { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main,
90 "video/x-wmv, wmvversion=3", "main"
92 { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced,
93 "video/x-wmv, wmvversion=3, format=(fourcc)WVC1", "advanced"
95 #if VA_CHECK_VERSION(0,32,0)
96 { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline,
97 "image/jpeg", "baseline"
104 static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = {
105 { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD },
106 { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT },
107 { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp },
108 #if VA_CHECK_VERSION(0,30,0)
109 { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice },
114 static const GstVaapiProfileMap *
115 get_profiles_map(GstVaapiProfile profile)
117 const GstVaapiProfileMap *m;
119 for (m = gst_vaapi_profiles; m->profile; m++)
120 if (m->profile == profile)
125 static const GstVaapiEntrypointMap *
126 get_entrypoints_map(GstVaapiEntrypoint entrypoint)
128 const GstVaapiEntrypointMap *m;
130 for (m = gst_vaapi_entrypoints; m->entrypoint; m++)
131 if (m->entrypoint == entrypoint)
138 * @profile: a #VAProfile
140 * Converts a VA profile into the corresponding #GstVaapiProfile. If
141 * the profile cannot be represented by #GstVaapiProfile, then zero is
144 * Return value: the #GstVaapiProfile describing the @profile
147 gst_vaapi_profile(VAProfile profile)
149 const GstVaapiProfileMap *m;
151 for (m = gst_vaapi_profiles; m->profile; m++)
152 if (m->va_profile == profile)
158 * gst_vaapi_profile_from_codec_data:
159 * @codec: a #GstVaapiCodec
160 * @buffer: a #GstBuffer holding code data
162 * Tries to parse VA profile from @buffer data and @codec information.
164 * Return value: the #GstVaapiProfile described in @buffer
166 static GstVaapiProfile
167 gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer)
169 /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */
170 guchar * const buf = GST_BUFFER_DATA(buffer);
172 if (buf[0] != 1) /* configurationVersion = 1 */
175 switch (buf[1]) { /* AVCProfileIndication */
176 case 66: return GST_VAAPI_PROFILE_H264_BASELINE;
177 case 77: return GST_VAAPI_PROFILE_H264_MAIN;
178 case 100: return GST_VAAPI_PROFILE_H264_HIGH;
183 static GstVaapiProfile
184 gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer)
186 GstVaapiProfile profile;
188 if (!codec || !buffer)
192 case GST_VAAPI_CODEC_H264:
193 profile = gst_vaapi_profile_from_codec_data_h264(buffer);
203 * gst_vaapi_profile_from_caps:
206 * Converts @caps into the corresponding #GstVaapiProfile. If the
207 * profile cannot be represented by #GstVaapiProfile, then zero is
210 * Return value: the #GstVaapiProfile describing the @caps
213 gst_vaapi_profile_from_caps(GstCaps *caps)
215 const GstVaapiProfileMap *m;
217 GstStructure *structure;
218 const gchar *profile_str;
219 GstVaapiProfile profile, best_profile;
220 GstBuffer *codec_data = NULL;
227 structure = gst_caps_get_structure(caps, 0);
231 name = gst_structure_get_name(structure);
232 namelen = strlen(name);
234 profile_str = gst_structure_get_string(structure, "profile");
236 const GValue *v_codec_data;
237 v_codec_data = gst_structure_get_value(structure, "codec_data");
239 codec_data = gst_value_get_buffer(v_codec_data);
244 for (m = gst_vaapi_profiles; !profile && m->profile; m++) {
245 if (strncmp(name, m->caps_str, namelen) != 0)
247 caps_test = gst_caps_from_string(m->caps_str);;
248 if (gst_caps_is_always_compatible(caps, caps_test)) {
249 best_profile = m->profile;
250 if (profile_str && m->profile_str &&
251 strcmp(profile_str, m->profile_str) == 0)
252 profile = best_profile;
255 profile = gst_vaapi_profile_from_codec_data(
256 gst_vaapi_profile_get_codec(m->profile),
260 WORKAROUND_QTDEMUX_NO_H263_PROFILES &&
261 strncmp(name, "video/x-h263", namelen) == 0) {
262 /* HACK: qtdemux does not report profiles for h263 */
263 profile = m->profile;
266 gst_caps_unref(caps_test);
268 return profile ? profile : best_profile;
272 * gst_vaapi_profile_get_va_profile:
273 * @profile: a #GstVaapiProfile
275 * Converts a #GstVaapiProfile into the corresponding VA profile. If
276 * no matching VA profile was found, -1 is returned and this error
277 * must be reported to be fixed.
279 * Return value: the VA profile, or -1 if none was found
282 gst_vaapi_profile_get_va_profile(GstVaapiProfile profile)
284 const GstVaapiProfileMap * const m = get_profiles_map(profile);
286 return m ? m->va_profile : (VAProfile)-1;
290 * gst_vaapi_profile_get_caps:
291 * @profile: a #GstVaapiProfile
293 * Converts a #GstVaapiProfile into the corresponding #GstCaps. If no
294 * matching caps were found, %NULL is returned.
296 * Return value: the newly allocated #GstCaps, or %NULL if none was found
299 gst_vaapi_profile_get_caps(GstVaapiProfile profile)
301 const GstVaapiProfileMap *m;
302 GstCaps *out_caps, *caps;
304 out_caps = gst_caps_new_empty();
308 for (m = gst_vaapi_profiles; m->profile; m++) {
309 if (m->profile != profile)
311 caps = gst_caps_from_string(m->caps_str);
316 "profile", G_TYPE_STRING, m->profile_str,
319 gst_caps_merge(out_caps, caps);
325 * gst_vaapi_profile_get_codec:
326 * @profile: a #GstVaapiProfile
328 * Extracts the #GstVaapiCodec from @profile.
330 * Return value: the #GstVaapiCodec from @profile
333 gst_vaapi_profile_get_codec(GstVaapiProfile profile)
338 case GST_VAAPI_PROFILE_VC1_SIMPLE:
339 case GST_VAAPI_PROFILE_VC1_MAIN:
340 codec = GST_VAAPI_CODEC_WMV3;
342 case GST_VAAPI_PROFILE_VC1_ADVANCED:
343 codec = GST_VAAPI_CODEC_VC1;
345 case GST_VAAPI_PROFILE_JPEG_BASELINE:
346 codec = GST_VAAPI_CODEC_JPEG;
349 codec = (guint32)profile & GST_MAKE_FOURCC(0xff,0xff,0xff,0);
356 * gst_vaapi_entrypoint:
357 * @entrypoint: a #VAEntrypoint
359 * Converts a VA entry-point into the corresponding #GstVaapiEntrypoint.
360 * If the entry-point cannot be represented by #GstVaapiEntrypoint,
361 * then zero is returned.
363 * Return value: the #GstVaapiEntrypoint describing the @entrypoint
366 gst_vaapi_entrypoint(VAEntrypoint entrypoint)
368 const GstVaapiEntrypointMap *m;
370 for (m = gst_vaapi_entrypoints; m->entrypoint; m++)
371 if (m->va_entrypoint == entrypoint)
372 return m->entrypoint;
377 * gst_vaapi_entrypoint_get_va_entrypoint:
378 * @entrypoint: a #GstVaapiEntrypoint
380 * Converts a #GstVaapiEntrypoint into the corresponding VA
381 * entry-point. If no matching VA entry-point was found, -1 is
382 * returned and this error must be reported to be fixed.
384 * Return value: the VA entry-point, or -1 if none was found
387 gst_vaapi_entrypoint_get_va_entrypoint(GstVaapiEntrypoint entrypoint)
389 const GstVaapiEntrypointMap * const m = get_entrypoints_map(entrypoint);
391 return m ? m->va_entrypoint : (VAEntrypoint)-1;