diff options
Diffstat (limited to 'tests/internal/codec.c')
-rw-r--r-- | tests/internal/codec.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/tests/internal/codec.c b/tests/internal/codec.c new file mode 100644 index 00000000..d14981ac --- /dev/null +++ b/tests/internal/codec.c @@ -0,0 +1,195 @@ +/* + * codec.c - Codec utilities for the tests + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "gst/vaapi/sysdeps.h" +#include <gst/vaapi/gstvaapidisplay.h> +#include "codec.h" + +typedef struct +{ + const gchar *codec_str; + GstVaapiCodec codec; + const gchar *caps_str; +} CodecMap; + +static const CodecMap g_codec_map[] = { + {"h264", GST_VAAPI_CODEC_H264, + "video/x-h264"}, + {"jpeg", GST_VAAPI_CODEC_JPEG, + "image/jpeg"}, + {"mpeg2", GST_VAAPI_CODEC_MPEG2, + "video/mpeg, mpegversion=2"}, + {"mpeg4", GST_VAAPI_CODEC_MPEG4, + "video/mpeg, mpegversion=4"}, + {"wmv3", GST_VAAPI_CODEC_VC1, + "video/x-wmv, wmvversion=3"}, + {"vc1", GST_VAAPI_CODEC_VC1, + "video/x-wmv, wmvversion=3, format=(string)WVC1"}, + {NULL,} +}; + +static const CodecMap * +get_codec_map (GstVaapiCodec codec) +{ + const CodecMap *m; + + if (codec) { + for (m = g_codec_map; m->codec_str != NULL; m++) { + if (m->codec == codec) + return m; + } + } + return NULL; +} + +const gchar * +string_from_codec (GstVaapiCodec codec) +{ + const CodecMap *const m = get_codec_map (codec); + + return m ? m->codec_str : NULL; +} + +GstCaps * +caps_from_codec (GstVaapiCodec codec) +{ + const CodecMap *const m = get_codec_map (codec); + + return m ? gst_caps_from_string (m->caps_str) : NULL; +} + +GstVaapiCodec +identify_codec_from_string (const gchar * codec_str) +{ + const CodecMap *m; + + if (codec_str) { + for (m = g_codec_map; m->codec_str != NULL; m++) { + if (g_ascii_strcasecmp (m->codec_str, codec_str) == 0) + return m->codec; + } + } + return 0; +} + +typedef struct +{ + GMappedFile *file; + guint8 *data; + guint size; + guint probability; + GstCaps *caps; + GstTypeFind type_find; +} CodecIdentifier; + +static const guint8 * +codec_identifier_peek (gpointer data, gint64 offset, guint size) +{ + CodecIdentifier *const cip = data; + + if (offset >= 0 && offset + size <= cip->size) + return cip->data + offset; + if (offset < 0 && ((gint) cip->size + offset) >= 0) + return &cip->data[cip->size + offset]; + return NULL; +} + +static void +codec_identifier_suggest (gpointer data, guint probability, GstCaps * caps) +{ + CodecIdentifier *const cip = data; + + if (cip->probability < probability) { + cip->probability = probability; + gst_caps_replace (&cip->caps, caps); + } +} + +static void +codec_identifier_free (CodecIdentifier * cip) +{ + if (!cip) + return; + + if (cip->file) { + g_mapped_file_unref (cip->file); + cip->file = NULL; + } + gst_caps_replace (&cip->caps, NULL); + g_slice_free (CodecIdentifier, cip); +} + +static CodecIdentifier * +codec_identifier_new (const gchar * filename) +{ + CodecIdentifier *cip; + GstTypeFind *tfp; + + cip = g_slice_new0 (CodecIdentifier); + if (!cip) + return NULL; + + cip->file = g_mapped_file_new (filename, FALSE, NULL); + if (!cip->file) + goto error; + + cip->size = g_mapped_file_get_length (cip->file); + cip->data = (guint8 *) g_mapped_file_get_contents (cip->file); + if (!cip->data) + goto error; + + tfp = &cip->type_find; + tfp->peek = codec_identifier_peek; + tfp->suggest = codec_identifier_suggest; + tfp->data = cip; + return cip; + +error: + codec_identifier_free (cip); + return NULL; +} + +GstVaapiCodec +identify_codec (const gchar * filename) +{ + CodecIdentifier *cip; + GList *type_list, *l; + guint32 codec = 0; + + cip = codec_identifier_new (filename); + if (!cip) + return 0; + + type_list = gst_type_find_factory_get_list (); + for (l = type_list; l != NULL; l = l->next) { + GstTypeFindFactory *const factory = GST_TYPE_FIND_FACTORY (l->data); + gst_type_find_factory_call_function (factory, &cip->type_find); + } + g_list_free (type_list); + + if (cip->probability >= GST_TYPE_FIND_LIKELY) + codec = + gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (cip->caps)); + + codec_identifier_free (cip); + return codec; +} |