xref: /OK3568_Linux_fs/external/gstreamer-rockchip/gst/rockchipmpp/gstmppvideodec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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