/* * codec.c - Codec utilities for the tests * * Copyright (C) 2013 Intel Corporation * * 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, " GST_MAKE_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 = (GstTypeFindPeekFunction)codec_identifier_peek; tfp->suggest = (GstTypeFindSuggestFunction)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; }