packaging: add packaging folder and update submodule pkgs
[platform/upstream/gstreamer-vaapi.git] / tests / codec.c
1 /*
2  *  codec.c - Codec utilities for the tests
3  *
4  *  Copyright (C) 2013 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 "gst/vaapi/sysdeps.h"
24 #include <gst/vaapi/gstvaapidisplay.h>
25 #include "codec.h"
26
27 typedef struct {
28     const gchar *codec_str;
29     GstVaapiCodec codec;
30     const gchar *caps_str;
31 } CodecMap;
32
33 static const CodecMap g_codec_map[] = {
34     { "h264",   GST_VAAPI_CODEC_H264,
35       "video/x-h264" },
36     { "jpeg",   GST_VAAPI_CODEC_JPEG,
37       "image/jpeg" },
38     { "mpeg2",  GST_VAAPI_CODEC_MPEG2,
39       "video/mpeg, mpegversion=2" },
40     { "mpeg4",  GST_VAAPI_CODEC_MPEG4,
41       "video/mpeg, mpegversion=4" },
42     { "wmv3",   GST_VAAPI_CODEC_VC1,
43       "video/x-wmv, wmvversion=3" },
44     { "vc1",    GST_VAAPI_CODEC_VC1,
45       "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1) },
46     { NULL, }
47 };
48
49 static const CodecMap *
50 get_codec_map(GstVaapiCodec codec)
51 {
52     const CodecMap *m;
53
54     if (codec) {
55         for (m = g_codec_map; m->codec_str != NULL; m++) {
56             if (m->codec == codec)
57                 return m;
58         }
59     }
60     return NULL;
61 }
62
63 const gchar *
64 string_from_codec(GstVaapiCodec codec)
65 {
66     const CodecMap * const m = get_codec_map(codec);
67
68     return m ? m->codec_str : NULL;
69 }
70
71 GstCaps *
72 caps_from_codec(GstVaapiCodec codec)
73 {
74     const CodecMap * const m = get_codec_map(codec);
75
76     return m ? gst_caps_from_string(m->caps_str) : NULL;
77 }
78
79 GstVaapiCodec
80 identify_codec_from_string(const gchar *codec_str)
81 {
82     const CodecMap *m;
83
84     if (codec_str) {
85         for (m = g_codec_map; m->codec_str != NULL; m++) {
86             if (g_ascii_strcasecmp(m->codec_str, codec_str) == 0)
87                 return m->codec;
88         }
89     }
90     return 0;
91 }
92
93 typedef struct {
94     GMappedFile *file;
95     guint8      *data;
96     guint        size;
97     guint        probability;
98     GstCaps     *caps;
99     GstTypeFind  type_find;
100 } CodecIdentifier;
101
102 static const guint8 *
103 codec_identifier_peek(gpointer data, gint64 offset, guint size)
104 {
105     CodecIdentifier * const cip = data;
106
107     if (offset >= 0 && offset + size <= cip->size)
108         return cip->data + offset;
109     if (offset < 0 && ((gint)cip->size + offset) >= 0)
110         return &cip->data[cip->size + offset];
111     return NULL;
112 }
113
114 static void
115 codec_identifier_suggest(gpointer data, guint probability, GstCaps *caps)
116 {
117     CodecIdentifier * const cip = data;
118
119     if (cip->probability < probability) {
120         cip->probability = probability;
121         gst_caps_replace(&cip->caps, caps);
122     }
123 }
124
125 static void
126 codec_identifier_free(CodecIdentifier *cip)
127 {
128     if (!cip)
129         return;
130
131     if (cip->file) {
132         g_mapped_file_unref(cip->file);
133         cip->file = NULL;
134     }
135     gst_caps_replace(&cip->caps, NULL);
136     g_slice_free(CodecIdentifier, cip);
137 }
138
139 static CodecIdentifier *
140 codec_identifier_new(const gchar *filename)
141 {
142     CodecIdentifier *cip;
143     GstTypeFind *tfp;
144
145     cip = g_slice_new0(CodecIdentifier);
146     if (!cip)
147         return NULL;
148
149     cip->file = g_mapped_file_new(filename, FALSE, NULL);
150     if (!cip->file)
151         goto error;
152
153     cip->size = g_mapped_file_get_length(cip->file);
154     cip->data = (guint8 *)g_mapped_file_get_contents(cip->file);
155     if (!cip->data)
156         goto error;
157
158     tfp = &cip->type_find;
159     tfp->peek = (GstTypeFindPeekFunction)codec_identifier_peek;
160     tfp->suggest = (GstTypeFindSuggestFunction)codec_identifier_suggest;
161     tfp->data = cip;
162     return cip;
163
164 error:
165     codec_identifier_free(cip);
166     return NULL;
167 }
168
169 GstVaapiCodec
170 identify_codec(const gchar *filename)
171 {
172     CodecIdentifier *cip;
173     GList *type_list, *l;
174     guint32 codec = 0;
175
176     cip = codec_identifier_new(filename);
177     if (!cip)
178         return 0;
179
180     type_list = gst_type_find_factory_get_list();
181     for (l = type_list; l != NULL; l = l->next) {
182         GstTypeFindFactory * const factory = GST_TYPE_FIND_FACTORY(l->data);
183         gst_type_find_factory_call_function(factory, &cip->type_find);
184     }
185     g_list_free(type_list);
186
187     if (cip->probability >= GST_TYPE_FIND_LIKELY)
188         codec = gst_vaapi_profile_get_codec(
189             gst_vaapi_profile_from_caps(cip->caps));
190
191     codec_identifier_free(cip);
192     return codec;
193 }