1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2017 Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun * Author: Randy Li <randy.li@rock-chips.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2021 Rockchip Electronics Co., Ltd
6*4882a593Smuzhiyun * Author: Jeffy Chen <jeffy.chen@rock-chips.com>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This library is free software; you can redistribute it and/or
9*4882a593Smuzhiyun * modify it under the terms of the GNU Library General Public
10*4882a593Smuzhiyun * License as published by the Free Software Foundation; either
11*4882a593Smuzhiyun * version 2 of the License, or (at your option) any later version.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * This library is distributed in the hope that it will be useful,
14*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16*4882a593Smuzhiyun * Library General Public License for more details.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * You should have received a copy of the GNU Library General Public
19*4882a593Smuzhiyun * License along with this library; if not, write to the
20*4882a593Smuzhiyun * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21*4882a593Smuzhiyun * Boston, MA 02110-1301, USA.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun */
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #ifdef HAVE_CONFIG_H
26*4882a593Smuzhiyun #include "config.h"
27*4882a593Smuzhiyun #endif
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #include "gstmppvideodec.h"
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #define GST_MPP_VIDEO_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
32*4882a593Smuzhiyun GST_TYPE_MPP_VIDEO_DEC, GstMppVideoDec))
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define GST_CAT_DEFAULT mpp_video_dec_debug
35*4882a593Smuzhiyun GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun struct _GstMppVideoDec
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun GstMppDec parent;
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun gint poll_timeout;
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define parent_class gst_mpp_video_dec_parent_class
45*4882a593Smuzhiyun G_DEFINE_TYPE (GstMppVideoDec, gst_mpp_video_dec, GST_TYPE_MPP_DEC);
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* Default output format is auto */
48*4882a593Smuzhiyun static GstVideoFormat DEFAULT_PROP_FORMAT = GST_VIDEO_FORMAT_UNKNOWN;
49*4882a593Smuzhiyun /* Disable ARM AFBC by default */
50*4882a593Smuzhiyun static GstVideoFormat DEFAULT_PROP_ARM_AFBC = FALSE;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun enum
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun PROP_0,
55*4882a593Smuzhiyun PROP_FORMAT,
56*4882a593Smuzhiyun PROP_ARM_AFBC,
57*4882a593Smuzhiyun PROP_LAST,
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun /* GstVideoDecoder base class method */
61*4882a593Smuzhiyun static GstStaticPadTemplate gst_mpp_video_dec_sink_template =
62*4882a593Smuzhiyun GST_STATIC_PAD_TEMPLATE ("sink",
63*4882a593Smuzhiyun GST_PAD_SINK,
64*4882a593Smuzhiyun GST_PAD_ALWAYS,
65*4882a593Smuzhiyun GST_STATIC_CAPS ("video/x-h263, parsed = (boolean) true;"
66*4882a593Smuzhiyun "video/x-h264, parsed = (boolean) true;"
67*4882a593Smuzhiyun "video/x-h265, parsed = (boolean) true;"
68*4882a593Smuzhiyun "video/x-av1, parsed = (boolean) true;"
69*4882a593Smuzhiyun "video/x-vp8; video/x-vp9;"
70*4882a593Smuzhiyun "video/mpeg, parsed = (boolean) true,"
71*4882a593Smuzhiyun "mpegversion = (int) { 1, 2, 4 }, systemstream = (boolean) false;"));
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun static GstStaticPadTemplate gst_mpp_video_dec_src_template =
74*4882a593Smuzhiyun GST_STATIC_PAD_TEMPLATE ("src",
75*4882a593Smuzhiyun GST_PAD_SRC,
76*4882a593Smuzhiyun GST_PAD_ALWAYS,
77*4882a593Smuzhiyun GST_STATIC_CAPS (MPP_DEC_CAPS_MAKE ("{" MPP_DEC_FORMATS "}") ";"
78*4882a593Smuzhiyun MPP_DEC_CAPS_MAKE_AFBC ("{" MPP_DEC_FORMATS "}") ";")
79*4882a593Smuzhiyun );
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun static MppCodingType
gst_mpp_video_dec_get_mpp_type(GstStructure * s)82*4882a593Smuzhiyun gst_mpp_video_dec_get_mpp_type (GstStructure * s)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/x-h263"))
85*4882a593Smuzhiyun return MPP_VIDEO_CodingH263;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/x-h264"))
88*4882a593Smuzhiyun return MPP_VIDEO_CodingAVC;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/x-h265"))
91*4882a593Smuzhiyun return MPP_VIDEO_CodingHEVC;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/x-av1"))
94*4882a593Smuzhiyun return MPP_VIDEO_CodingAV1;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/mpeg")) {
97*4882a593Smuzhiyun gint mpegversion = 0;
98*4882a593Smuzhiyun if (gst_structure_get_int (s, "mpegversion", &mpegversion)) {
99*4882a593Smuzhiyun switch (mpegversion) {
100*4882a593Smuzhiyun case 1:
101*4882a593Smuzhiyun case 2:
102*4882a593Smuzhiyun return MPP_VIDEO_CodingMPEG2;
103*4882a593Smuzhiyun case 4:
104*4882a593Smuzhiyun return MPP_VIDEO_CodingMPEG4;
105*4882a593Smuzhiyun default:
106*4882a593Smuzhiyun g_assert_not_reached ();
107*4882a593Smuzhiyun return MPP_VIDEO_CodingUnused;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/x-vp8"))
113*4882a593Smuzhiyun return MPP_VIDEO_CodingVP8;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun if (gst_structure_has_name (s, "video/x-vp9"))
116*4882a593Smuzhiyun return MPP_VIDEO_CodingVP9;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun return MPP_VIDEO_CodingUnused;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun static void
gst_mpp_video_dec_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)122*4882a593Smuzhiyun gst_mpp_video_dec_set_property (GObject * object,
123*4882a593Smuzhiyun guint prop_id, const GValue * value, GParamSpec * pspec)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun GstVideoDecoder *decoder = GST_VIDEO_DECODER (object);
126*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun switch (prop_id) {
129*4882a593Smuzhiyun case PROP_FORMAT:{
130*4882a593Smuzhiyun if (mppdec->input_state)
131*4882a593Smuzhiyun GST_WARNING_OBJECT (decoder, "unable to change output format");
132*4882a593Smuzhiyun else
133*4882a593Smuzhiyun mppdec->format = g_value_get_enum (value);
134*4882a593Smuzhiyun break;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun case PROP_ARM_AFBC:{
137*4882a593Smuzhiyun if (mppdec->input_state)
138*4882a593Smuzhiyun GST_WARNING_OBJECT (decoder, "unable to change ARM AFBC");
139*4882a593Smuzhiyun else
140*4882a593Smuzhiyun mppdec->arm_afbc = g_value_get_boolean (value);
141*4882a593Smuzhiyun break;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun default:
144*4882a593Smuzhiyun G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
145*4882a593Smuzhiyun return;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun static void
gst_mpp_video_dec_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)150*4882a593Smuzhiyun gst_mpp_video_dec_get_property (GObject * object,
151*4882a593Smuzhiyun guint prop_id, GValue * value, GParamSpec * pspec)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun GstVideoDecoder *decoder = GST_VIDEO_DECODER (object);
154*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun switch (prop_id) {
157*4882a593Smuzhiyun case PROP_FORMAT:
158*4882a593Smuzhiyun g_value_set_enum (value, mppdec->format);
159*4882a593Smuzhiyun break;
160*4882a593Smuzhiyun case PROP_ARM_AFBC:
161*4882a593Smuzhiyun g_value_set_boolean (value, mppdec->arm_afbc);
162*4882a593Smuzhiyun break;
163*4882a593Smuzhiyun default:
164*4882a593Smuzhiyun G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
165*4882a593Smuzhiyun break;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun static gboolean
gst_mpp_video_dec_set_format(GstVideoDecoder * decoder,GstVideoCodecState * state)170*4882a593Smuzhiyun gst_mpp_video_dec_set_format (GstVideoDecoder * decoder,
171*4882a593Smuzhiyun GstVideoCodecState * state)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun GstVideoDecoderClass *pclass = GST_VIDEO_DECODER_CLASS (parent_class);
174*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
175*4882a593Smuzhiyun GstStructure *structure;
176*4882a593Smuzhiyun const gchar *chroma_format;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun structure = gst_caps_get_structure (state->caps, 0);
179*4882a593Smuzhiyun mppdec->mpp_type = gst_mpp_video_dec_get_mpp_type (structure);
180*4882a593Smuzhiyun g_return_val_if_fail (mppdec->mpp_type != MPP_VIDEO_CodingUnused, FALSE);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* MPP doesn't support YUV444 for h264 */
183*4882a593Smuzhiyun if (mppdec->mpp_type == MPP_VIDEO_CodingAVC) {
184*4882a593Smuzhiyun chroma_format = gst_structure_get_string (structure, "chroma-format");
185*4882a593Smuzhiyun if (g_strcmp0 (chroma_format, "4:4:4") == 0)
186*4882a593Smuzhiyun return FALSE;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun return pclass->set_format (decoder, state);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun static gboolean
gst_mpp_video_dec_startup(GstVideoDecoder * decoder)193*4882a593Smuzhiyun gst_mpp_video_dec_startup (GstVideoDecoder * decoder)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun GstMppVideoDec *self = GST_MPP_VIDEO_DEC (decoder);
196*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
197*4882a593Smuzhiyun GstVideoCodecState *state = mppdec->input_state;
198*4882a593Smuzhiyun GstBuffer *codec_data = state->codec_data;
199*4882a593Smuzhiyun GstMapInfo mapinfo = { 0, };
200*4882a593Smuzhiyun MppPacket mpkt;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* Send extra codec data */
203*4882a593Smuzhiyun if (codec_data) {
204*4882a593Smuzhiyun gst_buffer_ref (codec_data);
205*4882a593Smuzhiyun gst_buffer_map (codec_data, &mapinfo, GST_MAP_READ);
206*4882a593Smuzhiyun mpp_packet_init (&mpkt, mapinfo.data, mapinfo.size);
207*4882a593Smuzhiyun mpp_packet_set_extra_data (mpkt);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun mppdec->mpi->decode_put_packet (mppdec->mpp_ctx, mpkt);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun mpp_packet_deinit (&mpkt);
212*4882a593Smuzhiyun gst_buffer_unmap (codec_data, &mapinfo);
213*4882a593Smuzhiyun gst_buffer_unref (codec_data);
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun if (mppdec->arm_afbc) {
217*4882a593Smuzhiyun MppFrameFormat mpp_format = MPP_FMT_YUV420SP | MPP_FRAME_FBC_AFBC_V2;
218*4882a593Smuzhiyun mppdec->mpi->control (mppdec->mpp_ctx, MPP_DEC_SET_OUTPUT_FORMAT,
219*4882a593Smuzhiyun &mpp_format);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun self->poll_timeout = 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun return TRUE;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun static MppPacket
gst_mpp_video_dec_get_mpp_packet(GstVideoDecoder * decoder UNUSED,GstMapInfo * mapinfo)228*4882a593Smuzhiyun gst_mpp_video_dec_get_mpp_packet (GstVideoDecoder * decoder UNUSED,
229*4882a593Smuzhiyun GstMapInfo * mapinfo)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun MppPacket mpkt = NULL;
232*4882a593Smuzhiyun mpp_packet_init (&mpkt, mapinfo->data, mapinfo->size);
233*4882a593Smuzhiyun return mpkt;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun static gboolean
gst_mpp_video_dec_send_mpp_packet(GstVideoDecoder * decoder,MppPacket mpkt,gint timeout_ms)237*4882a593Smuzhiyun gst_mpp_video_dec_send_mpp_packet (GstVideoDecoder * decoder,
238*4882a593Smuzhiyun MppPacket mpkt, gint timeout_ms)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
241*4882a593Smuzhiyun gint interval_ms = 2;
242*4882a593Smuzhiyun MPP_RET ret;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun do {
245*4882a593Smuzhiyun ret = mppdec->mpi->decode_put_packet (mppdec->mpp_ctx, mpkt);
246*4882a593Smuzhiyun if (!ret) {
247*4882a593Smuzhiyun mpp_packet_deinit (&mpkt);
248*4882a593Smuzhiyun return TRUE;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun g_usleep (interval_ms * 1000);
252*4882a593Smuzhiyun timeout_ms -= interval_ms;
253*4882a593Smuzhiyun } while (timeout_ms > 0);
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun return FALSE;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun static MppFrame
gst_mpp_video_dec_poll_mpp_frame(GstVideoDecoder * decoder,gint timeout_ms)259*4882a593Smuzhiyun gst_mpp_video_dec_poll_mpp_frame (GstVideoDecoder * decoder, gint timeout_ms)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun GstMppVideoDec *self = GST_MPP_VIDEO_DEC (decoder);
262*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
263*4882a593Smuzhiyun MppFrame mframe = NULL;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun if (self->poll_timeout != timeout_ms) {
266*4882a593Smuzhiyun self->poll_timeout = timeout_ms;
267*4882a593Smuzhiyun mppdec->mpi->control (mppdec->mpp_ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout_ms);
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun mppdec->mpi->decode_get_frame (mppdec->mpp_ctx, &mframe);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun return mframe;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun static gboolean
gst_mpp_video_dec_shutdown(GstVideoDecoder * decoder,gboolean drain)276*4882a593Smuzhiyun gst_mpp_video_dec_shutdown (GstVideoDecoder * decoder, gboolean drain)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (decoder);
279*4882a593Smuzhiyun MppPacket mpkt;
280*4882a593Smuzhiyun MPP_RET ret;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun /* It's safe to stop decoding immediately */
283*4882a593Smuzhiyun if (!drain) {
284*4882a593Smuzhiyun /* Interrupt the frame polling */
285*4882a593Smuzhiyun mppdec->mpi->reset (mppdec->mpp_ctx);
286*4882a593Smuzhiyun return FALSE;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun mpp_packet_init (&mpkt, NULL, 0);
290*4882a593Smuzhiyun mpp_packet_set_eos (mpkt);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun while (1) {
293*4882a593Smuzhiyun ret = mppdec->mpi->decode_put_packet (mppdec->mpp_ctx, mpkt);
294*4882a593Smuzhiyun if (!ret)
295*4882a593Smuzhiyun break;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun g_usleep (1000);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun mpp_packet_deinit (&mpkt);
301*4882a593Smuzhiyun return TRUE;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun #define GST_TYPE_MPP_VIDEO_DEC_FORMAT (gst_mpp_video_dec_format_get_type ())
305*4882a593Smuzhiyun static GType
gst_mpp_video_dec_format_get_type(void)306*4882a593Smuzhiyun gst_mpp_video_dec_format_get_type (void)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun static GType format = 0;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (!format) {
311*4882a593Smuzhiyun static const GEnumValue formats[] = {
312*4882a593Smuzhiyun {GST_VIDEO_FORMAT_UNKNOWN, "Auto", "auto"},
313*4882a593Smuzhiyun {GST_VIDEO_FORMAT_NV12, "NV12", "NV12"},
314*4882a593Smuzhiyun {GST_VIDEO_FORMAT_NV21, "NV21", "NV21"},
315*4882a593Smuzhiyun {GST_VIDEO_FORMAT_I420, "I420", "I420"},
316*4882a593Smuzhiyun {GST_VIDEO_FORMAT_YV12, "YV12", "YV12"},
317*4882a593Smuzhiyun {GST_VIDEO_FORMAT_NV16, "NV16", "NV16"},
318*4882a593Smuzhiyun {GST_VIDEO_FORMAT_NV61, "NV61", "NV61"},
319*4882a593Smuzhiyun {GST_VIDEO_FORMAT_BGR16, "BGR565", "BGR16"},
320*4882a593Smuzhiyun {GST_VIDEO_FORMAT_RGB, "RGB", "RGB"},
321*4882a593Smuzhiyun {GST_VIDEO_FORMAT_BGR, "BGR", "BGR"},
322*4882a593Smuzhiyun {GST_VIDEO_FORMAT_RGBA, "RGBA8888", "RGBA"},
323*4882a593Smuzhiyun {GST_VIDEO_FORMAT_BGRA, "BGRA8888", "BGRA"},
324*4882a593Smuzhiyun {GST_VIDEO_FORMAT_RGBx, "RGBX8888", "RGBx"},
325*4882a593Smuzhiyun {GST_VIDEO_FORMAT_BGRx, "BGRX8888", "BGRx"},
326*4882a593Smuzhiyun {0, NULL, NULL}
327*4882a593Smuzhiyun };
328*4882a593Smuzhiyun format = g_enum_register_static ("GstMppVideoDecFormat", formats);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun return format;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun static void
gst_mpp_video_dec_init(GstMppVideoDec * self)334*4882a593Smuzhiyun gst_mpp_video_dec_init (GstMppVideoDec * self)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun GstMppDec *mppdec = GST_MPP_DEC (self);
337*4882a593Smuzhiyun mppdec->format = DEFAULT_PROP_FORMAT;
338*4882a593Smuzhiyun mppdec->arm_afbc = DEFAULT_PROP_ARM_AFBC;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun static void
gst_mpp_video_dec_setup_default_format(void)342*4882a593Smuzhiyun gst_mpp_video_dec_setup_default_format (void)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun GEnumClass *class;
345*4882a593Smuzhiyun GEnumValue *value;
346*4882a593Smuzhiyun const gchar *env;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun env = g_getenv ("GST_MPP_VIDEODEC_DEFAULT_FORMAT");
349*4882a593Smuzhiyun if (!env)
350*4882a593Smuzhiyun return;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun class = g_type_class_ref (GST_TYPE_MPP_VIDEO_DEC_FORMAT);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun value = g_enum_get_value_by_nick (class, env);
355*4882a593Smuzhiyun if (value)
356*4882a593Smuzhiyun DEFAULT_PROP_FORMAT = value->value;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun g_type_class_unref (class);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun static void
gst_mpp_video_dec_class_init(GstMppVideoDecClass * klass)362*4882a593Smuzhiyun gst_mpp_video_dec_class_init (GstMppVideoDecClass * klass)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
365*4882a593Smuzhiyun GstMppDecClass *pclass = GST_MPP_DEC_CLASS (klass);
366*4882a593Smuzhiyun GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
367*4882a593Smuzhiyun GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "mppvideodec", 0,
370*4882a593Smuzhiyun "MPP video decoder");
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_mpp_video_dec_set_format);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun pclass->startup = GST_DEBUG_FUNCPTR (gst_mpp_video_dec_startup);
375*4882a593Smuzhiyun pclass->get_mpp_packet = GST_DEBUG_FUNCPTR (gst_mpp_video_dec_get_mpp_packet);
376*4882a593Smuzhiyun pclass->send_mpp_packet =
377*4882a593Smuzhiyun GST_DEBUG_FUNCPTR (gst_mpp_video_dec_send_mpp_packet);
378*4882a593Smuzhiyun pclass->poll_mpp_frame = GST_DEBUG_FUNCPTR (gst_mpp_video_dec_poll_mpp_frame);
379*4882a593Smuzhiyun pclass->shutdown = GST_DEBUG_FUNCPTR (gst_mpp_video_dec_shutdown);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun gobject_class->set_property =
382*4882a593Smuzhiyun GST_DEBUG_FUNCPTR (gst_mpp_video_dec_set_property);
383*4882a593Smuzhiyun gobject_class->get_property =
384*4882a593Smuzhiyun GST_DEBUG_FUNCPTR (gst_mpp_video_dec_get_property);
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun gst_mpp_video_dec_setup_default_format ();
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun #ifdef HAVE_RGA
389*4882a593Smuzhiyun g_object_class_install_property (gobject_class, PROP_FORMAT,
390*4882a593Smuzhiyun g_param_spec_enum ("format", "Prefered output format",
391*4882a593Smuzhiyun "Prefered output format",
392*4882a593Smuzhiyun GST_TYPE_MPP_VIDEO_DEC_FORMAT, DEFAULT_PROP_FORMAT,
393*4882a593Smuzhiyun G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
394*4882a593Smuzhiyun #endif
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun if (g_getenv ("GST_MPP_VIDEODEC_DEFAULT_ARM_AFBC"))
397*4882a593Smuzhiyun DEFAULT_PROP_ARM_AFBC = TRUE;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun g_object_class_install_property (gobject_class, PROP_ARM_AFBC,
400*4882a593Smuzhiyun g_param_spec_boolean ("arm-afbc", "ARM AFBC",
401*4882a593Smuzhiyun "Prefer ARM AFBC compressed format", DEFAULT_PROP_ARM_AFBC,
402*4882a593Smuzhiyun G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun gst_element_class_add_pad_template (element_class,
405*4882a593Smuzhiyun gst_static_pad_template_get (&gst_mpp_video_dec_src_template));
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun gst_element_class_add_pad_template (element_class,
408*4882a593Smuzhiyun gst_static_pad_template_get (&gst_mpp_video_dec_sink_template));
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun gst_element_class_set_static_metadata (element_class,
411*4882a593Smuzhiyun "Rockchip's MPP video decoder", "Decoder/Video",
412*4882a593Smuzhiyun "Multicodec (HEVC / AVC / VP8 / VP9) hardware decoder",
413*4882a593Smuzhiyun "Randy Li <randy.li@rock-chips.com>, "
414*4882a593Smuzhiyun "Jeffy Chen <jeffy.chen@rock-chips.com>");
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun gboolean
gst_mpp_video_dec_register(GstPlugin * plugin,guint rank)418*4882a593Smuzhiyun gst_mpp_video_dec_register (GstPlugin * plugin, guint rank)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun return gst_element_register (plugin, "mppvideodec", rank,
421*4882a593Smuzhiyun gst_mpp_video_dec_get_type ());
422*4882a593Smuzhiyun }
423