04993c8a4ea9d7b692ee2891bb690554c83966a6
[platform/upstream/gstreamer.git] / subprojects / gstreamer-vaapi / gst-libs / gst / vaapi / gstvaapiutils_mpeg2.c
1 /*
2  *  gstvaapiutils_mpeg2.c - MPEG-2 related utilities
3  *
4  *  Copyright (C) 2011-2014 Intel Corporation
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 #include "sysdeps.h"
24 #include <gst/codecparsers/gstmpegvideoparser.h>
25 #include "gstvaapicompat.h"
26 #include "gstvaapiutils_mpeg2_priv.h"
27
28 #define DEBUG 1
29 #include "gstvaapidebug.h"
30
31 struct map
32 {
33   guint value;
34   const gchar *name;
35 };
36
37 /* Profile string map */
38 static const struct map gst_vaapi_mpeg2_profile_map[] = {
39 /* *INDENT-OFF* */
40   { GST_VAAPI_PROFILE_MPEG2_SIMPLE,     "simple"        },
41   { GST_VAAPI_PROFILE_MPEG2_MAIN,       "main"          },
42   { GST_VAAPI_PROFILE_MPEG2_HIGH,       "high"          },
43   { 0, NULL }
44 /* *INDENT-ON* */
45 };
46
47 /* Level string map */
48 static const struct map gst_vaapi_mpeg2_level_map[] = {
49 /* *INDENT-OFF* */
50   { GST_VAAPI_LEVEL_MPEG2_LOW,          "low"           },
51   { GST_VAAPI_LEVEL_MPEG2_MAIN,         "main"          },
52   { GST_VAAPI_LEVEL_MPEG2_HIGH_1440,    "high-1440"     },
53   { GST_VAAPI_LEVEL_MPEG2_HIGH,         "high"          },
54   { GST_VAAPI_LEVEL_MPEG2_HIGHP,        "highP"         },
55   { 0, NULL }
56 /* *INDENT-ON* */
57 };
58
59 /* Table 8-10 to 8-13 (up to Main profile only) */
60 /* *INDENT-OFF* */
61 static const GstVaapiMPEG2LevelLimits gst_vaapi_mpeg2_level_limits[] = {
62   /* level      h_size  v_size  fps  samples     kbps  vbv_size */
63   { GST_VAAPI_LEVEL_MPEG2_LOW,
64     0x0a,        352,   288,   30,   3041280,   4000,   475136 },
65   { GST_VAAPI_LEVEL_MPEG2_MAIN,
66     0x08,        720,   576,   30,   1036800,  15000,  1835008 },
67   { GST_VAAPI_LEVEL_MPEG2_HIGH_1440,
68     0x06,       1440,  1152,   60,  47001600,  60000,  7340032 },
69   { GST_VAAPI_LEVEL_MPEG2_HIGH,
70     0x04,       1920,  1152,   60,  62668800,  80000,  9781248 },
71   /* Amendment 3: New level for 1080@50p/60p */
72   { GST_VAAPI_LEVEL_MPEG2_HIGHP,
73     0x02,       1920,  1152,   60, 125337600,  80000,  9781248 },
74   { 0, }
75 };
76 /* *INDENT-ON* */
77
78 /* Lookup value in map */
79 static const struct map *
80 map_lookup_value (const struct map *m, guint value)
81 {
82   g_return_val_if_fail (m != NULL, NULL);
83
84   for (; m->name != NULL; m++) {
85     if (m->value == value)
86       return m;
87   }
88   return NULL;
89 }
90
91 /* Lookup name in map */
92 static const struct map *
93 map_lookup_name (const struct map *m, const gchar * name)
94 {
95   g_return_val_if_fail (m != NULL, NULL);
96
97   if (!name)
98     return NULL;
99
100   for (; m->name != NULL; m++) {
101     if (strcmp (m->name, name) == 0)
102       return m;
103   }
104   return NULL;
105 }
106
107 /** Returns a relative score for the supplied GstVaapiProfile */
108 guint
109 gst_vaapi_utils_mpeg2_get_profile_score (GstVaapiProfile profile)
110 {
111   const struct map *const m =
112       map_lookup_value (gst_vaapi_mpeg2_profile_map, profile);
113
114   return m ? 1 + (m - gst_vaapi_mpeg2_profile_map) : 0;
115 }
116
117 /** Returns GstVaapiProfile from MPEG-2 profile_idc value */
118 GstVaapiProfile
119 gst_vaapi_utils_mpeg2_get_profile (guint8 profile_idc)
120 {
121   GstVaapiProfile profile;
122
123   switch (profile_idc) {
124     case GST_MPEG_VIDEO_PROFILE_SIMPLE:
125       profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE;
126       break;
127     case GST_MPEG_VIDEO_PROFILE_MAIN:
128       profile = GST_VAAPI_PROFILE_MPEG2_MAIN;
129       break;
130     case GST_MPEG_VIDEO_PROFILE_HIGH:
131       profile = GST_VAAPI_PROFILE_MPEG2_HIGH;
132       break;
133     default:
134       GST_DEBUG ("unsupported profile_idc value");
135       profile = GST_VAAPI_PROFILE_UNKNOWN;
136       break;
137   }
138   return profile;
139 }
140
141 /** Returns MPEG-2 profile_idc value from GstVaapiProfile */
142 guint8
143 gst_vaapi_utils_mpeg2_get_profile_idc (GstVaapiProfile profile)
144 {
145   guint8 profile_idc;
146
147   switch (profile) {
148     case GST_VAAPI_PROFILE_MPEG2_SIMPLE:
149       profile_idc = GST_MPEG_VIDEO_PROFILE_SIMPLE;
150       break;
151     case GST_VAAPI_PROFILE_MPEG2_MAIN:
152       profile_idc = GST_MPEG_VIDEO_PROFILE_MAIN;
153       break;
154     case GST_VAAPI_PROFILE_MPEG2_HIGH:
155       profile_idc = GST_MPEG_VIDEO_PROFILE_HIGH;
156       break;
157     default:
158       GST_DEBUG ("unsupported GstVaapiProfile value");
159       profile_idc = 0;
160       break;
161   }
162   return profile_idc;
163 }
164
165 /** Returns GstVaapiProfile from a string representation */
166 GstVaapiProfile
167 gst_vaapi_utils_mpeg2_get_profile_from_string (const gchar * str)
168 {
169   const struct map *const m =
170       map_lookup_name (gst_vaapi_mpeg2_profile_map, str);
171
172   return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN;
173 }
174
175 /** Returns a string representation for the supplied MPEG-2 profile */
176 const gchar *
177 gst_vaapi_utils_mpeg2_get_profile_string (GstVaapiProfile profile)
178 {
179   const struct map *const m =
180       map_lookup_value (gst_vaapi_mpeg2_profile_map, profile);
181
182   return m ? m->name : NULL;
183 }
184
185 /** Returns GstVaapiLevelMPEG2 from MPEG-2 level_idc value */
186 GstVaapiLevelMPEG2
187 gst_vaapi_utils_mpeg2_get_level (guint8 level_idc)
188 {
189   const GstVaapiMPEG2LevelLimits *llp;
190
191   for (llp = gst_vaapi_mpeg2_level_limits; llp->level != 0; llp++) {
192     if (llp->level_idc == level_idc)
193       return llp->level;
194   }
195   GST_DEBUG ("unsupported level_idc value");
196   return (GstVaapiLevelMPEG2) 0;
197 }
198
199 /** Returns MPEG-2 level_idc value from GstVaapiLevelMPEG2 */
200 guint8
201 gst_vaapi_utils_mpeg2_get_level_idc (GstVaapiLevelMPEG2 level)
202 {
203   const GstVaapiMPEG2LevelLimits *const llp =
204       gst_vaapi_utils_mpeg2_get_level_limits (level);
205
206   return llp ? llp->level_idc : 0;
207 }
208
209 /** Returns GstVaapiLevelMPEG2 from a string representation */
210 GstVaapiLevelMPEG2
211 gst_vaapi_utils_mpeg2_get_level_from_string (const gchar * str)
212 {
213   const struct map *const m = map_lookup_name (gst_vaapi_mpeg2_level_map, str);
214
215   return (GstVaapiLevelMPEG2) (m ? m->value : 0);
216 }
217
218 /** Returns a string representation for the supplied MPEG-2 level */
219 const gchar *
220 gst_vaapi_utils_mpeg2_get_level_string (GstVaapiLevelMPEG2 level)
221 {
222   if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGHP)
223     return NULL;
224   return gst_vaapi_mpeg2_level_map[level - GST_VAAPI_LEVEL_MPEG2_LOW].name;
225 }
226
227 /** Returns level limits as specified in Tables 8-10 to 8-13 of the
228     MPEG-2 standard */
229 const GstVaapiMPEG2LevelLimits *
230 gst_vaapi_utils_mpeg2_get_level_limits (GstVaapiLevelMPEG2 level)
231 {
232   if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGHP)
233     return NULL;
234   return &gst_vaapi_mpeg2_level_limits[level - GST_VAAPI_LEVEL_MPEG2_LOW];
235 }
236
237 /** Returns Tables 8-10 to 8-13 from the specification (up to High profile) */
238 const GstVaapiMPEG2LevelLimits *
239 gst_vaapi_utils_mpeg2_get_level_limits_table (guint * out_length_ptr)
240 {
241   if (out_length_ptr)
242     *out_length_ptr = G_N_ELEMENTS (gst_vaapi_mpeg2_level_limits) - 1;
243   return gst_vaapi_mpeg2_level_limits;
244 }
245
246 /** Returns GstVaapiChromaType from MPEG-2 chroma_format_idc value */
247 GstVaapiChromaType
248 gst_vaapi_utils_mpeg2_get_chroma_type (guint chroma_format_idc)
249 {
250   GstVaapiChromaType chroma_type;
251
252   switch (chroma_format_idc) {
253     case GST_MPEG_VIDEO_CHROMA_420:
254       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
255       break;
256     case GST_MPEG_VIDEO_CHROMA_422:
257       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
258       break;
259     case GST_MPEG_VIDEO_CHROMA_444:
260       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
261       break;
262     default:
263       GST_DEBUG ("unsupported chroma_format_idc value");
264       chroma_type = (GstVaapiChromaType) 0;
265       break;
266   }
267   return chroma_type;
268 }
269
270 /** Returns MPEG-2 chroma_format_idc value from GstVaapiChromaType */
271 guint
272 gst_vaapi_utils_mpeg2_get_chroma_format_idc (GstVaapiChromaType chroma_type)
273 {
274   guint chroma_format_idc;
275
276   switch (chroma_type) {
277     case GST_VAAPI_CHROMA_TYPE_YUV420:
278       chroma_format_idc = GST_MPEG_VIDEO_CHROMA_420;
279       break;
280     case GST_VAAPI_CHROMA_TYPE_YUV422:
281       chroma_format_idc = GST_MPEG_VIDEO_CHROMA_422;
282       break;
283     case GST_VAAPI_CHROMA_TYPE_YUV444:
284       chroma_format_idc = GST_MPEG_VIDEO_CHROMA_444;
285       break;
286     default:
287       GST_DEBUG ("unsupported GstVaapiChromaType value");
288       chroma_format_idc = 1;
289       break;
290   }
291   return chroma_format_idc;
292 }