/* * codec.c - Codec utilities for the tests * * Copyright (C) 2013 Intel Corporation * Author: Gwenole Beauchesne * * 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 #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; }