blob: a33d8f0301bb207618f0344d1626195020c8f7db [file] [log] [blame]
/*
* Copyright (c) 2016 MediaTek Inc
* Author: Rick Chang <rick.chang@mediatek.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include "gstv4l2mtkjpegdec.h"
#include "v4l2_calls.h"
#include <string.h>
#include <gst/gst-i18n-plugin.h>
GST_DEBUG_CATEGORY_STATIC (gst_v4l2_mtk_jpeg_dec_debug);
#define GST_CAT_DEFAULT gst_v4l2_mtk_jpeg_dec_debug
typedef struct
{
gchar *device;
GstCaps *sink_caps;
GstCaps *src_caps;
} GstV4l2MtkJpegDecCData;
enum
{
PROP_0,
V4L2_STD_OBJECT_PROPS,
};
static GstStaticPadTemplate gst_mtk_jpeg_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ "
"I420, Y42B, I422 } "))
);
#define gst_v4l2_mtk_jpeg_dec_parent_class parent_class
G_DEFINE_TYPE (GstV4l2MtkJpegDec, gst_v4l2_mtk_jpeg_dec, GST_TYPE_V4L2_VIDEO_DEC);
static void
gst_v4l2_mtk_jpeg_dec_init (GstV4l2MtkJpegDec * self)
{
}
static void
gst_v4l2_mtk_jpeg_dec_subinstance_init (GTypeInstance * instance, gpointer g_class)
{
GstV4l2VideoDecClass *klass = GST_V4L2_VIDEO_DEC_CLASS (g_class);
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (instance);
GstVideoDecoder *decoder = GST_VIDEO_DECODER (instance);
gst_video_decoder_set_packetized (decoder, TRUE);
self->v4l2output = gst_v4l2_object_new (GST_ELEMENT (self),
GST_VIDEO_DECODER_SINK_PAD (decoder), V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
gst_v4l2_get_output, gst_v4l2_set_output, NULL);
self->v4l2output->no_initial_format = TRUE;
self->v4l2output->keep_aspect = FALSE;
self->v4l2capture = gst_v4l2_object_new (GST_ELEMENT (self),
GST_VIDEO_DECODER_SRC_PAD (decoder), V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
gst_v4l2_get_input, gst_v4l2_set_input, NULL);
self->v4l2capture->no_initial_format = TRUE;
self->v4l2output->keep_aspect = FALSE;
}
static void
gst_v4l2_mtk_jpeg_dec_class_init (GstV4l2MtkJpegDecClass * klass)
{
GstElementClass *element_class;
GObjectClass *gobject_class;
GstV4l2VideoDecClass *v4l2_decoder_class;
GstVideoEncoderClass *baseclass;
parent_class = g_type_class_peek_parent (klass);
element_class = (GstElementClass *) klass;
gobject_class = (GObjectClass *) klass;
v4l2_decoder_class = GST_V4L2_VIDEO_DEC_CLASS (klass);
baseclass = GST_VIDEO_DECODER_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (gst_v4l2_mtk_jpeg_dec_debug, "v4l2mtkjpegdec", 0,
"V4L2 Mtk Jpeg HW Decoder");
gst_element_class_set_static_metadata (element_class,
"V4L2 Mtk Jpeg HW Decoder",
"Codec/Decoder/Image",
"MTK jpeg HW decode via V4L2 API",
"Rick Chang <rick.chang@mediatek.com>");
}
static void
gst_v4l2_mtk_jpeg_dec_subclass_init (gpointer g_class, gpointer data)
{
GstV4l2VideoDecClass *klass = GST_V4L2_VIDEO_DEC_CLASS (g_class);
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GstV4l2MtkJpegDecCData *cdata = data;
klass->default_device = cdata->device;
/* Note: gst_pad_template_new() take the floating ref from the caps */
gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
cdata->sink_caps));
gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
cdata->src_caps));
g_free (cdata);
}
gboolean
gst_v4l2_is_mtk_jpeg_dec (GstCaps * sink_caps, GstCaps * src_caps)
{
gboolean ret = FALSE;
GstCaps *caps = gst_caps_new_empty_simple ("image/jpeg");
if (gst_caps_is_subset (sink_caps, caps)
&& gst_caps_is_subset (src_caps, gst_v4l2_object_get_raw_caps ()))
ret = TRUE;
gst_caps_ref (caps);
return ret;
}
gboolean
gst_v4l2_mtk_jpeg_dec_register (GstPlugin * plugin, const gchar * basename,
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
{
GTypeQuery type_query;
GTypeInfo type_info = { 0, };
GType type, subtype;
gchar *type_name;
GstV4l2MtkJpegDecCData *cdata;
cdata = g_new0 (GstV4l2MtkJpegDecCData, 1);
cdata->device = g_strdup (device_path);
cdata->sink_caps = gst_caps_ref (sink_caps);
cdata->src_caps = gst_static_pad_template_get_caps(&gst_mtk_jpeg_src_template);
type = gst_v4l2_mtk_jpeg_dec_get_type ();
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_info.class_init = gst_v4l2_mtk_jpeg_dec_subclass_init;
type_info.class_data = cdata;
type_info.instance_init = gst_v4l2_mtk_jpeg_dec_subinstance_init;
type_name = g_strdup_printf ("v4l2mtkjpegdec");
subtype = g_type_register_static (type, type_name, &type_info, 0);
gst_element_register (plugin, type_name, GST_RANK_PRIMARY + 1, subtype);
g_free (type_name);
return TRUE;
}