b50b4754f8d38316e661dd9fcc28cc08a8cce9c2
[platform/upstream/gstreamer.git] / ext / mpeg2dec / gstmpeg2dec.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include <string.h>
24
25 #include <inttypes.h>
26
27 #include "gstmpeg2dec.h"
28
29 #include <gst/video/gstvideometa.h>
30 #include <gst/video/gstvideopool.h>
31
32 /* 16byte-aligns a buffer for libmpeg2 */
33 #define ALIGN_16(p) ((void *)(((uintptr_t)(p) + 15) & ~((uintptr_t)15)))
34
35 /* mpeg2dec changed a struct name after 0.3.1, here's a workaround */
36 /* mpeg2dec also only defined MPEG2_RELEASE after 0.3.1
37    #if MPEG2_RELEASE < MPEG2_VERSION(0,3,2)
38 */
39 #ifndef MPEG2_RELEASE
40 #define MPEG2_VERSION(a,b,c) ((((a)&0xff)<<16)|(((b)&0xff)<<8)|((c)&0xff))
41 #define MPEG2_RELEASE MPEG2_VERSION(0,3,1)
42 typedef picture_t mpeg2_picture_t;
43 typedef gint mpeg2_state_t;
44
45 #define STATE_BUFFER 0
46 #endif
47
48 GST_DEBUG_CATEGORY_STATIC (mpeg2dec_debug);
49 #define GST_CAT_DEFAULT (mpeg2dec_debug)
50 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
51
52 /* Send a warning message about decoding errors after receiving this many
53  * STATE_INVALID return values from mpeg2_parse. -1 means never.
54  */
55 #define WARN_THRESHOLD (5)
56
57 static GstStaticPadTemplate sink_template_factory =
58 GST_STATIC_PAD_TEMPLATE ("sink",
59     GST_PAD_SINK,
60     GST_PAD_ALWAYS,
61     GST_STATIC_CAPS ("video/mpeg, "
62         "mpegversion = (int) [ 1, 2 ], " "systemstream = (boolean) false")
63     );
64
65 static GstStaticPadTemplate src_template_factory =
66 GST_STATIC_PAD_TEMPLATE ("src",
67     GST_PAD_SRC,
68     GST_PAD_ALWAYS,
69     GST_STATIC_CAPS ("video/x-raw, "
70         "format = (string) { YV12, I420, Y42B, Y444 }, "
71         "width = (int) [ 16, 4096 ], "
72         "height = (int) [ 16, 4096 ], "
73         "framerate = (fraction) [ 0/1, 2147483647/1 ]")
74     );
75
76 #define gst_mpeg2dec_parent_class parent_class
77 G_DEFINE_TYPE (GstMpeg2dec, gst_mpeg2dec, GST_TYPE_VIDEO_DECODER);
78
79 static void gst_mpeg2dec_finalize (GObject * object);
80
81 /* GstVideoDecoder base class method */
82 static gboolean gst_mpeg2dec_open (GstVideoDecoder * decoder);
83 static gboolean gst_mpeg2dec_close (GstVideoDecoder * decoder);
84 static gboolean gst_mpeg2dec_start (GstVideoDecoder * decoder);
85 static gboolean gst_mpeg2dec_stop (GstVideoDecoder * decoder);
86 static gboolean gst_mpeg2dec_set_format (GstVideoDecoder * decoder,
87     GstVideoCodecState * state);
88 static gboolean gst_mpeg2dec_flush (GstVideoDecoder * decoder);
89 static GstFlowReturn gst_mpeg2dec_finish (GstVideoDecoder * decoder);
90 static GstFlowReturn gst_mpeg2dec_handle_frame (GstVideoDecoder * decoder,
91     GstVideoCodecFrame * frame);
92 static gboolean gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder,
93     GstQuery * query);
94
95 static void gst_mpeg2dec_clear_buffers (GstMpeg2dec * mpeg2dec);
96 static gboolean gst_mpeg2dec_crop_buffer (GstMpeg2dec * dec,
97     GstVideoCodecFrame * in_frame, GstVideoFrame * in_vframe);
98
99 static void
100 gst_mpeg2dec_class_init (GstMpeg2decClass * klass)
101 {
102   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
103   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
104   GstVideoDecoderClass *video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);
105
106   gobject_class->finalize = gst_mpeg2dec_finalize;
107
108   gst_element_class_add_pad_template (element_class,
109       gst_static_pad_template_get (&src_template_factory));
110   gst_element_class_add_pad_template (element_class,
111       gst_static_pad_template_get (&sink_template_factory));
112   gst_element_class_set_static_metadata (element_class,
113       "mpeg1 and mpeg2 video decoder", "Codec/Decoder/Video",
114       "Uses libmpeg2 to decode MPEG video streams",
115       "Wim Taymans <wim.taymans@chello.be>");
116
117   video_decoder_class->open = GST_DEBUG_FUNCPTR (gst_mpeg2dec_open);
118   video_decoder_class->close = GST_DEBUG_FUNCPTR (gst_mpeg2dec_close);
119   video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_mpeg2dec_start);
120   video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg2dec_stop);
121   video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_mpeg2dec_flush);
122   video_decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_mpeg2dec_set_format);
123   video_decoder_class->handle_frame =
124       GST_DEBUG_FUNCPTR (gst_mpeg2dec_handle_frame);
125   video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_mpeg2dec_finish);
126   video_decoder_class->decide_allocation =
127       GST_DEBUG_FUNCPTR (gst_mpeg2dec_decide_allocation);
128
129   GST_DEBUG_CATEGORY_INIT (mpeg2dec_debug, "mpeg2dec", 0,
130       "MPEG-2 Video Decoder");
131 }
132
133 static void
134 gst_mpeg2dec_init (GstMpeg2dec * mpeg2dec)
135 {
136   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (mpeg2dec), TRUE);
137   gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (mpeg2dec), TRUE);
138
139   /* initialize the mpeg2dec acceleration */
140 }
141
142 static void
143 gst_mpeg2dec_finalize (GObject * object)
144 {
145   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (object);
146
147   if (mpeg2dec->decoder) {
148     GST_DEBUG_OBJECT (mpeg2dec, "closing decoder");
149     mpeg2_close (mpeg2dec->decoder);
150     mpeg2dec->decoder = NULL;
151   }
152
153   gst_mpeg2dec_clear_buffers (mpeg2dec);
154   g_free (mpeg2dec->dummybuf[3]);
155   mpeg2dec->dummybuf[3] = NULL;
156
157   G_OBJECT_CLASS (parent_class)->finalize (object);
158 }
159
160 static gboolean
161 gst_mpeg2dec_open (GstVideoDecoder * decoder)
162 {
163   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
164
165   mpeg2_accel (MPEG2_ACCEL_DETECT);
166   if ((mpeg2dec->decoder = mpeg2_init ()) == NULL)
167     return FALSE;
168   mpeg2dec->info = mpeg2_info (mpeg2dec->decoder);
169
170   return TRUE;
171 }
172
173 static gboolean
174 gst_mpeg2dec_close (GstVideoDecoder * decoder)
175 {
176   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
177
178   if (mpeg2dec->decoder) {
179     mpeg2_close (mpeg2dec->decoder);
180     mpeg2dec->decoder = NULL;
181     mpeg2dec->info = NULL;
182   }
183   gst_mpeg2dec_clear_buffers (mpeg2dec);
184
185   return TRUE;
186 }
187
188 static gboolean
189 gst_mpeg2dec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
190 {
191   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
192
193   /* Save input state to be used as reference for output state */
194   if (mpeg2dec->input_state)
195     gst_video_codec_state_unref (mpeg2dec->input_state);
196   mpeg2dec->input_state = gst_video_codec_state_ref (state);
197
198   return TRUE;
199 }
200
201 static gboolean
202 gst_mpeg2dec_start (GstVideoDecoder * decoder)
203 {
204   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
205
206   mpeg2dec->discont_state = MPEG2DEC_DISC_NEW_PICTURE;
207
208   return TRUE;
209 }
210
211 static gboolean
212 gst_mpeg2dec_stop (GstVideoDecoder * decoder)
213 {
214   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
215
216   mpeg2_reset (mpeg2dec->decoder, 0);
217   mpeg2_skip (mpeg2dec->decoder, 1);
218
219   gst_mpeg2dec_clear_buffers (mpeg2dec);
220
221   if (mpeg2dec->input_state)
222     gst_video_codec_state_unref (mpeg2dec->input_state);
223   mpeg2dec->input_state = NULL;
224
225   return TRUE;
226 }
227
228 static gboolean
229 gst_mpeg2dec_flush (GstVideoDecoder * decoder)
230 {
231   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
232
233   /* reset the initial video state */
234   mpeg2dec->discont_state = MPEG2DEC_DISC_NEW_PICTURE;
235   mpeg2_reset (mpeg2dec->decoder, 1);
236   mpeg2_skip (mpeg2dec->decoder, 1);
237
238   gst_mpeg2dec_clear_buffers (mpeg2dec);
239
240   return TRUE;
241 }
242
243 static GstFlowReturn
244 gst_mpeg2dec_finish (GstVideoDecoder * decoder)
245 {
246   return GST_FLOW_OK;
247 }
248
249 static gboolean
250 gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
251 {
252   GstMpeg2dec *dec = GST_MPEG2DEC (decoder);
253   GstVideoCodecState *state;
254   GstBufferPool *pool;
255   guint size, min, max;
256   GstStructure *config;
257   GstAllocator *allocator;
258   GstAllocationParams params;
259   gboolean update_allocator;
260
261   /* Set allocation parameters to guarantee 16-byte aligned output buffers */
262   if (gst_query_get_n_allocation_params (query) > 0) {
263     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
264     update_allocator = TRUE;
265   } else {
266     allocator = NULL;
267     gst_allocation_params_init (&params);
268     update_allocator = FALSE;
269   }
270
271   params.align = MAX (params.align, 15);
272
273   if (update_allocator)
274     gst_query_set_nth_allocation_param (query, 0, allocator, &params);
275   else
276     gst_query_add_allocation_param (query, allocator, &params);
277   if (allocator)
278     gst_object_unref (allocator);
279
280   /* Now chain up to the parent class to guarantee that we can
281    * get a buffer pool from the query */
282   if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder,
283           query))
284     return FALSE;
285
286   state = gst_video_decoder_get_output_state (decoder);
287
288   gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
289
290   dec->has_cropping = FALSE;
291   config = gst_buffer_pool_get_config (pool);
292   if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
293     gst_buffer_pool_config_add_option (config,
294         GST_BUFFER_POOL_OPTION_VIDEO_META);
295     dec->has_cropping =
296         gst_query_find_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE,
297         NULL);
298   }
299
300   if (dec->has_cropping) {
301     GstCaps *caps;
302
303     /* Calculate uncropped size */
304     size = MAX (size, dec->decoded_info.size);
305     caps = gst_video_info_to_caps (&dec->decoded_info);
306     gst_buffer_pool_config_set_params (config, caps, size, min, max);
307     gst_caps_unref (caps);
308   }
309
310   gst_buffer_pool_set_config (pool, config);
311
312   gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
313
314   gst_object_unref (pool);
315   gst_video_codec_state_unref (state);
316
317   return TRUE;
318 }
319
320 static GstFlowReturn
321 gst_mpeg2dec_crop_buffer (GstMpeg2dec * dec, GstVideoCodecFrame * in_frame,
322     GstVideoFrame * input_vframe)
323 {
324   GstVideoCodecState *state;
325   GstVideoInfo *info;
326   GstVideoInfo *dinfo;
327   guint c, n_planes;
328   GstVideoFrame output_frame;
329   GstFlowReturn ret;
330
331   state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (dec));
332   info = &state->info;
333   dinfo = &dec->decoded_info;
334
335   GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
336       "Copying input buffer %ux%u (%" G_GSIZE_FORMAT ") to output buffer "
337       "%ux%u (%" G_GSIZE_FORMAT ")", dinfo->width, dinfo->height,
338       dinfo->size, info->width, info->height, info->size);
339
340   ret =
341       gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (dec),
342       in_frame);
343   if (ret != GST_FLOW_OK)
344     goto beach;
345
346   if (!gst_video_frame_map (&output_frame, info, in_frame->output_buffer,
347           GST_MAP_WRITE))
348     goto map_fail;
349
350   n_planes = GST_VIDEO_FRAME_N_PLANES (&output_frame);
351   for (c = 0; c < n_planes; c++) {
352     guint w, h, j;
353     guint8 *sp, *dp;
354     gint ss, ds;
355
356     sp = GST_VIDEO_FRAME_PLANE_DATA (input_vframe, c);
357     dp = GST_VIDEO_FRAME_PLANE_DATA (&output_frame, c);
358
359     ss = GST_VIDEO_FRAME_PLANE_STRIDE (input_vframe, c);
360     ds = GST_VIDEO_FRAME_PLANE_STRIDE (&output_frame, c);
361
362     w = MIN (ABS (ss), ABS (ds));
363     h = GST_VIDEO_FRAME_COMP_HEIGHT (&output_frame, c);
364
365     GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy plane %u, w:%u h:%u ", c, w, h);
366
367     for (j = 0; j < h; j++) {
368       memcpy (dp, sp, w);
369       dp += ds;
370       sp += ss;
371     }
372   }
373
374   gst_video_frame_unmap (&output_frame);
375
376   GST_BUFFER_FLAGS (in_frame->output_buffer) =
377       GST_BUFFER_FLAGS (input_vframe->buffer);
378
379 beach:
380   gst_video_codec_state_unref (state);
381
382   return ret;
383
384 map_fail:
385   {
386     GST_ERROR_OBJECT (dec, "Failed to map output frame");
387     gst_video_codec_state_unref (state);
388     return GST_FLOW_ERROR;
389   }
390 }
391
392 static void
393 frame_user_data_destroy_notify (GstBuffer * buf)
394 {
395   GST_DEBUG ("Releasing buffer %p", buf);
396   if (buf)
397     gst_buffer_unref (buf);
398 }
399
400 static GstFlowReturn
401 gst_mpeg2dec_alloc_sized_buf (GstMpeg2dec * mpeg2dec, guint size,
402     GstVideoCodecFrame * frame, GstBuffer ** buffer)
403 {
404   GstFlowReturn ret = GST_FLOW_OK;
405   GstVideoCodecState *state;
406
407   state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (mpeg2dec));
408
409   if (!mpeg2dec->need_cropping || mpeg2dec->has_cropping) {
410     /* need parsed input, but that might be slightly bogus,
411      * so avoid giving up altogether and mark it as error */
412     if (frame->output_buffer) {
413       gst_buffer_replace (&frame->output_buffer, NULL);
414       GST_VIDEO_DECODER_ERROR (mpeg2dec, 1, STREAM, DECODE,
415           ("decoding error"), ("Input not correctly parsed"), ret);
416     }
417     ret =
418         gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (mpeg2dec),
419         frame);
420     *buffer = frame->output_buffer;
421   } else {
422     GstAllocationParams params = { 0, 15, 0, 0 };
423
424     *buffer = gst_buffer_new_allocate (NULL, size, &params);
425     gst_video_codec_frame_set_user_data (frame, *buffer,
426         (GDestroyNotify) frame_user_data_destroy_notify);
427   }
428
429   gst_video_codec_state_unref (state);
430
431   return ret;
432 }
433
434 typedef struct
435 {
436   gint id;
437   GstVideoFrame frame;
438 } GstMpeg2DecBuffer;
439
440 static void
441 gst_mpeg2dec_clear_buffers (GstMpeg2dec * mpeg2dec)
442 {
443   GList *l;
444   while ((l = g_list_first (mpeg2dec->buffers))) {
445     GstMpeg2DecBuffer *mbuf = l->data;
446     gst_video_frame_unmap (&mbuf->frame);
447     g_slice_free (GstMpeg2DecBuffer, mbuf);
448     mpeg2dec->buffers = g_list_delete_link (mpeg2dec->buffers, l);
449   }
450 }
451
452 static void
453 gst_mpeg2dec_save_buffer (GstMpeg2dec * mpeg2dec, gint id,
454     GstVideoFrame * frame)
455 {
456   GstMpeg2DecBuffer *mbuf;
457
458   GST_LOG_OBJECT (mpeg2dec, "Saving local info for frame %d", id);
459
460   mbuf = g_slice_new0 (GstMpeg2DecBuffer);
461   mbuf->id = id;
462   mbuf->frame = *frame;
463
464   mpeg2dec->buffers = g_list_prepend (mpeg2dec->buffers, mbuf);
465 }
466
467 static gint
468 gst_mpeg2dec_buffer_compare (GstMpeg2DecBuffer * mbuf, gconstpointer id)
469 {
470   if (mbuf->id == GPOINTER_TO_INT (id))
471     return 0;
472   return -1;
473 }
474
475 static void
476 gst_mpeg2dec_discard_buffer (GstMpeg2dec * mpeg2dec, gint id)
477 {
478   GList *l = g_list_find_custom (mpeg2dec->buffers, GINT_TO_POINTER (id),
479       (GCompareFunc) gst_mpeg2dec_buffer_compare);
480
481   if (l) {
482     GstMpeg2DecBuffer *mbuf = l->data;
483     gst_video_frame_unmap (&mbuf->frame);
484     g_slice_free (GstMpeg2DecBuffer, mbuf);
485     mpeg2dec->buffers = g_list_delete_link (mpeg2dec->buffers, l);
486     GST_LOG_OBJECT (mpeg2dec, "Discarded local info for frame %d", id);
487   } else {
488     GST_WARNING ("Could not find buffer %d, will be leaked until next reset",
489         id);
490   }
491 }
492
493 static GstVideoFrame *
494 gst_mpeg2dec_get_buffer (GstMpeg2dec * mpeg2dec, gint id)
495 {
496   GList *l = g_list_find_custom (mpeg2dec->buffers, GINT_TO_POINTER (id),
497       (GCompareFunc) gst_mpeg2dec_buffer_compare);
498
499   if (l) {
500     GstMpeg2DecBuffer *mbuf = l->data;
501     return &mbuf->frame;
502   }
503
504   return NULL;
505 }
506
507 static GstFlowReturn
508 gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, GstVideoCodecFrame * frame,
509     GstBuffer ** buffer)
510 {
511   GstFlowReturn ret;
512   GstVideoFrame vframe;
513   guint8 *buf[3];
514
515   ret =
516       gst_mpeg2dec_alloc_sized_buf (mpeg2dec, mpeg2dec->decoded_info.size,
517       frame, buffer);
518   if (G_UNLIKELY (ret != GST_FLOW_OK))
519     goto beach;
520
521   if (mpeg2dec->need_cropping && mpeg2dec->has_cropping) {
522     GstVideoCropMeta *crop;
523     GstVideoCodecState *state;
524     GstVideoInfo *vinfo;
525
526     state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (mpeg2dec));
527     vinfo = &state->info;
528
529     crop = gst_buffer_add_video_crop_meta (frame->output_buffer);
530     /* we can do things slightly more efficient when we know that
531      * downstream understands clipping */
532     crop->x = 0;
533     crop->y = 0;
534     crop->width = vinfo->width;
535     crop->height = vinfo->height;
536
537     gst_video_codec_state_unref (state);
538   }
539
540   if (!gst_video_frame_map (&vframe, &mpeg2dec->decoded_info, *buffer,
541           GST_MAP_READ | GST_MAP_WRITE))
542     goto map_fail;
543
544   buf[0] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
545   buf[1] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
546   buf[2] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
547
548   GST_DEBUG_OBJECT (mpeg2dec, "set_buf: %p %p %p, frame %i",
549       buf[0], buf[1], buf[2], frame->system_frame_number);
550
551   /* Note: We use a non-null 'id' value to make the distinction
552    * between the dummy buffers (which have an id of NULL) and the
553    * ones we did */
554   mpeg2_set_buf (mpeg2dec->decoder, buf,
555       GINT_TO_POINTER (frame->system_frame_number + 1));
556   gst_mpeg2dec_save_buffer (mpeg2dec, frame->system_frame_number, &vframe);
557
558 beach:
559   return ret;
560
561 map_fail:
562   {
563     GST_ERROR_OBJECT (mpeg2dec, "Failed to map frame");
564     return GST_FLOW_ERROR;
565   }
566 }
567
568 static void
569 init_dummybuf (GstMpeg2dec * mpeg2dec)
570 {
571   g_free (mpeg2dec->dummybuf[3]);
572
573   /* libmpeg2 needs 16 byte aligned buffers... care for this here */
574   mpeg2dec->dummybuf[3] = g_malloc0 (mpeg2dec->decoded_info.size + 15);
575   mpeg2dec->dummybuf[0] = ALIGN_16 (mpeg2dec->dummybuf[3]);
576   mpeg2dec->dummybuf[1] =
577       mpeg2dec->dummybuf[0] +
578       GST_VIDEO_INFO_PLANE_OFFSET (&mpeg2dec->decoded_info, 1);
579   mpeg2dec->dummybuf[2] =
580       mpeg2dec->dummybuf[0] +
581       GST_VIDEO_INFO_PLANE_OFFSET (&mpeg2dec->decoded_info, 2);
582 }
583
584 static GstFlowReturn
585 handle_sequence (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
586 {
587   GstFlowReturn ret = GST_FLOW_OK;
588   GstClockTime latency;
589   const mpeg2_sequence_t *sequence;
590   GstVideoCodecState *state;
591   GstVideoInfo *dinfo = &mpeg2dec->decoded_info;
592   GstVideoInfo *vinfo;
593   GstVideoInfo pre_crop_info;
594   GstVideoFormat format;
595
596   sequence = info->sequence;
597
598   if (sequence->frame_period == 0)
599     goto invalid_frame_period;
600
601   /* mpeg2 video can only be from 16x16 to 4096x4096. Everything
602    * else is a corrupted file */
603   if (sequence->width > 4096 || sequence->width < 16 ||
604       sequence->height > 4096 || sequence->height < 16)
605     goto invalid_size;
606
607   GST_DEBUG_OBJECT (mpeg2dec,
608       "widthxheight: %dx%d , decoded_widthxheight: %dx%d",
609       sequence->picture_width, sequence->picture_height, sequence->width,
610       sequence->height);
611
612   if (sequence->picture_width != sequence->width ||
613       sequence->picture_height != sequence->height) {
614     GST_DEBUG_OBJECT (mpeg2dec, "we need to crop");
615     mpeg2dec->need_cropping = TRUE;
616   } else {
617     GST_DEBUG_OBJECT (mpeg2dec, "no cropping needed");
618     mpeg2dec->need_cropping = FALSE;
619   }
620
621   /* get subsampling */
622   if (sequence->chroma_width < sequence->width) {
623     /* horizontally subsampled */
624     if (sequence->chroma_height < sequence->height) {
625       /* and vertically subsamples */
626       format = GST_VIDEO_FORMAT_I420;
627     } else {
628       format = GST_VIDEO_FORMAT_Y42B;
629     }
630   } else {
631     /* not subsampled */
632     format = GST_VIDEO_FORMAT_Y444;
633   }
634
635   state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (mpeg2dec),
636       format, sequence->picture_width, sequence->picture_height,
637       mpeg2dec->input_state);
638   vinfo = &state->info;
639
640   /* If we don't have a valid upstream PAR override it */
641   if (GST_VIDEO_INFO_PAR_N (vinfo) == 1 &&
642       GST_VIDEO_INFO_PAR_D (vinfo) == 1 &&
643       sequence->pixel_width != 0 && sequence->pixel_height != 0) {
644 #if MPEG2_RELEASE >= MPEG2_VERSION(0,5,0)
645     guint pixel_width, pixel_height;
646     if (mpeg2_guess_aspect (sequence, &pixel_width, &pixel_height)) {
647       vinfo->par_n = pixel_width;
648       vinfo->par_d = pixel_height;
649     }
650 #else
651     vinfo->par_n = sequence->pixel_width;
652     vinfo->par_d = sequence->pixel_height;
653 #endif
654     GST_DEBUG_OBJECT (mpeg2dec, "Setting PAR %d x %d",
655         vinfo->par_n, vinfo->par_d);
656   }
657   vinfo->fps_n = 27000000;
658   vinfo->fps_d = sequence->frame_period;
659
660   if (!(sequence->flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE))
661     vinfo->interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
662   else
663     vinfo->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
664
665   vinfo->chroma_site = GST_VIDEO_CHROMA_SITE_MPEG2;
666   vinfo->colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
667
668   if (sequence->flags & SEQ_FLAG_COLOUR_DESCRIPTION) {
669     /* do color description */
670     switch (sequence->colour_primaries) {
671       case 1:
672         vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
673         break;
674       case 4:
675         vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
676         break;
677       case 5:
678         vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
679         break;
680       case 6:
681         vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
682         break;
683       case 7:
684         vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
685         break;
686         /* 0 forbidden */
687         /* 2 unspecified */
688         /* 3 reserved */
689         /* 8-255 reseved */
690       default:
691         vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
692         break;
693     }
694     /* matrix coefficients */
695     switch (sequence->matrix_coefficients) {
696       case 1:
697         vinfo->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
698         break;
699       case 4:
700         vinfo->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
701         break;
702       case 5:
703       case 6:
704         vinfo->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
705         break;
706       case 7:
707         vinfo->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
708         break;
709         /* 0 forbidden */
710         /* 2 unspecified */
711         /* 3 reserved */
712         /* 8-255 reseved */
713       default:
714         vinfo->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
715         break;
716     }
717     /* transfer characteristics */
718     switch (sequence->transfer_characteristics) {
719       case 1:
720         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
721         break;
722       case 4:
723         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
724         break;
725       case 5:
726         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
727         break;
728       case 6:
729         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
730         break;
731       case 7:
732         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
733         break;
734       case 8:
735         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
736         break;
737         /* 0 forbidden */
738         /* 2 unspecified */
739         /* 3 reserved */
740         /* 9-255 reseved */
741       default:
742         vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
743         break;
744     }
745   }
746
747   GST_DEBUG_OBJECT (mpeg2dec,
748       "sequence flags: %d, frame period: %d, frame rate: %d/%d",
749       sequence->flags, sequence->frame_period, vinfo->fps_n, vinfo->fps_d);
750   GST_DEBUG_OBJECT (mpeg2dec, "profile: %02x, colour_primaries: %d",
751       sequence->profile_level_id, sequence->colour_primaries);
752   GST_DEBUG_OBJECT (mpeg2dec, "transfer chars: %d, matrix coef: %d",
753       sequence->transfer_characteristics, sequence->matrix_coefficients);
754   GST_DEBUG_OBJECT (mpeg2dec,
755       "FLAGS: CONSTRAINED_PARAMETERS:%d, PROGRESSIVE_SEQUENCE:%d",
756       sequence->flags & SEQ_FLAG_CONSTRAINED_PARAMETERS,
757       sequence->flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE);
758   GST_DEBUG_OBJECT (mpeg2dec, "FLAGS: LOW_DELAY:%d, COLOUR_DESCRIPTION:%d",
759       sequence->flags & SEQ_FLAG_LOW_DELAY,
760       sequence->flags & SEQ_FLAG_COLOUR_DESCRIPTION);
761
762   /* we store the codec size before cropping */
763   *dinfo = *vinfo;
764   gst_video_info_set_format (&pre_crop_info, format, sequence->width,
765       sequence->height);
766   dinfo->width = sequence->width;
767   dinfo->height = sequence->height;
768   dinfo->size = pre_crop_info.size;
769   memcpy (dinfo->stride, pre_crop_info.stride, sizeof (pre_crop_info.stride));
770   memcpy (dinfo->offset, pre_crop_info.offset, sizeof (pre_crop_info.offset));
771
772   /* Mpeg2dec has 2 frame latency to produce a picture and 1 frame latency in
773    * it's parser */
774   latency = gst_util_uint64_scale (3, vinfo->fps_d, vinfo->fps_n);
775   gst_video_decoder_set_latency (GST_VIDEO_DECODER (mpeg2dec), latency,
776       latency);
777
778   if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (mpeg2dec)))
779     goto negotiation_fail;
780
781   gst_video_codec_state_unref (state);
782
783   mpeg2_custom_fbuf (mpeg2dec->decoder, 1);
784
785   init_dummybuf (mpeg2dec);
786
787   /* Pump in some null buffers, because otherwise libmpeg2 doesn't
788    * initialise the discard_fbuf->id */
789   mpeg2_set_buf (mpeg2dec->decoder, mpeg2dec->dummybuf, NULL);
790   mpeg2_set_buf (mpeg2dec->decoder, mpeg2dec->dummybuf, NULL);
791   mpeg2_set_buf (mpeg2dec->decoder, mpeg2dec->dummybuf, NULL);
792   gst_mpeg2dec_clear_buffers (mpeg2dec);
793
794   return ret;
795
796 invalid_frame_period:
797   {
798     GST_WARNING_OBJECT (mpeg2dec, "Frame period is 0!");
799     return GST_FLOW_ERROR;
800   }
801 invalid_size:
802   {
803     GST_ERROR_OBJECT (mpeg2dec, "Invalid frame dimensions: %d x %d",
804         sequence->width, sequence->height);
805     return GST_FLOW_ERROR;
806   }
807
808 negotiation_fail:
809   {
810     GST_WARNING_OBJECT (mpeg2dec, "Failed to negotiate with downstream");
811     return GST_FLOW_ERROR;
812   }
813 }
814
815 static GstFlowReturn
816 handle_picture (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
817     GstVideoCodecFrame * frame)
818 {
819   GstFlowReturn ret;
820   gint type;
821   const gchar *type_str = NULL;
822   gboolean key_frame = FALSE;
823   const mpeg2_picture_t *picture = info->current_picture;
824   GstBuffer *buffer;
825
826   ret = gst_mpeg2dec_alloc_buffer (mpeg2dec, frame, &buffer);
827   if (ret != GST_FLOW_OK)
828     return ret;
829
830   type = picture->flags & PIC_MASK_CODING_TYPE;
831   switch (type) {
832     case PIC_FLAG_CODING_TYPE_I:
833       key_frame = TRUE;
834       mpeg2_skip (mpeg2dec->decoder, 0);
835       type_str = "I";
836       break;
837     case PIC_FLAG_CODING_TYPE_P:
838       type_str = "P";
839       break;
840     case PIC_FLAG_CODING_TYPE_B:
841       type_str = "B";
842       break;
843     default:
844       gst_video_codec_frame_ref (frame);
845       ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
846       GST_VIDEO_DECODER_ERROR (mpeg2dec, 1, STREAM, DECODE,
847           ("decoding error"), ("Invalid picture type"), ret);
848       return ret;
849   }
850
851   GST_DEBUG_OBJECT (mpeg2dec, "handle picture type %s", type_str);
852   GST_DEBUG_OBJECT (mpeg2dec, "picture %s, frame %i",
853       key_frame ? ", kf," : "    ", frame->system_frame_number);
854
855   if (GST_VIDEO_INFO_IS_INTERLACED (&mpeg2dec->decoded_info)) {
856     /* This implies SEQ_FLAG_PROGRESSIVE_SEQUENCE is not set */
857     if (picture->flags & PIC_FLAG_TOP_FIELD_FIRST) {
858       GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_TFF);
859     }
860     if (!(picture->flags & PIC_FLAG_PROGRESSIVE_FRAME)) {
861       GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
862     }
863 #if MPEG2_RELEASE >= MPEG2_VERSION(0,5,0)
864     /* repeat field introduced in 0.5.0 */
865     if (picture->flags & PIC_FLAG_REPEAT_FIRST_FIELD) {
866       GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_RFF);
867     }
868 #endif
869   }
870
871   if (mpeg2dec->discont_state == MPEG2DEC_DISC_NEW_PICTURE && key_frame) {
872     mpeg2dec->discont_state = MPEG2DEC_DISC_NEW_KEYFRAME;
873   }
874
875   GST_DEBUG_OBJECT (mpeg2dec,
876       "picture: %s %s %s %s %s fields:%d ts:%"
877       GST_TIME_FORMAT,
878       (picture->flags & PIC_FLAG_PROGRESSIVE_FRAME ? "prog" : "    "),
879       (picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? "tff" : "   "),
880 #if MPEG2_RELEASE >= MPEG2_VERSION(0,5,0)
881       (picture->flags & PIC_FLAG_REPEAT_FIRST_FIELD ? "rff" : "   "),
882 #else
883       "unknown rff",
884 #endif
885       (picture->flags & PIC_FLAG_SKIP ? "skip" : "    "),
886       (picture->flags & PIC_FLAG_COMPOSITE_DISPLAY ? "composite" : "         "),
887       picture->nb_fields, GST_TIME_ARGS (frame->pts));
888
889   return ret;
890 }
891
892 static GstFlowReturn
893 handle_slice (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
894 {
895   GstFlowReturn ret = GST_FLOW_OK;
896   GstVideoCodecFrame *frame;
897   const mpeg2_picture_t *picture;
898   gboolean key_frame = FALSE;
899   GstVideoCodecState *state;
900
901   GST_DEBUG_OBJECT (mpeg2dec,
902       "fbuf:%p display_picture:%p current_picture:%p fbuf->id:%d",
903       info->display_fbuf, info->display_picture, info->current_picture,
904       GPOINTER_TO_INT (info->display_fbuf->id) - 1);
905
906   /* Note, the fbuf-id is shifted by 1 to make the difference between
907    * NULL values (used by dummy buffers) and 'real' values */
908   frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (mpeg2dec),
909       GPOINTER_TO_INT (info->display_fbuf->id) - 1);
910   if (!frame)
911     goto no_frame;
912   picture = info->display_picture;
913   key_frame = (picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_I;
914
915   GST_DEBUG_OBJECT (mpeg2dec, "picture flags: %d, type: %d, keyframe: %d",
916       picture->flags, picture->flags & PIC_MASK_CODING_TYPE, key_frame);
917
918   if (key_frame) {
919     mpeg2_skip (mpeg2dec->decoder, 0);
920   }
921
922   if (mpeg2dec->discont_state == MPEG2DEC_DISC_NEW_KEYFRAME && key_frame)
923     mpeg2dec->discont_state = MPEG2DEC_DISC_NONE;
924
925   if (picture->flags & PIC_FLAG_SKIP) {
926     GST_DEBUG_OBJECT (mpeg2dec, "dropping buffer because of skip flag");
927     ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
928     mpeg2_skip (mpeg2dec->decoder, 1);
929     return ret;
930   }
931
932   if (mpeg2dec->discont_state != MPEG2DEC_DISC_NONE) {
933     GST_DEBUG_OBJECT (mpeg2dec, "dropping buffer, discont state %d",
934         mpeg2dec->discont_state);
935     ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
936     return ret;
937   }
938
939   state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (mpeg2dec));
940
941   /* do cropping if the target region is smaller than the input one */
942   if (mpeg2dec->need_cropping && !mpeg2dec->has_cropping) {
943     GstVideoFrame *vframe;
944
945     if (gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (mpeg2dec),
946             frame) < 0) {
947       GST_DEBUG_OBJECT (mpeg2dec, "dropping buffer crop, too late");
948       ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
949       goto beach;
950     }
951
952     GST_DEBUG_OBJECT (mpeg2dec, "cropping buffer");
953     vframe = gst_mpeg2dec_get_buffer (mpeg2dec, frame->system_frame_number);
954     g_assert (vframe != NULL);
955     ret = gst_mpeg2dec_crop_buffer (mpeg2dec, frame, vframe);
956   }
957
958   ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
959
960 beach:
961   gst_video_codec_state_unref (state);
962   return ret;
963
964 no_frame:
965   {
966     GST_DEBUG ("display buffer does not have a valid frame");
967     return GST_FLOW_OK;
968   }
969 }
970
971 static GstFlowReturn
972 gst_mpeg2dec_handle_frame (GstVideoDecoder * decoder,
973     GstVideoCodecFrame * frame)
974 {
975   GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (decoder);
976   GstBuffer *buf = frame->input_buffer;
977   GstMapInfo minfo;
978   const mpeg2_info_t *info;
979   mpeg2_state_t state;
980   gboolean done = FALSE;
981   GstFlowReturn ret = GST_FLOW_OK;
982
983   GST_LOG_OBJECT (mpeg2dec, "received frame %d, timestamp %"
984       GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
985       frame->system_frame_number,
986       GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->duration));
987
988   gst_buffer_ref (buf);
989   if (!gst_buffer_map (buf, &minfo, GST_MAP_READ)) {
990     GST_ERROR_OBJECT (mpeg2dec, "Failed to map input buffer");
991     return GST_FLOW_ERROR;
992   }
993
994   info = mpeg2dec->info;
995
996   GST_LOG_OBJECT (mpeg2dec, "calling mpeg2_buffer");
997   mpeg2_buffer (mpeg2dec->decoder, minfo.data, minfo.data + minfo.size);
998   GST_LOG_OBJECT (mpeg2dec, "calling mpeg2_buffer done");
999
1000   while (!done) {
1001     GST_LOG_OBJECT (mpeg2dec, "calling parse");
1002     state = mpeg2_parse (mpeg2dec->decoder);
1003     GST_DEBUG_OBJECT (mpeg2dec, "parse state %d", state);
1004
1005     switch (state) {
1006 #if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
1007       case STATE_SEQUENCE_MODIFIED:
1008         GST_DEBUG_OBJECT (mpeg2dec, "sequence modified");
1009         mpeg2dec->discont_state = MPEG2DEC_DISC_NEW_PICTURE;
1010         gst_mpeg2dec_clear_buffers (mpeg2dec);
1011         /* fall through */
1012 #endif
1013       case STATE_SEQUENCE:
1014         ret = handle_sequence (mpeg2dec, info);
1015         /* if there is an error handling the sequence
1016          * reset the decoder, maybe something more elegant
1017          * could be done.
1018          */
1019         if (ret == GST_FLOW_ERROR) {
1020           GST_VIDEO_DECODER_ERROR (decoder, 1, STREAM, DECODE,
1021               ("decoding error"), ("Bad sequence header"), ret);
1022           gst_video_decoder_drop_frame (decoder, frame);
1023           gst_mpeg2dec_flush (decoder);
1024           goto done;
1025         }
1026         break;
1027       case STATE_SEQUENCE_REPEATED:
1028         GST_DEBUG_OBJECT (mpeg2dec, "sequence repeated");
1029         break;
1030       case STATE_GOP:
1031         GST_DEBUG_OBJECT (mpeg2dec, "gop");
1032         break;
1033       case STATE_PICTURE:
1034         ret = handle_picture (mpeg2dec, info, frame);
1035         break;
1036       case STATE_SLICE_1ST:
1037         GST_LOG_OBJECT (mpeg2dec, "1st slice of frame encountered");
1038         break;
1039       case STATE_PICTURE_2ND:
1040         GST_LOG_OBJECT (mpeg2dec,
1041             "Second picture header encountered. Decoding 2nd field");
1042         break;
1043 #if MPEG2_RELEASE >= MPEG2_VERSION (0, 4, 0)
1044       case STATE_INVALID_END:
1045         GST_DEBUG_OBJECT (mpeg2dec, "invalid end");
1046 #endif
1047       case STATE_END:
1048         GST_DEBUG_OBJECT (mpeg2dec, "end");
1049       case STATE_SLICE:
1050         GST_DEBUG_OBJECT (mpeg2dec, "display_fbuf:%p, discard_fbuf:%p",
1051             info->display_fbuf, info->discard_fbuf);
1052         if (info->display_fbuf && info->display_fbuf->id) {
1053           ret = handle_slice (mpeg2dec, info);
1054         } else {
1055           GST_DEBUG_OBJECT (mpeg2dec, "no picture to display");
1056         }
1057         if (info->discard_fbuf && info->discard_fbuf->id)
1058           gst_mpeg2dec_discard_buffer (mpeg2dec,
1059               GPOINTER_TO_INT (info->discard_fbuf->id) - 1);
1060         if (state != STATE_SLICE) {
1061           gst_mpeg2dec_clear_buffers (mpeg2dec);
1062         }
1063         break;
1064       case STATE_BUFFER:
1065         done = TRUE;
1066         break;
1067         /* error */
1068       case STATE_INVALID:
1069         GST_VIDEO_DECODER_ERROR (decoder, 1, STREAM, DECODE,
1070             ("decoding error"), ("Reached libmpeg2 invalid state"), ret);
1071         continue;
1072       default:
1073         GST_ERROR_OBJECT (mpeg2dec, "Unknown libmpeg2 state %d, FIXME", state);
1074         ret = GST_FLOW_OK;
1075         gst_video_codec_frame_unref (frame);
1076         goto done;
1077     }
1078
1079     if (ret != GST_FLOW_OK) {
1080       GST_DEBUG_OBJECT (mpeg2dec, "exit loop, reason %s",
1081           gst_flow_get_name (ret));
1082       break;
1083     }
1084   }
1085
1086   gst_video_codec_frame_unref (frame);
1087
1088 done:
1089   gst_buffer_unmap (buf, &minfo);
1090   gst_buffer_unref (buf);
1091   return ret;
1092 }
1093
1094 static gboolean
1095 plugin_init (GstPlugin * plugin)
1096 {
1097   if (!gst_element_register (plugin, "mpeg2dec", GST_RANK_PRIMARY,
1098           GST_TYPE_MPEG2DEC))
1099     return FALSE;
1100
1101   return TRUE;
1102 }
1103
1104 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1105     GST_VERSION_MINOR,
1106     mpeg2dec,
1107     "LibMpeg2 decoder", plugin_init, VERSION, "GPL", GST_PACKAGE_NAME,
1108     GST_PACKAGE_ORIGIN);