Add VA entrypoint abstraction.
[vaapi:gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapiprofile.c
1 /*
2  *  gstvaapiprofile.c - VA profile abstraction
3  *
4  *  gstreamer-vaapi (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19  */
20
21 /**
22  * SECTION:gstvaapiprofile
23  * @short_description: VA profile abstraction
24  */
25
26 #include "config.h"
27 #include <string.h>
28 #include "gstvaapicompat.h"
29 #include "gstvaapiprofile.h"
30
31 typedef struct _GstVaapiProfileMap              GstVaapiProfileMap;
32 typedef struct _GstVaapiEntrypointMap           GstVaapiEntrypointMap;
33
34 struct _GstVaapiProfileMap {
35     GstVaapiProfile             profile;
36     VAProfile                   va_profile;
37     const char                 *caps_str;
38 };
39
40 struct _GstVaapiEntrypointMap {
41     GstVaapiEntrypoint          entrypoint;
42     VAEntrypoint                va_entrypoint;
43 };
44
45 /* Profiles */
46 static const GstVaapiProfileMap gst_vaapi_profiles[] = {
47     { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple,
48       "video/mpeg, mpegversion=2, profile=simple"
49     },
50     { GST_VAAPI_PROFILE_MPEG2_MAIN, VAProfileMPEG2Main,
51       "video/mpeg, mpegversion=2, profile=main"
52     },
53     { GST_VAAPI_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple,
54       "video/mpeg, mpegversion=4, profile=simple"
55     },
56     { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple,
57       "video/mpeg, mpegversion=4, profile=advanced-simple"
58     },
59     { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main,
60       "video/mpeg, mpegversion=4, profile=main"
61     },
62 #if VA_CHECK_VERSION(0,30,0)
63     { GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline,
64       "video/x-h263, variant=itu, h263version=h263, profile=baseline"
65     },
66 #endif
67     { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline,
68       "video/x-h264, variant=itu, profile=baseline"
69     },
70     { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main,
71       "video/x-h264, variant=itu, profile=main"
72     },
73     { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High,
74       "video/x-h264, variant=itu, profile=high"
75     },
76     { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple,
77       "video/x-vc1, profile=simple"
78     },
79     { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main,
80       "video/x-vc1, profile=main"
81     },
82     { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced,
83       "video/x-vc1, profile=advanced"
84     },
85     { 0, }
86 };
87
88 /* Entry-points */
89 static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = {
90     { GST_VAAPI_ENTRYPOINT_VLD,         VAEntrypointVLD         },
91     { GST_VAAPI_ENTRYPOINT_IDCT,        VAEntrypointIDCT        },
92     { GST_VAAPI_ENTRYPOINT_MOCO,        VAEntrypointMoComp      },
93     { 0, }
94 };
95
96 static const GstVaapiProfileMap *
97 get_profiles_map(GstVaapiProfile profile)
98 {
99     const GstVaapiProfileMap *m;
100
101     for (m = gst_vaapi_profiles; m->profile; m++)
102         if (m->profile == profile)
103             return m;
104     return NULL;
105 }
106
107 static const GstVaapiEntrypointMap *
108 get_entrypoints_map(GstVaapiEntrypoint entrypoint)
109 {
110     const GstVaapiEntrypointMap *m;
111
112     for (m = gst_vaapi_entrypoints; m->entrypoint; m++)
113         if (m->entrypoint == entrypoint)
114             return m;
115     return NULL;
116 }
117
118 /**
119  * gst_vaapi_profile:
120  * @profile: a #VAProfile
121  *
122  * Converts a VA profile into the corresponding #GstVaapiProfile. If
123  * the profile cannot be represented by #GstVaapiProfile, then zero is
124  * returned.
125  *
126  * Return value: the #GstVaapiProfile describing the @profile
127  */
128 GstVaapiProfile
129 gst_vaapi_profile(VAProfile profile)
130 {
131     const GstVaapiProfileMap *m;
132
133     for (m = gst_vaapi_profiles; m->profile; m++)
134         if (m->va_profile == profile)
135             return m->profile;
136     return 0;
137 }
138
139 /**
140  * gst_vaapi_profile_from_caps:
141  * @caps: a #GstCaps
142  *
143  * Converts @caps into the corresponding #GstVaapiProfile. If the
144  * profile cannot be represented by #GstVaapiProfile, then zero is
145  * returned.
146  *
147  * Return value: the #GstVaapiProfile describing the @caps
148  */
149 GstVaapiProfile
150 gst_vaapi_profile_from_caps(GstCaps *caps)
151 {
152     const GstVaapiProfileMap *m;
153     GstCaps *caps_test;
154     GstStructure *structure;
155     const gchar *name;
156     gsize namelen;
157     gboolean found;
158
159     if (!caps)
160         return 0;
161
162     structure = gst_caps_get_structure(caps, 0);
163     if (!structure)
164         return 0;
165
166     name    = gst_structure_get_name(structure);
167     namelen = strlen(name);
168
169     found = FALSE;
170     for (m = gst_vaapi_profiles; !found && m->profile; m++) {
171         if (strncmp(name, m->caps_str, namelen) != 0)
172             continue;
173         caps_test = gst_caps_from_string(m->caps_str);
174         found = gst_caps_is_always_compatible(caps_test, caps);
175         gst_caps_unref(caps_test);
176     }
177     return found ? m->va_profile : 0;
178 }
179
180 /**
181  * gst_vaapi_profile_get_va_profile:
182  * @profile: a #GstVaapiProfile
183  *
184  * Converts a #GstVaapiProfile into the corresponding VA profile. If
185  * no matching VA profile was found, -1 is returned and this error
186  * must be reported to be fixed.
187  *
188  * Return value: the VA profile, or -1 if none was found
189  */
190 VAProfile
191 gst_vaapi_profile_get_va_profile(GstVaapiProfile profile)
192 {
193     const GstVaapiProfileMap * const m = get_profiles_map(profile);
194
195     return m ? m->va_profile : (VAProfile)-1;
196 }
197
198 /**
199  * gst_vaapi_profile_get_caps:
200  * @profile: a #GstVaapiProfile
201  *
202  * Converts a #GstVaapiProfile into the corresponding #GstCaps. If no
203  * matching caps were found, %NULL is returned.
204  *
205  * Return value: the newly allocated #GstCaps, or %NULL if none was found
206  */
207 GstCaps *
208 gst_vaapi_profile_get_caps(GstVaapiProfile profile)
209 {
210     const GstVaapiProfileMap * const m = get_profiles_map(profile);
211
212     return m ? gst_caps_from_string(m->caps_str) : NULL;
213 }
214
215 /**
216  * gst_vaapi_profile_get_codec:
217  * @profile: a #GstVaapiProfile
218  *
219  * Extracts the #GstVaapiCodec from @profile.
220  *
221  * Return value: the #GstVaapiCodec from @profile
222  */
223 GstVaapiCodec
224 gst_vaapi_profile_get_codec(GstVaapiProfile profile)
225 {
226     return (GstVaapiCodec)(((guint32)profile) & 0xffffff00);
227 }
228
229 /**
230  * gst_vaapi_entrypoint:
231  * @entryprofile: a #VAEntrypoint
232  *
233  * Converts a VA entry-point into the corresponding #GstVaapiEntrypoint.
234  * If the entry-point cannot be represented by #GstVaapiEntrypoint,
235  * then zero is returned.
236  *
237  * Return value: the #GstVaapiEntrypoint describing the @entrypoint
238  */
239 GstVaapiEntrypoint
240 gst_vaapi_entrypoint(VAEntrypoint entrypoint)
241 {
242     const GstVaapiEntrypointMap *m;
243
244     for (m = gst_vaapi_entrypoints; m->entrypoint; m++)
245         if (m->va_entrypoint == entrypoint)
246             return m->entrypoint;
247     return 0;
248 }
249
250 /**
251  * gst_vaapi_entrypoint_get_va_entrypoint:
252  * @entrypoint: a #GstVaapiEntrypoint
253  *
254  * Converts a #GstVaapiEntrypoint into the corresponding VA
255  * entry-point. If no matching VA entry-point was found, -1 is
256  * returned and this error must be reported to be fixed.
257  *
258  * Return value: the VA entry-point, or -1 if none was found
259  */
260 VAEntrypoint
261 gst_vaapi_entrypoint_get_va_entrypoint(GstVaapiEntrypoint entrypoint)
262 {
263     const GstVaapiEntrypointMap * const m = get_entrypoints_map(entrypoint);
264
265     return m ? m->va_entrypoint : (VAEntrypoint)-1;
266 }