/* * Copyright (C) 2012,2018 Collabora Ltd. * Author: Sebastian Dröge * Copyright (C) 2015, Sebastian Dröge * Copyright (C) 2023, Ratchanan Srirattanamet * * 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 * version 2.1 of the License. * * 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 * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "../gstamc-format.h" #include "gstamc-ndk.h" #include "gstamc-internal-ndk.h" #include #include #include static struct { void *mediandk_handle; AMediaFormat *(*new) (); media_status_t (*delete) (AMediaFormat *); const char *(*to_string) (AMediaFormat *); bool (*get_int32) (AMediaFormat *, const char *name, int32_t * out); bool (*get_float) (AMediaFormat *, const char *name, float *out); bool (*get_buffer) (AMediaFormat *, const char *name, void **data, size_t *size); bool (*get_string) (AMediaFormat *, const char *name, const char **out); void (*set_int32) (AMediaFormat *, const char *name, int32_t value); void (*set_float) (AMediaFormat *, const char *name, float value); void (*set_string) (AMediaFormat *, const char *name, const char *value); void (*set_buffer) (AMediaFormat *, const char *name, const void *data, size_t size); } a_media_format; gboolean gst_amc_format_ndk_static_init (void) { a_media_format.mediandk_handle = dlopen ("libmediandk.so", RTLD_NOW); if (!a_media_format.mediandk_handle) return FALSE; a_media_format.new = dlsym (a_media_format.mediandk_handle, "AMediaFormat_new"); a_media_format.delete = dlsym (a_media_format.mediandk_handle, "AMediaFormat_delete"); a_media_format.to_string = dlsym (a_media_format.mediandk_handle, "AMediaFormat_toString"); a_media_format.get_int32 = dlsym (a_media_format.mediandk_handle, "AMediaFormat_getInt32"); a_media_format.get_float = dlsym (a_media_format.mediandk_handle, "AMediaFormat_getFloat"); a_media_format.get_buffer = dlsym (a_media_format.mediandk_handle, "AMediaFormat_getBuffer"); a_media_format.get_string = dlsym (a_media_format.mediandk_handle, "AMediaFormat_getString"); a_media_format.set_int32 = dlsym (a_media_format.mediandk_handle, "AMediaFormat_setInt32"); a_media_format.set_float = dlsym (a_media_format.mediandk_handle, "AMediaFormat_setFloat"); a_media_format.set_string = dlsym (a_media_format.mediandk_handle, "AMediaFormat_setString"); a_media_format.set_buffer = dlsym (a_media_format.mediandk_handle, "AMediaFormat_setBuffer"); if (!a_media_format.new || !a_media_format.delete || !a_media_format.to_string || !a_media_format.get_int32 || !a_media_format.get_float || !a_media_format.get_buffer || !a_media_format.get_string || !a_media_format.set_int32 || !a_media_format.set_float || !a_media_format.set_string || !a_media_format.set_buffer) { GST_WARNING ("Failed to get AMediaFormat functions"); dlclose (a_media_format.mediandk_handle); a_media_format.mediandk_handle = NULL; return FALSE; } return TRUE; } GstAmcFormat * gst_amc_format_ndk_new (GError ** err) { GstAmcFormat *ret = g_new0 (GstAmcFormat, 1); ret->ndk_media_format = a_media_format.new (); if (!ret->ndk_media_format) { g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "Failed to allocate AMediaFormat"); g_free (ret); return NULL; } return ret; } #define MEDIAFORMAT_KEY_MIME "mime" #define MEDIAFORMAT_SAMPLE_RATE "sample-rate" #define MEDIAFORMAT_CHANNEL_COUNT "channel-count" static GstAmcFormat * gst_amc_format_ndk_new_audio (const gchar * mime, gint sample_rate, gint channels, GError ** err) { GstAmcFormat *ret = gst_amc_format_ndk_new (err); if (!ret) return ret; a_media_format.set_string (ret->ndk_media_format, MEDIAFORMAT_KEY_MIME, mime); a_media_format.set_int32 (ret->ndk_media_format, MEDIAFORMAT_SAMPLE_RATE, sample_rate); a_media_format.set_int32 (ret->ndk_media_format, MEDIAFORMAT_CHANNEL_COUNT, channels); return ret; } #define MEDIAFORMAT_KEY_WIDTH "width" #define MEDIAFORMAT_KEY_HEIGHT "height" static GstAmcFormat * gst_amc_format_ndk_new_video (const gchar * mime, gint width, gint height, GError ** err) { GstAmcFormat *ret = gst_amc_format_ndk_new (err); if (!ret) return ret; a_media_format.set_string (ret->ndk_media_format, MEDIAFORMAT_KEY_MIME, mime); a_media_format.set_int32 (ret->ndk_media_format, MEDIAFORMAT_KEY_WIDTH, width); a_media_format.set_int32 (ret->ndk_media_format, MEDIAFORMAT_KEY_HEIGHT, height); return ret; } GstAmcFormat * gst_amc_format_ndk_from_a_media_format (AMediaFormat * ndk_media_format) { GstAmcFormat *ret = g_new0 (GstAmcFormat, 1); ret->ndk_media_format = ndk_media_format; return ret; } static void gst_amc_format_ndk_free (GstAmcFormat * format) { a_media_format.delete (format->ndk_media_format); g_free (format); } static gchar * gst_amc_format_ndk_to_string (GstAmcFormat * format, GError ** err) { const char *str = a_media_format.to_string (format->ndk_media_format); if (!str) { g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "Failed to call AMediaFormat_toString()"); return NULL; } return g_strdup (str); } static gboolean gst_amc_format_ndk_get_float (GstAmcFormat * format, const gchar * key, gfloat * value, GError ** err) { float val; if (!a_media_format.get_float (format->ndk_media_format, key, &val)) { g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "Failed to call AMediaFormat_getFloat()"); return FALSE; } *value = val; return TRUE; } static gboolean gst_amc_format_ndk_set_float (GstAmcFormat * format, const gchar * key, gfloat value, GError ** err) { a_media_format.set_float (format->ndk_media_format, key, value); return TRUE; } static gboolean gst_amc_format_ndk_get_int (GstAmcFormat * format, const gchar * key, gint * value, GError ** err) { int32_t val; if (!a_media_format.get_int32 (format->ndk_media_format, key, &val)) { g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "Failed to call AMediaFormat_getInt32()"); return FALSE; } *value = val; return TRUE; } static gboolean gst_amc_format_ndk_set_int (GstAmcFormat * format, const gchar * key, gint value, GError ** err) { a_media_format.set_int32 (format->ndk_media_format, key, value); return TRUE; } static gboolean gst_amc_format_ndk_get_string (GstAmcFormat * format, const gchar * key, gchar ** value, GError ** err) { const char *val; if (!a_media_format.get_string (format->ndk_media_format, key, &val)) { g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "Failed to call AMediaFormat_getString()"); return FALSE; } *value = g_strdup (val); return TRUE; } static gboolean gst_amc_format_ndk_set_string (GstAmcFormat * format, const gchar * key, const gchar * value, GError ** err) { a_media_format.set_string (format->ndk_media_format, key, value); return TRUE; } static gboolean gst_amc_format_ndk_get_buffer (GstAmcFormat * format, const gchar * key, guint8 ** out_data, gsize * out_size, GError ** err) { void *data; size_t size; if (!a_media_format.get_buffer (format->ndk_media_format, key, &data, &size)) { g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "Failed to call AMediaFormat_getBuffer()"); return FALSE; } *out_size = size; *out_data = g_memdup2 (data, size); return TRUE; } static gboolean gst_amc_format_ndk_set_buffer (GstAmcFormat * format, const gchar * key, guint8 * data, gsize size, GError ** err) { a_media_format.set_buffer (format->ndk_media_format, key, data, size); return TRUE; } GstAmcFormatVTable gst_amc_format_ndk_vtable = { .new_audio = gst_amc_format_ndk_new_audio, .new_video = gst_amc_format_ndk_new_video, .free = gst_amc_format_ndk_free, .to_string = gst_amc_format_ndk_to_string, .get_float = gst_amc_format_ndk_get_float, .set_float = gst_amc_format_ndk_set_float, .get_int = gst_amc_format_ndk_get_int, .set_int = gst_amc_format_ndk_set_int, .get_string = gst_amc_format_ndk_get_string, .set_string = gst_amc_format_ndk_set_string, .get_buffer = gst_amc_format_ndk_get_buffer, .set_buffer = gst_amc_format_ndk_set_buffer, };