1 /*
2 * Copyright 2018 Rockchip Electronics Co., Ltd
3 * Author: Randy Li <randy.li@rock-chips.com>
4 *
5 * Copyright 2021 Rockchip Electronics Co., Ltd
6 * Author: Jeffy Chen <jeffy.chen@rock-chips.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "gstmppallocator.h"
30 #include "gstmppjpegdec.h"
31
32 #define GST_MPP_JPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
33 GST_TYPE_MPP_JPEG_DEC, GstMppJpegDec))
34
35 #define GST_CAT_DEFAULT mpp_jpeg_dec_debug
36 GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
37
38 struct _GstMppJpegDec
39 {
40 GstMppDec parent;
41
42 /* size of output buffer */
43 guint buf_size;
44
45 /* group for input packet buffer allocations */
46 MppBufferGroup input_group;
47
48 MppPacket eos_packet;
49 };
50
51 #define parent_class gst_mpp_jpeg_dec_parent_class
52 G_DEFINE_TYPE (GstMppJpegDec, gst_mpp_jpeg_dec, GST_TYPE_MPP_DEC);
53
54 /* Default output format is auto */
55 static GstVideoFormat DEFAULT_PROP_FORMAT = GST_VIDEO_FORMAT_UNKNOWN;
56
57 enum
58 {
59 PROP_0,
60 PROP_FORMAT,
61 PROP_LAST,
62 };
63
64 /* GstVideoDecoder base class method */
65 static GstStaticPadTemplate gst_mpp_jpeg_dec_sink_template =
66 GST_STATIC_PAD_TEMPLATE ("sink",
67 GST_PAD_SINK,
68 GST_PAD_ALWAYS,
69 GST_STATIC_CAPS ("image/jpeg," "parsed = (boolean) true" ";")
70 );
71
72 #define MPP_JPEGDEC_FORMATS \
73 MPP_DEC_FORMATS ", BGR16, RGB16, " \
74 "ABGR, ARGB, BGRA, RGBA, xBGR, xRGB, BGRx, RGBx"
75
76 static GstStaticPadTemplate gst_mpp_jpeg_dec_src_template =
77 GST_STATIC_PAD_TEMPLATE ("src",
78 GST_PAD_SRC,
79 GST_PAD_ALWAYS,
80 GST_STATIC_CAPS (MPP_DEC_CAPS_MAKE ("{" MPP_JPEGDEC_FORMATS "}") ";")
81 );
82
83 static const GstVideoFormat gst_mpp_jpeg_dec_pp_formats[] = {
84 GST_VIDEO_FORMAT_UNKNOWN,
85 GST_VIDEO_FORMAT_NV12,
86 GST_VIDEO_FORMAT_RGB16,
87 GST_VIDEO_FORMAT_BGR16,
88 GST_VIDEO_FORMAT_ARGB,
89 GST_VIDEO_FORMAT_ABGR,
90 GST_VIDEO_FORMAT_RGBA,
91 GST_VIDEO_FORMAT_BGRA,
92 GST_VIDEO_FORMAT_xRGB,
93 GST_VIDEO_FORMAT_xBGR,
94 GST_VIDEO_FORMAT_RGBx,
95 GST_VIDEO_FORMAT_BGRx,
96 };
97
98 static GstVideoFormat
gst_mpp_jpeg_dec_try_pp_convert(GstVideoDecoder * decoder,GstVideoFormat format,gboolean force)99 gst_mpp_jpeg_dec_try_pp_convert (GstVideoDecoder * decoder,
100 GstVideoFormat format, gboolean force)
101 {
102 GstMppDec *mppdec = GST_MPP_DEC (decoder);
103 MppFrameFormat mpp_format = force ? MPP_FMT_YUV420SP : MPP_FMT_BUTT;
104 guint i;
105
106 for (i = 0; i < ARRAY_SIZE (gst_mpp_jpeg_dec_pp_formats); i++) {
107 if (format == gst_mpp_jpeg_dec_pp_formats[i]) {
108 mpp_format = gst_mpp_gst_format_to_mpp_format (format);
109 break;
110 }
111 }
112
113 /* Using MPP internal format conversion (PP) */
114 if (mpp_format != MPP_FMT_BUTT) {
115 if (mppdec->mpi->control (mppdec->mpp_ctx, MPP_DEC_SET_OUTPUT_FORMAT,
116 &mpp_format) >= 0)
117 return gst_mpp_mpp_format_to_gst_format (mpp_format);
118 }
119
120 return GST_VIDEO_FORMAT_UNKNOWN;
121 }
122
123 static GstVideoFormat
gst_mpp_jpeg_dec_get_format(GstStructure * structure)124 gst_mpp_jpeg_dec_get_format (GstStructure * structure)
125 {
126 const gchar *s;
127
128 if ((s = gst_structure_get_string (structure, "format")))
129 return gst_video_format_from_string (s);
130
131 return GST_VIDEO_FORMAT_UNKNOWN;
132 }
133
134 static void
gst_mpp_jpeg_dec_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)135 gst_mpp_jpeg_dec_set_property (GObject * object,
136 guint prop_id, const GValue * value, GParamSpec * pspec)
137 {
138 GstVideoDecoder *decoder = GST_VIDEO_DECODER (object);
139 GstMppDec *mppdec = GST_MPP_DEC (decoder);
140
141 switch (prop_id) {
142 case PROP_FORMAT:{
143 if (mppdec->input_state)
144 GST_WARNING_OBJECT (decoder, "unable to change output format");
145 else
146 mppdec->format = g_value_get_enum (value);
147 break;
148 }
149
150 default:
151 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
152 return;
153 }
154 }
155
156 static void
gst_mpp_jpeg_dec_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)157 gst_mpp_jpeg_dec_get_property (GObject * object,
158 guint prop_id, GValue * value, GParamSpec * pspec)
159 {
160 GstVideoDecoder *decoder = GST_VIDEO_DECODER (object);
161 GstMppDec *mppdec = GST_MPP_DEC (decoder);
162
163 switch (prop_id) {
164 case PROP_FORMAT:
165 g_value_set_enum (value, mppdec->format);
166 break;
167 default:
168 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
169 break;
170 }
171 }
172
173 static gboolean
gst_mpp_jpeg_dec_start(GstVideoDecoder * decoder)174 gst_mpp_jpeg_dec_start (GstVideoDecoder * decoder)
175 {
176 GstVideoDecoderClass *pclass = GST_VIDEO_DECODER_CLASS (parent_class);
177 GstMppJpegDec *self = GST_MPP_JPEG_DEC (decoder);
178 GstMppDec *mppdec = GST_MPP_DEC (decoder);
179 MppBuffer mbuf;
180
181 GST_DEBUG_OBJECT (self, "starting");
182
183 if (mpp_buffer_group_get_internal (&self->input_group, MPP_BUFFER_TYPE_DRM))
184 return FALSE;
185
186 /* Prepare EOS packet */
187 mpp_buffer_get (self->input_group, &mbuf, 1);
188 mpp_packet_init_with_buffer (&self->eos_packet, mbuf);
189 mpp_buffer_put (mbuf);
190 mpp_packet_set_size (self->eos_packet, 0);
191 mpp_packet_set_length (self->eos_packet, 0);
192 mpp_packet_set_eos (self->eos_packet);
193
194 if (!pclass->start (decoder)) {
195 mpp_packet_deinit (&self->eos_packet);
196 mpp_buffer_group_put (self->input_group);
197 return FALSE;
198 }
199
200 mppdec->mpp_type = MPP_VIDEO_CodingMJPEG;
201
202 GST_DEBUG_OBJECT (self, "started");
203
204 return TRUE;
205 }
206
207 static gboolean
gst_mpp_jpeg_dec_stop(GstVideoDecoder * decoder)208 gst_mpp_jpeg_dec_stop (GstVideoDecoder * decoder)
209 {
210 GstVideoDecoderClass *pclass = GST_VIDEO_DECODER_CLASS (parent_class);
211 GstMppJpegDec *self = GST_MPP_JPEG_DEC (decoder);
212
213 GST_DEBUG_OBJECT (self, "stopping");
214
215 pclass->stop (decoder);
216
217 mpp_packet_deinit (&self->eos_packet);
218 mpp_buffer_group_put (self->input_group);
219
220 GST_DEBUG_OBJECT (self, "stopped");
221
222 return TRUE;
223 }
224
225 static gboolean
gst_mpp_jpeg_dec_set_format(GstVideoDecoder * decoder,GstVideoCodecState * state)226 gst_mpp_jpeg_dec_set_format (GstVideoDecoder * decoder,
227 GstVideoCodecState * state)
228 {
229 GstVideoDecoderClass *pclass = GST_VIDEO_DECODER_CLASS (parent_class);
230 GstMppJpegDec *self = GST_MPP_JPEG_DEC (decoder);
231 GstMppDec *mppdec = GST_MPP_DEC (decoder);
232 GstVideoInfo *info = &mppdec->info;
233 GstStructure *structure;
234 GstVideoFormat src_format, dst_format;
235 gint width = GST_VIDEO_INFO_WIDTH (&state->info);
236 gint height = GST_VIDEO_INFO_HEIGHT (&state->info);
237 gint dst_width, dst_height;
238 guint align = GST_MPP_ALIGNMENT;
239
240 if (!width || !height) {
241 GST_ERROR_OBJECT (self, "invalid input video info");
242 return FALSE;
243 }
244
245 if (!pclass->set_format (decoder, state))
246 return FALSE;
247
248 /* Figure out original output format */
249 structure = gst_caps_get_structure (state->caps, 0);
250 src_format = gst_mpp_jpeg_dec_get_format (structure);
251 switch (src_format) {
252 case GST_VIDEO_FORMAT_NV12:
253 case GST_VIDEO_FORMAT_I420:
254 src_format = GST_VIDEO_FORMAT_NV12;
255 break;
256 case GST_VIDEO_FORMAT_UYVY:
257 case GST_VIDEO_FORMAT_Y42B:
258 case GST_VIDEO_FORMAT_NV16:
259 src_format = GST_VIDEO_FORMAT_NV16;
260 break;
261 default:
262 /* FIXME: Gst doesn't support semi-planar version of Y444/Y41B...etc */
263 src_format = GST_VIDEO_FORMAT_UNKNOWN;
264 break;
265 }
266
267 /* Figure out final output info */
268 gst_mpp_dec_fixup_video_info (decoder, src_format, width, height);
269 dst_format = GST_VIDEO_INFO_FORMAT (info);
270 dst_width = GST_VIDEO_INFO_WIDTH (info);
271 dst_height = GST_VIDEO_INFO_HEIGHT (info);
272
273 /* Prefer MPP internal format conversion (PP) */
274 if (src_format != dst_format) {
275 GstVideoFormat pp_format = GST_VIDEO_FORMAT_UNKNOWN;
276
277 if (src_format == GST_VIDEO_FORMAT_UNKNOWN) {
278 /* PP conversion is required for unknown formats */
279 pp_format = gst_mpp_jpeg_dec_try_pp_convert (decoder, dst_format, TRUE);
280 if (pp_format == GST_VIDEO_FORMAT_UNKNOWN) {
281 GST_ERROR_OBJECT (self, "unsupported video format");
282 return FALSE;
283 }
284 } else if (dst_width == width && dst_height == height) {
285 /* Prefer PP conversion */
286 pp_format = gst_mpp_jpeg_dec_try_pp_convert (decoder, dst_format, TRUE);
287 }
288
289 /* MPP is going to provide the converted format */
290 if (pp_format != GST_VIDEO_FORMAT_UNKNOWN)
291 src_format = pp_format;
292 }
293
294 if (dst_format != src_format || dst_width != width || dst_height != height) {
295 /* Conversion required */
296 GST_INFO_OBJECT (self, "convert from %s (%dx%d) to %s (%dx%d)",
297 gst_mpp_video_format_to_string (src_format), width, height,
298 gst_mpp_video_format_to_string (dst_format), dst_width, dst_height);
299
300 align = 0;
301 }
302
303 /* Original output buffer size calculation */
304 gst_mpp_video_info_update_format (info, src_format, width, height);
305 if (!gst_mpp_video_info_align (info, 0, 0))
306 return FALSE;
307
308 self->buf_size = GST_VIDEO_INFO_SIZE (info);
309
310 /* FIXME: Workaround MPP's JPEG parser size requirement issue (w * h * 2) */
311 self->buf_size =
312 MAX (self->buf_size, GST_VIDEO_INFO_PLANE_OFFSET (info, 1) * 2);
313
314 /* Update final output info */
315 return gst_mpp_dec_update_simple_video_info (decoder, dst_format,
316 dst_width, dst_height, align);
317 }
318
319 static MppPacket
gst_mpp_jpeg_dec_get_mpp_packet(GstVideoDecoder * decoder,GstMapInfo * mapinfo)320 gst_mpp_jpeg_dec_get_mpp_packet (GstVideoDecoder * decoder,
321 GstMapInfo * mapinfo)
322 {
323 GstMppJpegDec *self = GST_MPP_JPEG_DEC (decoder);
324 MppBuffer mbuf = NULL;
325 MppPacket mpkt = NULL;
326
327 mpp_buffer_get (self->input_group, &mbuf, mapinfo->size);
328 if (G_UNLIKELY (!mbuf))
329 return NULL;
330
331 /* FIXME: performance bad */
332 memcpy (mpp_buffer_get_ptr (mbuf), mapinfo->data, mapinfo->size);
333
334 mpp_packet_init_with_buffer (&mpkt, mbuf);
335 mpp_buffer_put (mbuf);
336 if (G_UNLIKELY (!mpkt))
337 return NULL;
338
339 mpp_packet_set_size (mpkt, mapinfo->size);
340 mpp_packet_set_length (mpkt, mapinfo->size);
341
342 return mpkt;
343 }
344
345 static gboolean
gst_mpp_jpeg_dec_send_mpp_packet(GstVideoDecoder * decoder,MppPacket mpkt,gint timeout_ms)346 gst_mpp_jpeg_dec_send_mpp_packet (GstVideoDecoder * decoder,
347 MppPacket mpkt, gint timeout_ms)
348 {
349 GstMppJpegDec *self = GST_MPP_JPEG_DEC (decoder);
350 GstMppDec *mppdec = GST_MPP_DEC (decoder);
351 MppBuffer mbuf;
352 MppFrame mframe = NULL;
353 MppTask mtask = NULL;
354 MppMeta meta;
355
356 mppdec->mpi->poll (mppdec->mpp_ctx, MPP_PORT_INPUT, timeout_ms);
357 mppdec->mpi->dequeue (mppdec->mpp_ctx, MPP_PORT_INPUT, &mtask);
358 if (G_UNLIKELY (!mtask))
359 goto error;
360
361 mpp_task_meta_set_packet (mtask, KEY_INPUT_PACKET, mpkt);
362
363 mbuf = gst_mpp_allocator_alloc_mppbuf (mppdec->allocator, self->buf_size);
364 if (G_UNLIKELY (!mbuf))
365 goto error;
366
367 mpp_frame_init (&mframe);
368 mpp_frame_set_buffer (mframe, mbuf);
369 mpp_buffer_put (mbuf);
370
371 meta = mpp_frame_get_meta (mframe);
372 mpp_meta_set_packet (meta, KEY_INPUT_PACKET, mpkt);
373
374 mpp_task_meta_set_frame (mtask, KEY_OUTPUT_FRAME, mframe);
375
376 if (mppdec->mpi->enqueue (mppdec->mpp_ctx, MPP_PORT_INPUT, mtask))
377 goto error;
378
379 return TRUE;
380
381 error:
382 if (mtask) {
383 mpp_task_meta_set_packet (mtask, KEY_INPUT_PACKET, NULL);
384 mpp_task_meta_set_frame (mtask, KEY_OUTPUT_FRAME, NULL);
385 mppdec->mpi->enqueue (mppdec->mpp_ctx, MPP_PORT_INPUT, mtask);
386 }
387
388 if (mframe)
389 mpp_frame_deinit (&mframe);
390
391 return FALSE;
392 }
393
394 static MppFrame
gst_mpp_jpeg_dec_poll_mpp_frame(GstVideoDecoder * decoder,gint timeout_ms)395 gst_mpp_jpeg_dec_poll_mpp_frame (GstVideoDecoder * decoder, gint timeout_ms)
396 {
397 GstMppDec *mppdec = GST_MPP_DEC (decoder);
398 MppPacket mpkt = NULL;
399 MppTask mtask = NULL;
400 MppFrame mframe = NULL;
401 MppMeta meta;
402
403 if (mppdec->mpi->poll (mppdec->mpp_ctx, MPP_PORT_OUTPUT, timeout_ms))
404 return NULL;
405
406 mppdec->mpi->dequeue (mppdec->mpp_ctx, MPP_PORT_OUTPUT, &mtask);
407 if (!mtask)
408 return NULL;
409
410 mpp_task_meta_get_frame (mtask, KEY_OUTPUT_FRAME, &mframe);
411 if (!mframe) {
412 mppdec->mpi->enqueue (mppdec->mpp_ctx, MPP_PORT_OUTPUT, mtask);
413 return NULL;
414 }
415
416 meta = mpp_frame_get_meta (mframe);
417 mpp_meta_get_packet (meta, KEY_INPUT_PACKET, &mpkt);
418 if (mpkt)
419 mpp_packet_deinit (&mpkt);
420
421 mppdec->mpi->enqueue (mppdec->mpp_ctx, MPP_PORT_OUTPUT, mtask);
422
423 return mframe;
424 }
425
426 static gboolean
gst_mpp_jpeg_dec_shutdown(GstVideoDecoder * decoder,gboolean drain UNUSED)427 gst_mpp_jpeg_dec_shutdown (GstVideoDecoder * decoder, gboolean drain UNUSED)
428 {
429 GstMppJpegDec *self = GST_MPP_JPEG_DEC (decoder);
430 GstMppDec *mppdec = GST_MPP_DEC (decoder);
431 MppFrame mframe = NULL;
432 MppTask mtask = NULL;
433
434 GST_DEBUG_OBJECT (self, "sending EOS");
435
436 mppdec->mpi->poll (mppdec->mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
437 mppdec->mpi->dequeue (mppdec->mpp_ctx, MPP_PORT_INPUT, &mtask);
438 if (!mtask)
439 goto error;
440
441 mpp_task_meta_set_packet (mtask, KEY_INPUT_PACKET, self->eos_packet);
442
443 mpp_frame_init (&mframe);
444 if (!mframe)
445 goto error;
446
447 mpp_task_meta_set_frame (mtask, KEY_OUTPUT_FRAME, mframe);
448
449 if (mppdec->mpi->enqueue (mppdec->mpp_ctx, MPP_PORT_INPUT, mtask))
450 goto error;
451
452 return TRUE;
453
454 error:
455 GST_WARNING_OBJECT (self, "failed to send EOS");
456
457 if (mtask) {
458 mpp_task_meta_set_packet (mtask, KEY_INPUT_PACKET, NULL);
459 mpp_task_meta_set_frame (mtask, KEY_OUTPUT_FRAME, NULL);
460 mppdec->mpi->enqueue (mppdec->mpp_ctx, MPP_PORT_INPUT, mtask);
461 }
462
463 if (mframe)
464 mpp_frame_deinit (&mframe);
465
466 return FALSE;
467 }
468
469 #define GST_TYPE_MPP_JPEG_DEC_FORMAT (gst_mpp_jpeg_dec_format_get_type ())
470 static GType
gst_mpp_jpeg_dec_format_get_type(void)471 gst_mpp_jpeg_dec_format_get_type (void)
472 {
473 static GType format = 0;
474
475 if (!format) {
476 static const GEnumValue formats[] = {
477 {GST_VIDEO_FORMAT_UNKNOWN, "Auto", "auto"},
478 {GST_VIDEO_FORMAT_NV12, "NV12", "NV12"},
479 #ifdef HAVE_RGA
480 {GST_VIDEO_FORMAT_NV21, "NV21", "NV21"},
481 {GST_VIDEO_FORMAT_I420, "I420", "I420"},
482 {GST_VIDEO_FORMAT_YV12, "YV12", "YV12"},
483 {GST_VIDEO_FORMAT_NV16, "NV16", "NV16"},
484 {GST_VIDEO_FORMAT_NV61, "NV61", "NV61"},
485 {GST_VIDEO_FORMAT_RGB, "RGB", "RGB"},
486 {GST_VIDEO_FORMAT_BGR, "BGR", "BGR"},
487 #endif
488 {GST_VIDEO_FORMAT_RGB16, "RGB565", "RGB16"},
489 {GST_VIDEO_FORMAT_BGR16, "BGR565", "BGR16"},
490 {GST_VIDEO_FORMAT_ARGB, "ARGB8888", "ARGB"},
491 {GST_VIDEO_FORMAT_ABGR, "ABGR8888", "ABGR"},
492 {GST_VIDEO_FORMAT_RGBA, "RGBA8888", "RGBA"},
493 {GST_VIDEO_FORMAT_BGRA, "BGRA8888", "BGRA"},
494 {GST_VIDEO_FORMAT_xRGB, "XRGB8888", "xRGB"},
495 {GST_VIDEO_FORMAT_xBGR, "XBGR8888", "xBGR"},
496 {GST_VIDEO_FORMAT_RGBx, "RGBX8888", "RGBx"},
497 {GST_VIDEO_FORMAT_BGRx, "BGRX8888", "BGRx"},
498 {0, NULL, NULL}
499 };
500 format = g_enum_register_static ("GstMppJpegDecFormat", formats);
501 }
502 return format;
503 }
504
505 static void
gst_mpp_jpeg_dec_init(GstMppJpegDec * self)506 gst_mpp_jpeg_dec_init (GstMppJpegDec * self)
507 {
508 GstMppDec *mppdec = GST_MPP_DEC (self);
509 mppdec->format = DEFAULT_PROP_FORMAT;
510 }
511
512 static void
gst_mpp_jpeg_dec_setup_default_format(void)513 gst_mpp_jpeg_dec_setup_default_format (void)
514 {
515 GEnumClass *class;
516 GEnumValue *value;
517 const gchar *env;
518
519 env = g_getenv ("GST_MPP_JPEGDEC_DEFAULT_FORMAT");
520 if (!env)
521 return;
522
523 class = g_type_class_ref (GST_TYPE_MPP_JPEG_DEC_FORMAT);
524
525 value = g_enum_get_value_by_nick (class, env);
526 if (value)
527 DEFAULT_PROP_FORMAT = value->value;
528
529 g_type_class_unref (class);
530 }
531
532 static void
gst_mpp_jpeg_dec_class_init(GstMppJpegDecClass * klass)533 gst_mpp_jpeg_dec_class_init (GstMppJpegDecClass * klass)
534 {
535 GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
536 GstMppDecClass *pclass = GST_MPP_DEC_CLASS (klass);
537 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
538 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
539
540 GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "mppjpegdec", 0,
541 "MPP JPEG decoder");
542
543 decoder_class->start = GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_start);
544 decoder_class->stop = GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_stop);
545 decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_set_format);
546
547 pclass->startup = NULL;
548 pclass->get_mpp_packet = GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_get_mpp_packet);
549 pclass->send_mpp_packet =
550 GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_send_mpp_packet);
551 pclass->poll_mpp_frame = GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_poll_mpp_frame);
552 pclass->shutdown = GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_shutdown);
553
554 gobject_class->set_property =
555 GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_set_property);
556 gobject_class->get_property =
557 GST_DEBUG_FUNCPTR (gst_mpp_jpeg_dec_get_property);
558
559 gst_mpp_jpeg_dec_setup_default_format ();
560
561 g_object_class_install_property (gobject_class, PROP_FORMAT,
562 g_param_spec_enum ("format", "Prefered output format",
563 "Prefered output format",
564 GST_TYPE_MPP_JPEG_DEC_FORMAT, DEFAULT_PROP_FORMAT,
565 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
566
567 gst_element_class_add_pad_template (element_class,
568 gst_static_pad_template_get (&gst_mpp_jpeg_dec_src_template));
569
570 gst_element_class_add_pad_template (element_class,
571 gst_static_pad_template_get (&gst_mpp_jpeg_dec_sink_template));
572
573 gst_element_class_set_static_metadata (element_class,
574 "Rockchip's MPP JPEG image decoder", "Decoder/Image",
575 "JPEG hardware decoder",
576 "Randy Li <randy.li@rock-chips.com>, "
577 "Jeffy Chen <jeffy.chen@rock-chips.com>");
578 }
579
580 gboolean
gst_mpp_jpeg_dec_register(GstPlugin * plugin,guint rank)581 gst_mpp_jpeg_dec_register (GstPlugin * plugin, guint rank)
582 {
583 return gst_element_register (plugin, "mppjpegdec", rank,
584 gst_mpp_jpeg_dec_get_type ());
585 }
586