mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
Add video decoder element
This commit is contained in:
parent
c846605082
commit
1e73da2941
3 changed files with 1581 additions and 1 deletions
|
@ -25,6 +25,8 @@
|
||||||
#include "gstamc.h"
|
#include "gstamc.h"
|
||||||
#include "gstamc-constants.h"
|
#include "gstamc-constants.h"
|
||||||
|
|
||||||
|
#include "gstamcvideodec.h"
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -2208,6 +2210,158 @@ gst_amc_aac_profile_from_string (const gchar * profile)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
create_type_name (const gchar * parent_name, const gchar * codec_name)
|
||||||
|
{
|
||||||
|
gchar *typified_name;
|
||||||
|
gint i, k;
|
||||||
|
gint parent_name_len = strlen (parent_name);
|
||||||
|
gint codec_name_len = strlen (codec_name);
|
||||||
|
gboolean upper = TRUE;
|
||||||
|
|
||||||
|
typified_name = g_new0 (gchar, parent_name_len + 1 + strlen (codec_name) + 1);
|
||||||
|
memcpy (typified_name, parent_name, parent_name_len);
|
||||||
|
typified_name[parent_name_len] = '-';
|
||||||
|
|
||||||
|
for (i = 0, k = 0; i < codec_name_len; i++) {
|
||||||
|
if (g_ascii_isalnum (codec_name[i])) {
|
||||||
|
if (upper)
|
||||||
|
typified_name[parent_name_len + 1 + k++] =
|
||||||
|
g_ascii_toupper (codec_name[i]);
|
||||||
|
else
|
||||||
|
typified_name[parent_name_len + 1 + k++] =
|
||||||
|
g_ascii_tolower (codec_name[i]);
|
||||||
|
|
||||||
|
upper = FALSE;
|
||||||
|
} else {
|
||||||
|
/* Skip all non-alnum chars and start a new upper case word */
|
||||||
|
upper = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return typified_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
create_element_name (gboolean video, gboolean encoder, const gchar * codec_name)
|
||||||
|
{
|
||||||
|
#define PREFIX_LEN 10
|
||||||
|
static const gchar *prefixes[] = {
|
||||||
|
"amcviddec-",
|
||||||
|
"amcauddec-",
|
||||||
|
"amcvidenc-",
|
||||||
|
"amcaudenc-"
|
||||||
|
};
|
||||||
|
gchar *element_name;
|
||||||
|
gint i, k;
|
||||||
|
gint codec_name_len = strlen (codec_name);
|
||||||
|
const gchar *prefix;
|
||||||
|
|
||||||
|
if (video && !encoder)
|
||||||
|
prefix = prefixes[0];
|
||||||
|
else if (!video && !encoder)
|
||||||
|
prefix = prefixes[1];
|
||||||
|
else if (video && encoder)
|
||||||
|
prefix = prefixes[2];
|
||||||
|
else
|
||||||
|
prefix = prefixes[3];
|
||||||
|
|
||||||
|
element_name = g_new0 (gchar, PREFIX_LEN + strlen (codec_name) + 1);
|
||||||
|
memcpy (element_name, prefix, PREFIX_LEN);
|
||||||
|
|
||||||
|
for (i = 0, k = 0; i < codec_name_len; i++) {
|
||||||
|
if (g_ascii_isalnum (codec_name[i])) {
|
||||||
|
element_name[PREFIX_LEN + k++] = g_ascii_tolower (codec_name[i]);
|
||||||
|
}
|
||||||
|
/* Skip all non-alnum chars */
|
||||||
|
}
|
||||||
|
|
||||||
|
return element_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef PREFIX_LEN
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
register_codecs (GstPlugin * plugin)
|
||||||
|
{
|
||||||
|
gboolean ret = TRUE;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = codec_infos; l; l = l->next) {
|
||||||
|
GstAmcCodecInfo *codec_info = l->data;
|
||||||
|
gboolean is_audio = FALSE;
|
||||||
|
gboolean is_video = FALSE;
|
||||||
|
gint i;
|
||||||
|
gint n_types;
|
||||||
|
|
||||||
|
GST_DEBUG ("Registering codec '%s'", codec_info->name);
|
||||||
|
for (i = 0; i < codec_info->n_supported_types; i++) {
|
||||||
|
GstAmcCodecType *codec_type = &codec_info->supported_types[i];
|
||||||
|
|
||||||
|
if (g_str_has_prefix (codec_type->mime, "audio/"))
|
||||||
|
is_audio = TRUE;
|
||||||
|
else if (g_str_has_prefix (codec_type->mime, "video/"))
|
||||||
|
is_video = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_types = 0;
|
||||||
|
if (is_audio)
|
||||||
|
n_types++;
|
||||||
|
if (is_video)
|
||||||
|
n_types++;
|
||||||
|
|
||||||
|
for (i = 0; i < n_types; i++) {
|
||||||
|
GTypeQuery type_query;
|
||||||
|
GTypeInfo type_info = { 0, };
|
||||||
|
GType type, subtype;
|
||||||
|
gchar *type_name, *element_name;
|
||||||
|
guint rank;
|
||||||
|
|
||||||
|
if (is_video && !codec_info->is_encoder)
|
||||||
|
type = gst_amc_video_dec_get_type ();
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
g_type_query (type, &type_query);
|
||||||
|
memset (&type_info, 0, sizeof (type_info));
|
||||||
|
type_info.class_size = type_query.class_size;
|
||||||
|
type_info.instance_size = type_query.instance_size;
|
||||||
|
type_name = create_type_name (type_query.type_name, codec_info->name);
|
||||||
|
|
||||||
|
if (g_type_from_name (type_name) != G_TYPE_INVALID) {
|
||||||
|
GST_ERROR ("Type '%s' already exists for codec '%s'", type_name,
|
||||||
|
codec_info->name);
|
||||||
|
g_free (type_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
subtype = g_type_register_static (type, type_name, &type_info, 0);
|
||||||
|
g_free (type_name);
|
||||||
|
|
||||||
|
g_type_set_qdata (type, gst_amc_codec_info_quark, codec_info);
|
||||||
|
|
||||||
|
element_name =
|
||||||
|
create_element_name (is_video, codec_info->is_encoder,
|
||||||
|
codec_info->name);
|
||||||
|
|
||||||
|
/* Give the Google software codec a secondary rank,
|
||||||
|
* everything else is likely a hardware codec */
|
||||||
|
if (g_str_has_prefix (codec_info->name, "OMX.google"))
|
||||||
|
rank = GST_RANK_SECONDARY;
|
||||||
|
else
|
||||||
|
rank = GST_RANK_PRIMARY;
|
||||||
|
|
||||||
|
ret |= gst_element_register (plugin, element_name, rank, subtype);
|
||||||
|
g_free (element_name);
|
||||||
|
|
||||||
|
is_video = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
|
@ -2219,9 +2373,12 @@ plugin_init (GstPlugin * plugin)
|
||||||
gst_plugin_add_dependency_simple (plugin, NULL, "/etc", "media_codecs.xml",
|
gst_plugin_add_dependency_simple (plugin, NULL, "/etc", "media_codecs.xml",
|
||||||
GST_PLUGIN_DEPENDENCY_FLAG_NONE);
|
GST_PLUGIN_DEPENDENCY_FLAG_NONE);
|
||||||
|
|
||||||
|
if (!get_java_classes () || !scan_codecs ())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
gst_amc_codec_info_quark = g_quark_from_static_string ("gst-amc-codec-info");
|
gst_amc_codec_info_quark = g_quark_from_static_string ("gst-amc-codec-info");
|
||||||
|
|
||||||
if (!get_java_classes () || !scan_codecs ())
|
if (!register_codecs (plugin))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
1321
sys/androidmedia/gstamcvideodec.c
Normal file
1321
sys/androidmedia/gstamcvideodec.c
Normal file
File diff suppressed because it is too large
Load diff
102
sys/androidmedia/gstamcvideodec.h
Normal file
102
sys/androidmedia/gstamcvideodec.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012, Collabora Ltd.
|
||||||
|
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_AMC_VIDEO_DEC_H__
|
||||||
|
#define __GST_AMC_VIDEO_DEC_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_GST_0_10_37
|
||||||
|
#include <gst/video/gstvideodecoder.h>
|
||||||
|
#else
|
||||||
|
#include "video/gstvideodecoder.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gstamc.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GST_TYPE_AMC_VIDEO_DEC \
|
||||||
|
(gst_amc_video_dec_get_type())
|
||||||
|
#define GST_AMC_VIDEO_DEC(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AMC_VIDEO_DEC,GstAmcVideoDec))
|
||||||
|
#define GST_AMC_VIDEO_DEC_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AMC_VIDEO_DEC,GstAmcVideoDecClass))
|
||||||
|
#define GST_AMC_VIDEO_DEC_GET_CLASS(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_AMC_VIDEO_DEC,GstAmcVideoDecClass))
|
||||||
|
#define GST_IS_AMC_VIDEO_DEC(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AMC_VIDEO_DEC))
|
||||||
|
#define GST_IS_AMC_VIDEO_DEC_CLASS(obj) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AMC_VIDEO_DEC))
|
||||||
|
|
||||||
|
typedef struct _GstAmcVideoDec GstAmcVideoDec;
|
||||||
|
typedef struct _GstAmcVideoDecClass GstAmcVideoDecClass;
|
||||||
|
|
||||||
|
struct _GstAmcVideoDec
|
||||||
|
{
|
||||||
|
GstVideoDecoder parent;
|
||||||
|
|
||||||
|
/* < private > */
|
||||||
|
GstAmcCodec *codec;
|
||||||
|
GstAmcBuffer *input_buffers, *output_buffers;
|
||||||
|
gsize n_input_buffers, n_output_buffers;
|
||||||
|
|
||||||
|
GstVideoCodecState *input_state;
|
||||||
|
gboolean input_state_changed;
|
||||||
|
|
||||||
|
/* Output format of the codec */
|
||||||
|
GstVideoFormat format;
|
||||||
|
gint color_format;
|
||||||
|
gint width, height, stride, slice_height;
|
||||||
|
gint crop_left, crop_right;
|
||||||
|
gint crop_top, crop_bottom;
|
||||||
|
|
||||||
|
GstBuffer *codec_data;
|
||||||
|
/* TRUE if the component is configured and saw
|
||||||
|
* the first buffer */
|
||||||
|
gboolean started;
|
||||||
|
gboolean flushing;
|
||||||
|
|
||||||
|
GstClockTime last_upstream_ts;
|
||||||
|
|
||||||
|
/* Draining state */
|
||||||
|
GMutex *drain_lock;
|
||||||
|
GCond *drain_cond;
|
||||||
|
/* TRUE if EOS buffers shouldn't be forwarded */
|
||||||
|
gboolean draining;
|
||||||
|
|
||||||
|
/* TRUE if upstream is EOS */
|
||||||
|
gboolean eos;
|
||||||
|
|
||||||
|
GstFlowReturn downstream_flow_ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstAmcVideoDecClass
|
||||||
|
{
|
||||||
|
GstVideoDecoderClass parent_class;
|
||||||
|
|
||||||
|
const GstAmcCodecInfo *codec_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gst_amc_video_dec_get_type (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_AMC_VIDEO_DEC_H__ */
|
Loading…
Reference in a new issue