• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2020 Intel Corporation
3  *     Author: He Junyan <junyan.he@intel.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 /**
21  * SECTION:gstmpeg2decoder
22  * @title: GstMpeg2Decoder
23  * @short_description: Base class to implement stateless MPEG2 decoders
24  * @sources:
25  * - gstmpeg2picture.h
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <gst/base/base.h>
33 #include "gstmpeg2decoder.h"
34 
35 GST_DEBUG_CATEGORY (gst_mpeg2_decoder_debug);
36 #define GST_CAT_DEFAULT gst_mpeg2_decoder_debug
37 
38 /* ------------------------------------------------------------------------- */
39 /* --- PTS Generator                                                     --- */
40 /* ------------------------------------------------------------------------- */
41 typedef struct _PTSGenerator PTSGenerator;
42 struct _PTSGenerator
43 {
44   /* The current GOP PTS */
45   GstClockTime gop_pts;
46   /* Max picture PTS */
47   GstClockTime max_pts;
48   /* Absolute GOP TSN */
49   guint gop_tsn;
50   /* Max picture TSN, relative to last GOP TSN */
51   guint max_tsn;
52   /* How many times TSN overflowed since GOP */
53   guint ovl_tsn;
54   /* Last picture TSN */
55   guint lst_tsn;
56   guint fps_n;
57   guint fps_d;
58 };
59 
60 static void
_pts_init(PTSGenerator * tsg)61 _pts_init (PTSGenerator * tsg)
62 {
63   tsg->gop_pts = GST_CLOCK_TIME_NONE;
64   tsg->max_pts = GST_CLOCK_TIME_NONE;
65   tsg->gop_tsn = 0;
66   tsg->max_tsn = 0;
67   tsg->ovl_tsn = 0;
68   tsg->lst_tsn = 0;
69   tsg->fps_n = 0;
70   tsg->fps_d = 0;
71 }
72 
73 static inline GstClockTime
_pts_get_duration(PTSGenerator * tsg,guint num_frames)74 _pts_get_duration (PTSGenerator * tsg, guint num_frames)
75 {
76   return gst_util_uint64_scale (num_frames, GST_SECOND * tsg->fps_d,
77       tsg->fps_n);
78 }
79 
80 static inline guint
_pts_get_poc(PTSGenerator * tsg)81 _pts_get_poc (PTSGenerator * tsg)
82 {
83   return tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->lst_tsn;
84 }
85 
86 static void
_pts_set_framerate(PTSGenerator * tsg,guint fps_n,guint fps_d)87 _pts_set_framerate (PTSGenerator * tsg, guint fps_n, guint fps_d)
88 {
89   tsg->fps_n = fps_n;
90   tsg->fps_d = fps_d;
91 }
92 
93 static void
_pts_sync(PTSGenerator * tsg,GstClockTime gop_pts)94 _pts_sync (PTSGenerator * tsg, GstClockTime gop_pts)
95 {
96   guint gop_tsn;
97 
98   if (!GST_CLOCK_TIME_IS_VALID (gop_pts) ||
99       (GST_CLOCK_TIME_IS_VALID (tsg->max_pts) && tsg->max_pts >= gop_pts)) {
100     /* Invalid GOP PTS, interpolate from the last known picture PTS */
101     if (GST_CLOCK_TIME_IS_VALID (tsg->max_pts)) {
102       gop_pts = tsg->max_pts + _pts_get_duration (tsg, 1);
103       gop_tsn = tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->max_tsn + 1;
104     } else {
105       gop_pts = 0;
106       gop_tsn = 0;
107     }
108   } else {
109     /* Interpolate GOP TSN from this valid PTS */
110     if (GST_CLOCK_TIME_IS_VALID (tsg->gop_pts))
111       gop_tsn = tsg->gop_tsn + gst_util_uint64_scale (gop_pts - tsg->gop_pts +
112           _pts_get_duration (tsg, 1) - 1, tsg->fps_n, GST_SECOND * tsg->fps_d);
113     else
114       gop_tsn = 0;
115   }
116 
117   tsg->gop_pts = gop_pts;
118   tsg->gop_tsn = gop_tsn;
119   tsg->max_tsn = 0;
120   tsg->ovl_tsn = 0;
121   tsg->lst_tsn = 0;
122 }
123 
124 static GstClockTime
_pts_eval(PTSGenerator * tsg,GstClockTime pic_pts,guint pic_tsn)125 _pts_eval (PTSGenerator * tsg, GstClockTime pic_pts, guint pic_tsn)
126 {
127   GstClockTime pts;
128 
129   if (!GST_CLOCK_TIME_IS_VALID (tsg->gop_pts))
130     tsg->gop_pts = _pts_get_duration (tsg, pic_tsn);
131 
132   pts = pic_pts;
133   if (!GST_CLOCK_TIME_IS_VALID (pts))
134     pts = tsg->gop_pts + _pts_get_duration (tsg, tsg->ovl_tsn * 1024 + pic_tsn);
135   else if (pts == tsg->gop_pts) {
136     /* The picture following the GOP header shall be an I-frame.
137        So we can compensate for the GOP start time from here */
138     tsg->gop_pts -= _pts_get_duration (tsg, pic_tsn);
139   }
140 
141   if (!GST_CLOCK_TIME_IS_VALID (tsg->max_pts) || tsg->max_pts < pts)
142     tsg->max_pts = pts;
143 
144   if (tsg->max_tsn < pic_tsn)
145     tsg->max_tsn = pic_tsn;
146   else if (tsg->max_tsn == 1023 && pic_tsn < tsg->lst_tsn) {    /* TSN wrapped */
147     tsg->max_tsn = pic_tsn;
148     tsg->ovl_tsn++;
149   }
150   tsg->lst_tsn = pic_tsn;
151 
152   return pts;
153 }
154 
155 static inline gboolean
_seq_hdr_is_valid(GstMpegVideoSequenceHdr * hdr)156 _seq_hdr_is_valid (GstMpegVideoSequenceHdr * hdr)
157 {
158   return hdr->width > 0 && hdr->height > 0;
159 }
160 
161 #define SEQ_HDR_INIT (GstMpegVideoSequenceHdr) { 0, }
162 
163 static inline gboolean
_seq_ext_is_valid(GstMpegVideoSequenceExt * ext)164 _seq_ext_is_valid (GstMpegVideoSequenceExt * ext)
165 {
166   return ext->profile >= GST_MPEG_VIDEO_PROFILE_422
167       && ext->profile <= GST_MPEG_VIDEO_PROFILE_SIMPLE;
168 }
169 
170 #define SEQ_EXT_INIT (GstMpegVideoSequenceExt) { 0xff, 0, }
171 
172 static inline gboolean
_seq_display_ext_is_valid(GstMpegVideoSequenceDisplayExt * ext)173 _seq_display_ext_is_valid (GstMpegVideoSequenceDisplayExt * ext)
174 {
175   return ext->video_format != 0xff;
176 }
177 
178 #define SEQ_DISPLAY_EXT_INIT (GstMpegVideoSequenceDisplayExt) { 0xff, 0, }
179 
180 static inline gboolean
_seq_scalable_ext_is_valid(GstMpegVideoSequenceScalableExt * ext)181 _seq_scalable_ext_is_valid (GstMpegVideoSequenceScalableExt * ext)
182 {
183   return ext->scalable_mode != 0xff;
184 }
185 
186 #define SEQ_SCALABLE_EXT_INIT (GstMpegVideoSequenceScalableExt) { 0xff, 0, }
187 
188 static inline gboolean
_quant_matrix_ext_is_valid(GstMpegVideoQuantMatrixExt * ext)189 _quant_matrix_ext_is_valid (GstMpegVideoQuantMatrixExt * ext)
190 {
191   return ext->load_intra_quantiser_matrix != 0xff;
192 }
193 
194 #define QUANT_MATRIX_EXT_INIT (GstMpegVideoQuantMatrixExt) { 0xff, { 0, } }
195 
196 static inline gboolean
_pic_hdr_is_valid(GstMpegVideoPictureHdr * hdr)197 _pic_hdr_is_valid (GstMpegVideoPictureHdr * hdr)
198 {
199   return hdr->tsn != 0xffff;
200 }
201 
202 #define PIC_HDR_INIT (GstMpegVideoPictureHdr) { 0xffff, 0, }
203 
204 static inline gboolean
_pic_hdr_ext_is_valid(GstMpegVideoPictureExt * ext)205 _pic_hdr_ext_is_valid (GstMpegVideoPictureExt * ext)
206 {
207   return ext->f_code[0][0] != 0xff;
208 }
209 
210 #define PIC_HDR_EXT_INIT                                        \
211     (GstMpegVideoPictureExt) { { { 0xff, 0, }, { 0, } }, 0, }
212 
213 typedef enum
214 {
215   GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR = 1 << 0,
216   GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT = 1 << 1,
217   GST_MPEG2_DECODER_STATE_GOT_PIC_HDR = 1 << 2,
218   GST_MPEG2_DECODER_STATE_GOT_PIC_EXT = 1 << 3,
219   GST_MPEG2_DECODER_STATE_GOT_SLICE = 1 << 4,
220 
221   GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS =
222       (GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR |
223       GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT),
224   GST_MPEG2_DECODER_STATE_VALID_PIC_HEADERS =
225       (GST_MPEG2_DECODER_STATE_GOT_PIC_HDR |
226       GST_MPEG2_DECODER_STATE_GOT_PIC_EXT),
227   GST_MPEG2_DECODER_STATE_VALID_PICTURE =
228       (GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS |
229       GST_MPEG2_DECODER_STATE_VALID_PIC_HEADERS |
230       GST_MPEG2_DECODER_STATE_GOT_SLICE)
231 } GstMpeg2DecoderState;
232 
233 struct _GstMpeg2DecoderPrivate
234 {
235   gint width;
236   gint height;
237   gint display_width;
238   gint display_height;
239   GstMpegVideoProfile profile;
240   gboolean progressive;
241 
242   GstMpegVideoSequenceHdr seq_hdr;
243   GstMpegVideoSequenceExt seq_ext;
244   GstMpegVideoSequenceDisplayExt seq_display_ext;
245   GstMpegVideoSequenceScalableExt seq_scalable_ext;
246 
247   /* some sequence info changed after last new_sequence () */
248   gboolean seq_changed;
249   /* whether we need to drain before new_sequence () */
250   gboolean need_to_drain;
251   GstMpegVideoGop gop;
252   GstMpegVideoQuantMatrixExt quant_matrix;
253   GstMpegVideoPictureHdr pic_hdr;
254   GstMpegVideoPictureExt pic_ext;
255 
256   GstMpeg2Dpb *dpb;
257   GstMpeg2DecoderState state;
258   PTSGenerator tsg;
259   GstClockTime current_pts;
260 
261   GstMpeg2Picture *current_picture;
262   GstVideoCodecFrame *current_frame;
263   GstMpeg2Picture *first_field;
264 
265   guint preferred_output_delay;
266   /* for delayed output */
267   GstQueueArray *output_queue;
268   /* used for low-latency vs. high throughput mode decision */
269   gboolean is_live;
270 };
271 
272 #define UPDATE_FLOW_RETURN(ret,new_ret) G_STMT_START { \
273   if (*(ret) == GST_FLOW_OK) \
274     *(ret) = new_ret; \
275 } G_STMT_END
276 
277 typedef struct
278 {
279   GstVideoCodecFrame *frame;
280   GstMpeg2Picture *picture;
281   GstMpeg2Decoder *self;
282 } GstMpeg2DecoderOutputFrame;
283 
284 
285 #define parent_class gst_mpeg2_decoder_parent_class
286 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstMpeg2Decoder, gst_mpeg2_decoder,
287     GST_TYPE_VIDEO_DECODER,
288     G_ADD_PRIVATE (GstMpeg2Decoder);
289     GST_DEBUG_CATEGORY_INIT (gst_mpeg2_decoder_debug, "mpeg2decoder", 0,
290         "MPEG2 Video Decoder"));
291 
292 static gboolean gst_mpeg2_decoder_start (GstVideoDecoder * decoder);
293 static gboolean gst_mpeg2_decoder_stop (GstVideoDecoder * decoder);
294 static gboolean gst_mpeg2_decoder_set_format (GstVideoDecoder * decoder,
295     GstVideoCodecState * state);
296 static GstFlowReturn gst_mpeg2_decoder_finish (GstVideoDecoder * decoder);
297 static gboolean gst_mpeg2_decoder_flush (GstVideoDecoder * decoder);
298 static GstFlowReturn gst_mpeg2_decoder_drain (GstVideoDecoder * decoder);
299 static GstFlowReturn gst_mpeg2_decoder_handle_frame (GstVideoDecoder * decoder,
300     GstVideoCodecFrame * frame);
301 static void gst_mpeg2_decoder_do_output_picture (GstMpeg2Decoder * self,
302     GstMpeg2Picture * picture, GstFlowReturn * ret);
303 static void gst_mpeg2_decoder_clear_output_frame (GstMpeg2DecoderOutputFrame *
304     output_frame);
305 static void gst_mpeg2_decoder_drain_output_queue (GstMpeg2Decoder *
306     self, guint num, GstFlowReturn * ret);
307 
308 
309 static void
gst_mpeg2_decoder_class_init(GstMpeg2DecoderClass * klass)310 gst_mpeg2_decoder_class_init (GstMpeg2DecoderClass * klass)
311 {
312   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
313 
314   decoder_class->start = GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_start);
315   decoder_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_stop);
316   decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_set_format);
317   decoder_class->finish = GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_finish);
318   decoder_class->flush = GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_flush);
319   decoder_class->drain = GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_drain);
320   decoder_class->handle_frame =
321       GST_DEBUG_FUNCPTR (gst_mpeg2_decoder_handle_frame);
322 }
323 
324 static void
gst_mpeg2_decoder_init(GstMpeg2Decoder * self)325 gst_mpeg2_decoder_init (GstMpeg2Decoder * self)
326 {
327   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
328 
329   self->priv = gst_mpeg2_decoder_get_instance_private (self);
330 
331   self->priv->seq_hdr = SEQ_HDR_INIT;
332   self->priv->seq_ext = SEQ_EXT_INIT;
333   self->priv->seq_display_ext = SEQ_DISPLAY_EXT_INIT;
334   self->priv->seq_scalable_ext = SEQ_SCALABLE_EXT_INIT;
335   self->priv->quant_matrix = QUANT_MATRIX_EXT_INIT;
336   self->priv->pic_hdr = PIC_HDR_INIT;
337   self->priv->pic_ext = PIC_HDR_EXT_INIT;
338 }
339 
340 static gboolean
gst_mpeg2_decoder_start(GstVideoDecoder * decoder)341 gst_mpeg2_decoder_start (GstVideoDecoder * decoder)
342 {
343   GstMpeg2Decoder *self = GST_MPEG2_DECODER (decoder);
344   GstMpeg2DecoderPrivate *priv = self->priv;
345 
346   _pts_init (&priv->tsg);
347   priv->dpb = gst_mpeg2_dpb_new ();
348   priv->profile = -1;
349   priv->progressive = TRUE;
350 
351   priv->output_queue =
352       gst_queue_array_new_for_struct (sizeof (GstMpeg2DecoderOutputFrame), 1);
353   gst_queue_array_set_clear_func (priv->output_queue,
354       (GDestroyNotify) gst_mpeg2_decoder_clear_output_frame);
355 
356   return TRUE;
357 }
358 
359 static gboolean
gst_mpeg2_decoder_stop(GstVideoDecoder * decoder)360 gst_mpeg2_decoder_stop (GstVideoDecoder * decoder)
361 {
362   GstMpeg2Decoder *self = GST_MPEG2_DECODER (decoder);
363   GstMpeg2DecoderPrivate *priv = self->priv;
364 
365   g_clear_pointer (&self->input_state, gst_video_codec_state_unref);
366   g_clear_pointer (&priv->dpb, gst_mpeg2_dpb_free);
367   gst_queue_array_free (priv->output_queue);
368 
369   return TRUE;
370 }
371 
372 static gboolean
gst_mpeg2_decoder_set_format(GstVideoDecoder * decoder,GstVideoCodecState * state)373 gst_mpeg2_decoder_set_format (GstVideoDecoder * decoder,
374     GstVideoCodecState * state)
375 {
376   GstMpeg2Decoder *self = GST_MPEG2_DECODER (decoder);
377   GstMpeg2DecoderPrivate *priv = self->priv;
378   GstQuery *query;
379 
380   GST_DEBUG_OBJECT (decoder, "Set format");
381 
382   if (self->input_state)
383     gst_video_codec_state_unref (self->input_state);
384 
385   self->input_state = gst_video_codec_state_ref (state);
386 
387   priv->width = GST_VIDEO_INFO_WIDTH (&state->info);
388   priv->height = GST_VIDEO_INFO_HEIGHT (&state->info);
389 
390   query = gst_query_new_latency ();
391   if (gst_pad_peer_query (GST_VIDEO_DECODER_SINK_PAD (self), query))
392     gst_query_parse_latency (query, &priv->is_live, NULL, NULL);
393   gst_query_unref (query);
394 
395   return TRUE;
396 }
397 
398 static GstFlowReturn
gst_mpeg2_decoder_drain(GstVideoDecoder * decoder)399 gst_mpeg2_decoder_drain (GstVideoDecoder * decoder)
400 {
401   GstMpeg2Decoder *self = GST_MPEG2_DECODER (decoder);
402   GstMpeg2DecoderPrivate *priv = self->priv;
403   GstMpeg2Picture *picture;
404   GstFlowReturn ret = GST_FLOW_OK;
405 
406   while ((picture = gst_mpeg2_dpb_bump (priv->dpb)) != NULL) {
407     gst_mpeg2_decoder_do_output_picture (self, picture, &ret);
408   }
409 
410   gst_mpeg2_decoder_drain_output_queue (self, 0, &ret);
411   gst_queue_array_clear (priv->output_queue);
412   gst_mpeg2_dpb_clear (priv->dpb);
413 
414   return ret;
415 }
416 
417 static GstFlowReturn
gst_mpeg2_decoder_finish(GstVideoDecoder * decoder)418 gst_mpeg2_decoder_finish (GstVideoDecoder * decoder)
419 {
420   return gst_mpeg2_decoder_drain (decoder);
421 }
422 
423 static gboolean
gst_mpeg2_decoder_flush(GstVideoDecoder * decoder)424 gst_mpeg2_decoder_flush (GstVideoDecoder * decoder)
425 {
426   GstMpeg2Decoder *self = GST_MPEG2_DECODER (decoder);
427   GstMpeg2DecoderPrivate *priv = self->priv;
428 
429   gst_mpeg2_dpb_clear (priv->dpb);
430   gst_queue_array_clear (priv->output_queue);
431   priv->state &= GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS;
432   priv->pic_hdr = PIC_HDR_INIT;
433   priv->pic_ext = PIC_HDR_EXT_INIT;
434 
435   return TRUE;
436 }
437 
438 static inline gboolean
_is_valid_state(GstMpeg2Decoder * decoder,GstMpeg2DecoderState state)439 _is_valid_state (GstMpeg2Decoder * decoder, GstMpeg2DecoderState state)
440 {
441   GstMpeg2DecoderPrivate *priv = decoder->priv;
442 
443   return (priv->state & state) == state;
444 }
445 
446 static void
gst_mpeg2_decoder_set_latency(GstMpeg2Decoder * decoder)447 gst_mpeg2_decoder_set_latency (GstMpeg2Decoder * decoder)
448 {
449   GstCaps *caps;
450   GstClockTime min, max;
451   GstMpeg2DecoderPrivate *priv = decoder->priv;
452   GstStructure *structure;
453   gint fps_d = 1, fps_n = 0;
454 
455   if (priv->tsg.fps_d > 0 && priv->tsg.fps_n > 0) {
456     fps_n = priv->tsg.fps_n;
457     fps_d = priv->tsg.fps_d;
458   } else {
459     caps = gst_pad_get_current_caps (GST_VIDEO_DECODER_SINK_PAD (decoder));
460     if (caps) {
461       structure = gst_caps_get_structure (caps, 0);
462       if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
463         if (fps_n == 0) {
464           /* variable framerate: see if we have a max-framerate */
465           gst_structure_get_fraction (structure, "max-framerate", &fps_n,
466               &fps_d);
467         }
468       }
469       gst_caps_unref (caps);
470     }
471   }
472 
473   /* if no fps or variable, then 25/1 */
474   if (fps_n == 0) {
475     fps_n = 25;
476     fps_d = 1;
477   }
478 
479   max = gst_util_uint64_scale (2 * GST_SECOND, fps_d, fps_n);
480   min = gst_util_uint64_scale (1 * GST_SECOND, fps_d, fps_n);
481 
482   GST_LOG_OBJECT (decoder,
483       "latency min %" G_GUINT64_FORMAT " max %" G_GUINT64_FORMAT, min, max);
484 
485   gst_video_decoder_set_latency (GST_VIDEO_DECODER (decoder), min, max);
486 }
487 
488 static GstFlowReturn
gst_mpeg2_decoder_handle_sequence(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)489 gst_mpeg2_decoder_handle_sequence (GstMpeg2Decoder * decoder,
490     GstMpegVideoPacket * packet)
491 {
492   GstMpeg2DecoderPrivate *priv = decoder->priv;
493   GstMpegVideoSequenceHdr seq_hdr = { 0, };
494 
495   if (!gst_mpeg_video_packet_parse_sequence_header (packet, &seq_hdr)) {
496     GST_ERROR_OBJECT (decoder, "failed to parse sequence header");
497     return GST_FLOW_ERROR;
498   }
499 
500   /* 6.1.1.6 Sequence header
501      The quantisation matrices may be redefined each time that a sequence
502      header occurs in the bitstream */
503   priv->quant_matrix = QUANT_MATRIX_EXT_INIT;
504 
505   if (_seq_hdr_is_valid (&priv->seq_hdr) &&
506       memcmp (&priv->seq_hdr, &seq_hdr, sizeof (seq_hdr)) == 0)
507     return GST_FLOW_OK;
508 
509   priv->seq_ext = SEQ_EXT_INIT;
510   priv->seq_display_ext = SEQ_DISPLAY_EXT_INIT;
511   priv->seq_scalable_ext = SEQ_SCALABLE_EXT_INIT;
512   priv->pic_ext = PIC_HDR_EXT_INIT;
513 
514   priv->seq_hdr = seq_hdr;
515   priv->seq_changed = TRUE;
516 
517   if (priv->width != seq_hdr.width || priv->height != seq_hdr.height) {
518     priv->need_to_drain = TRUE;
519     priv->width = seq_hdr.width;
520     priv->height = seq_hdr.height;
521   }
522   priv->display_width = priv->width;
523   priv->display_height = priv->height;
524 
525   _pts_set_framerate (&priv->tsg, seq_hdr.fps_n, seq_hdr.fps_d);
526 
527   gst_mpeg2_decoder_set_latency (decoder);
528 
529   priv->state = GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR;
530 
531   return GST_FLOW_OK;
532 }
533 
534 static GstFlowReturn
gst_mpeg2_decoder_handle_sequence_ext(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)535 gst_mpeg2_decoder_handle_sequence_ext (GstMpeg2Decoder * decoder,
536     GstMpegVideoPacket * packet)
537 {
538   GstMpeg2DecoderPrivate *priv = decoder->priv;
539   GstMpegVideoSequenceExt seq_ext = { 0, };
540   guint width, height;
541 
542   if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR)) {
543     GST_ERROR_OBJECT (decoder, "no sequence before parsing sequence-extension");
544     return GST_FLOW_ERROR;
545   }
546 
547   if (!gst_mpeg_video_packet_parse_sequence_extension (packet, &seq_ext)) {
548     GST_ERROR_OBJECT (decoder, "failed to parse sequence-extension");
549     return GST_FLOW_ERROR;
550   }
551 
552   if (_seq_ext_is_valid (&priv->seq_ext) &&
553       memcmp (&priv->seq_ext, &seq_ext, sizeof (seq_ext)) == 0)
554     return GST_FLOW_OK;
555 
556   priv->seq_ext = seq_ext;
557   priv->seq_changed = TRUE;
558 
559   if (seq_ext.fps_n_ext && seq_ext.fps_d_ext) {
560     guint fps_n = priv->tsg.fps_n;
561     guint fps_d = priv->tsg.fps_d;
562     fps_n *= seq_ext.fps_n_ext + 1;
563     fps_d *= seq_ext.fps_d_ext + 1;
564     _pts_set_framerate (&priv->tsg, fps_n, fps_d);
565     gst_mpeg2_decoder_set_latency (decoder);
566   }
567 
568   width = (priv->width & 0x0fff) | ((guint32) seq_ext.horiz_size_ext << 12);
569   height = (priv->height & 0x0fff) | ((guint32) seq_ext.vert_size_ext << 12);
570 
571   if (priv->width != width || priv->height != height ||
572       priv->profile != seq_ext.profile ||
573       priv->progressive != seq_ext.progressive) {
574     priv->need_to_drain = TRUE;
575     priv->width = width;
576     priv->height = height;
577     priv->profile = seq_ext.profile;
578     priv->progressive = seq_ext.progressive;
579 
580     GST_DEBUG_OBJECT (decoder, "video resolution %ux%u, profile %d,"
581         " progressive %d", priv->width, priv->height, priv->profile,
582         priv->progressive);
583   }
584 
585   priv->state |= GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT;
586 
587   return GST_FLOW_OK;
588 }
589 
590 static GstFlowReturn
gst_mpeg2_decoder_handle_sequence_display_ext(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)591 gst_mpeg2_decoder_handle_sequence_display_ext (GstMpeg2Decoder * decoder,
592     GstMpegVideoPacket * packet)
593 {
594   GstMpeg2DecoderPrivate *priv = decoder->priv;
595   GstMpegVideoSequenceDisplayExt seq_display_ext = { 0, };
596 
597   if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR)) {
598     GST_ERROR_OBJECT (decoder,
599         "no sequence before parsing sequence-display-extension");
600     return GST_FLOW_ERROR;
601   }
602 
603   if (!gst_mpeg_video_packet_parse_sequence_display_extension (packet,
604           &seq_display_ext)) {
605     GST_ERROR_OBJECT (decoder, "failed to parse sequence-display-extension");
606     return GST_FLOW_ERROR;
607   }
608 
609   if (_seq_display_ext_is_valid (&priv->seq_display_ext) &&
610       memcmp (&priv->seq_display_ext, &seq_display_ext,
611           sizeof (seq_display_ext)) == 0)
612     return GST_FLOW_OK;
613 
614   priv->seq_display_ext = seq_display_ext;
615   priv->seq_changed = TRUE;
616 
617   priv->display_width = seq_display_ext.display_horizontal_size;
618   priv->display_height = seq_display_ext.display_vertical_size;
619 
620   return GST_FLOW_OK;
621 }
622 
623 static GstFlowReturn
gst_mpeg2_decoder_handle_sequence_scalable_ext(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)624 gst_mpeg2_decoder_handle_sequence_scalable_ext (GstMpeg2Decoder * decoder,
625     GstMpegVideoPacket * packet)
626 {
627   GstMpeg2DecoderPrivate *priv = decoder->priv;
628   GstMpegVideoSequenceScalableExt seq_scalable_ext = { 0, };
629 
630   if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR)) {
631     GST_ERROR_OBJECT (decoder,
632         "no sequence before parsing sequence-scalable-extension");
633     return GST_FLOW_ERROR;
634   }
635 
636   if (!gst_mpeg_video_packet_parse_sequence_scalable_extension (packet,
637           &seq_scalable_ext)) {
638     GST_ERROR_OBJECT (decoder, "failed to parse sequence-scalable-extension");
639     return GST_FLOW_ERROR;
640   }
641 
642   if (_seq_scalable_ext_is_valid (&priv->seq_scalable_ext) &&
643       memcmp (&priv->seq_scalable_ext, &seq_scalable_ext,
644           sizeof (seq_scalable_ext)) == 0)
645     return GST_FLOW_OK;
646 
647   priv->seq_scalable_ext = seq_scalable_ext;
648   priv->seq_changed = TRUE;
649 
650   return GST_FLOW_OK;
651 }
652 
653 static GstFlowReturn
gst_mpeg2_decoder_handle_quant_matrix_ext(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)654 gst_mpeg2_decoder_handle_quant_matrix_ext (GstMpeg2Decoder * decoder,
655     GstMpegVideoPacket * packet)
656 {
657   GstMpeg2DecoderPrivate *priv = decoder->priv;
658   GstMpegVideoQuantMatrixExt matrix_ext = { 0, };
659 
660   if (!gst_mpeg_video_packet_parse_quant_matrix_extension (packet, &matrix_ext)) {
661     GST_ERROR_OBJECT (decoder, "failed to parse sequence-scalable-extension");
662     return GST_FLOW_ERROR;
663   }
664 
665   priv->quant_matrix = matrix_ext;
666 
667   return GST_FLOW_OK;
668 }
669 
670 static GstFlowReturn
gst_mpeg2_decoder_handle_picture_ext(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)671 gst_mpeg2_decoder_handle_picture_ext (GstMpeg2Decoder * decoder,
672     GstMpegVideoPacket * packet)
673 {
674   GstMpeg2DecoderPrivate *priv = decoder->priv;
675   GstMpegVideoPictureExt pic_ext = { {{0,},}, };
676 
677   if (!_is_valid_state (decoder,
678           GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS |
679           GST_MPEG2_DECODER_STATE_GOT_PIC_HDR)) {
680     GST_ERROR_OBJECT (decoder,
681         "no sequence before parsing sequence-scalable-extension");
682     return GST_FLOW_ERROR;
683   }
684 
685   if (!gst_mpeg_video_packet_parse_picture_extension (packet, &pic_ext)) {
686     GST_ERROR_OBJECT (decoder, "failed to parse picture-extension");
687     return GST_FLOW_ERROR;
688   }
689 
690   if (priv->progressive && !pic_ext.progressive_frame) {
691     GST_WARNING_OBJECT (decoder,
692         "invalid interlaced frame in progressive sequence, fixing");
693     pic_ext.progressive_frame = 1;
694   }
695 
696   if (pic_ext.picture_structure == 0 ||
697       (pic_ext.progressive_frame &&
698           pic_ext.picture_structure !=
699           GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME)) {
700     GST_WARNING_OBJECT (decoder,
701         "invalid picture_structure %d, replacing with \"frame\"",
702         pic_ext.picture_structure);
703     pic_ext.picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME;
704   }
705 
706   priv->pic_ext = pic_ext;
707 
708   priv->state |= GST_MPEG2_DECODER_STATE_GOT_PIC_EXT;
709 
710   return GST_FLOW_OK;
711 }
712 
713 static GstFlowReturn
gst_mpeg2_decoder_handle_gop(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)714 gst_mpeg2_decoder_handle_gop (GstMpeg2Decoder * decoder,
715     GstMpegVideoPacket * packet)
716 {
717   GstMpeg2DecoderPrivate *priv = decoder->priv;
718   GstMpegVideoGop gop = { 0, };
719 
720   if (!gst_mpeg_video_packet_parse_gop (packet, &gop)) {
721     GST_ERROR_OBJECT (decoder, "failed to parse GOP");
722     return GST_FLOW_ERROR;
723   }
724 
725   GST_DEBUG_OBJECT (decoder,
726       "GOP %02u:%02u:%02u:%02u (closed_gop %d, broken_link %d)", gop.hour,
727       gop.minute, gop.second, gop.frame, gop.closed_gop, gop.broken_link);
728 
729   priv->gop = gop;
730 
731   _pts_sync (&priv->tsg, priv->current_frame->pts);
732 
733   return GST_FLOW_OK;
734 }
735 
736 static GstFlowReturn
gst_mpeg2_decoder_handle_picture(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)737 gst_mpeg2_decoder_handle_picture (GstMpeg2Decoder * decoder,
738     GstMpegVideoPacket * packet)
739 {
740   GstMpeg2DecoderPrivate *priv = decoder->priv;
741   GstMpegVideoPictureHdr pic_hdr = { 0, };
742   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
743 
744   if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS)) {
745     GST_ERROR_OBJECT (decoder, "no sequence before parsing picture header");
746     return GST_FLOW_ERROR;
747   }
748 
749   /* If need_to_drain, we must have sequence changed. */
750   g_assert (priv->need_to_drain ? priv->seq_changed : TRUE);
751 
752   /* 6.1.1.6: Conversely if no sequence_xxx_extension() occurs between
753      the first sequence_header() and the first picture_header() then
754      sequence_xxx_extension() shall not occur in the bitstream. */
755   if (priv->seq_changed) {
756     GstFlowReturn ret;
757 
758     /* There are a lot of info in the mpeg2's sequence(also including ext
759        display_ext and scalable_ext). We need to notify the subclass about
760        its change, but not all the changes should trigger a drain(), which
761        may change the output picture order. */
762     if (priv->need_to_drain) {
763       ret = gst_mpeg2_decoder_drain (GST_VIDEO_DECODER (decoder));
764       if (ret != GST_FLOW_OK)
765         return ret;
766 
767       priv->need_to_drain = FALSE;
768     }
769 
770     if (klass->get_preferred_output_delay)
771       priv->preferred_output_delay =
772           klass->get_preferred_output_delay (decoder, priv->is_live);
773 
774     priv->seq_changed = FALSE;
775 
776     if (klass->new_sequence) {
777       ret = klass->new_sequence (decoder, &priv->seq_hdr,
778           _seq_ext_is_valid (&priv->seq_ext) ? &priv->seq_ext : NULL,
779           _seq_display_ext_is_valid (&priv->seq_display_ext) ?
780           &priv->seq_display_ext : NULL,
781           _seq_scalable_ext_is_valid (&priv->seq_scalable_ext) ?
782           &priv->seq_scalable_ext : NULL);
783 
784       if (ret != GST_FLOW_OK) {
785         GST_WARNING_OBJECT (decoder, "new sequence error");
786         return ret;
787       }
788     }
789   }
790 
791   priv->state &= (GST_MPEG2_DECODER_STATE_GOT_SEQ_HDR |
792       GST_MPEG2_DECODER_STATE_GOT_SEQ_EXT);
793 
794   if (!gst_mpeg_video_packet_parse_picture_header (packet, &pic_hdr)) {
795     GST_ERROR_OBJECT (decoder, "failed to parse picture header");
796     return GST_FLOW_ERROR;
797   }
798 
799   priv->pic_hdr = pic_hdr;
800 
801   priv->state |= GST_MPEG2_DECODER_STATE_GOT_PIC_HDR;
802 
803   return GST_FLOW_OK;
804 }
805 
806 static GstFlowReturn
gst_mpeg2_decoder_start_current_picture(GstMpeg2Decoder * decoder,GstMpeg2Slice * slice)807 gst_mpeg2_decoder_start_current_picture (GstMpeg2Decoder * decoder,
808     GstMpeg2Slice * slice)
809 {
810   GstMpeg2DecoderPrivate *priv = decoder->priv;
811   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
812   GstMpeg2Picture *prev_picture, *next_picture;
813   GstFlowReturn ret;
814 
815   if (!klass->start_picture)
816     return GST_FLOW_OK;
817 
818   gst_mpeg2_dpb_get_neighbours (priv->dpb, priv->current_picture,
819       &prev_picture, &next_picture);
820 
821   if (priv->current_picture->type == GST_MPEG_VIDEO_PICTURE_TYPE_B
822       && !prev_picture && !priv->gop.closed_gop) {
823     GST_VIDEO_CODEC_FRAME_FLAG_SET (priv->current_frame,
824         GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
825   }
826 
827   ret = klass->start_picture (decoder, priv->current_picture, slice,
828       prev_picture, next_picture);
829 
830   if (ret != GST_FLOW_OK) {
831     GST_WARNING_OBJECT (decoder, "subclass does not want to start picture");
832     return ret;
833   }
834 
835   return GST_FLOW_OK;
836 }
837 
838 static GstFlowReturn
gst_mpeg2_decoder_ensure_current_picture(GstMpeg2Decoder * decoder,GstMpeg2Slice * slice)839 gst_mpeg2_decoder_ensure_current_picture (GstMpeg2Decoder * decoder,
840     GstMpeg2Slice * slice)
841 {
842   GstMpeg2DecoderPrivate *priv = decoder->priv;
843   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
844   GstMpeg2Picture *picture = NULL;
845   GstFlowReturn ret = GST_FLOW_OK;
846 
847   if (priv->current_picture) {
848     g_assert (_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_GOT_SLICE));
849     return GST_FLOW_OK;
850   }
851 
852   if (priv->progressive ||
853       priv->pic_ext.picture_structure ==
854       GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME) {
855     g_assert (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_GOT_SLICE));
856 
857     if (priv->first_field) {
858       GST_WARNING_OBJECT (decoder, "An unmatched first field");
859       gst_mpeg2_picture_clear (&priv->first_field);
860     }
861 
862     picture = gst_mpeg2_picture_new ();
863     if (klass->new_picture)
864       ret = klass->new_picture (decoder, priv->current_frame, picture);
865 
866     if (ret != GST_FLOW_OK) {
867       GST_WARNING_OBJECT (decoder, "subclass does not want accept new picture");
868       gst_mpeg2_picture_unref (picture);
869       return ret;
870     }
871 
872     picture->structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME;
873   } else {
874     if (!priv->first_field) {
875       picture = gst_mpeg2_picture_new ();
876       if (klass->new_picture)
877         ret = klass->new_picture (decoder, priv->current_frame, picture);
878 
879       if (ret != GST_FLOW_OK) {
880         GST_WARNING_OBJECT (decoder,
881             "subclass does not want accept new picture");
882         gst_mpeg2_picture_unref (picture);
883         return ret;
884       }
885     } else {
886       picture = gst_mpeg2_picture_new ();
887 
888       if (klass->new_field_picture)
889         ret = klass->new_field_picture (decoder, priv->first_field, picture);
890 
891       if (ret != GST_FLOW_OK) {
892         GST_WARNING_OBJECT (decoder,
893             "Subclass couldn't handle new field picture");
894         gst_mpeg2_picture_unref (picture);
895         return ret;
896       }
897 
898       picture->first_field = gst_mpeg2_picture_ref (priv->first_field);
899 
900       /* At this moment, this picture should be interlaced */
901       picture->buffer_flags |= GST_VIDEO_BUFFER_FLAG_INTERLACED;
902       if (priv->pic_ext.top_field_first)
903         picture->buffer_flags |= GST_VIDEO_BUFFER_FLAG_TFF;
904     }
905 
906     picture->structure = priv->pic_ext.picture_structure;
907   }
908 
909   picture->needed_for_output = TRUE;
910   /* This allows accessing the frame from the picture. */
911   picture->system_frame_number = priv->current_frame->system_frame_number;
912   picture->type = priv->pic_hdr.pic_type;
913   picture->tsn = priv->pic_hdr.tsn;
914   priv->current_pts =
915       _pts_eval (&priv->tsg, priv->current_frame->pts, picture->tsn);
916   picture->pic_order_cnt = _pts_get_poc (&priv->tsg);
917 
918   priv->current_picture = picture;
919   GST_LOG_OBJECT (decoder,
920       "Create new picture %p(%s), system number: %d, poc: %d,"
921       " type: 0x%d, first field %p",
922       picture,
923       (picture->structure == GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME) ?
924       "frame" : "field",
925       picture->system_frame_number, picture->pic_order_cnt, picture->type,
926       picture->first_field);
927 
928   return gst_mpeg2_decoder_start_current_picture (decoder, slice);
929 }
930 
931 static GstFlowReturn
gst_mpeg2_decoder_finish_current_field(GstMpeg2Decoder * decoder)932 gst_mpeg2_decoder_finish_current_field (GstMpeg2Decoder * decoder)
933 {
934   GstMpeg2DecoderPrivate *priv = decoder->priv;
935   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
936   GstFlowReturn ret;
937 
938   if (priv->current_picture == NULL)
939     return GST_FLOW_OK;
940 
941   ret = klass->end_picture (decoder, priv->current_picture);
942   if (ret != GST_FLOW_OK) {
943     GST_WARNING_OBJECT (decoder, "subclass end_picture failed");
944     return ret;
945   }
946 
947   if (priv->current_picture->structure !=
948       GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME &&
949       !priv->current_picture->first_field) {
950     priv->first_field = priv->current_picture;
951     priv->current_picture = NULL;
952   } else {
953     GST_WARNING_OBJECT (decoder, "The current picture %p is not %s, should not "
954         "begin another picture. Just discard this.",
955         priv->current_picture, priv->current_picture->structure ==
956         GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME ?
957         " a field" : "the first field");
958     gst_mpeg2_picture_clear (&priv->current_picture);
959   }
960 
961   return GST_FLOW_OK;
962 }
963 
964 static GstFlowReturn
gst_mpeg2_decoder_finish_current_picture(GstMpeg2Decoder * decoder)965 gst_mpeg2_decoder_finish_current_picture (GstMpeg2Decoder * decoder)
966 {
967   GstMpeg2DecoderPrivate *priv = decoder->priv;
968   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
969   GstFlowReturn ret;
970 
971   g_assert (priv->current_picture != NULL);
972 
973   ret = klass->end_picture (decoder, priv->current_picture);
974   if (ret != GST_FLOW_OK) {
975     GST_WARNING_OBJECT (decoder, "subclass end_picture failed");
976     return ret;
977   }
978 
979   if (priv->current_picture->structure !=
980       GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME &&
981       !priv->current_picture->first_field) {
982     priv->first_field = priv->current_picture;
983     priv->current_picture = NULL;
984   }
985 
986   return GST_FLOW_OK;
987 }
988 
989 static GstFlowReturn
gst_mpeg2_decoder_handle_slice(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)990 gst_mpeg2_decoder_handle_slice (GstMpeg2Decoder * decoder,
991     GstMpegVideoPacket * packet)
992 {
993   GstMpeg2DecoderPrivate *priv = decoder->priv;
994   GstMpegVideoSliceHdr slice_hdr;
995   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
996   GstMpeg2Slice slice;
997   GstFlowReturn ret;
998 
999   if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_VALID_PIC_HEADERS)) {
1000     GST_ERROR_OBJECT (decoder,
1001         "no sequence or picture header before parsing picture header");
1002     return GST_FLOW_ERROR;
1003   }
1004 
1005   if (!gst_mpeg_video_packet_parse_slice_header (packet, &slice_hdr,
1006           &priv->seq_hdr,
1007           _seq_scalable_ext_is_valid (&priv->seq_scalable_ext) ?
1008           &priv->seq_scalable_ext : NULL)) {
1009     GST_ERROR_OBJECT (decoder, "failed to parse slice header");
1010     return GST_FLOW_ERROR;
1011   }
1012 
1013   slice.header = slice_hdr;
1014   slice.packet = *packet;
1015   slice.quant_matrix = _quant_matrix_ext_is_valid (&priv->quant_matrix) ?
1016       &priv->quant_matrix : NULL;
1017   g_assert (_pic_hdr_is_valid (&priv->pic_hdr));
1018   slice.pic_hdr = &priv->pic_hdr;
1019   slice.pic_ext = _pic_hdr_ext_is_valid (&priv->pic_ext) ?
1020       &priv->pic_ext : NULL;
1021   slice.sc_offset = slice.packet.offset - 4;
1022   slice.size = slice.packet.size + 4;
1023 
1024   ret = gst_mpeg2_decoder_ensure_current_picture (decoder, &slice);
1025   if (ret != GST_FLOW_OK) {
1026     GST_WARNING_OBJECT (decoder, "failed to start current picture");
1027     return ret;
1028   }
1029 
1030   g_assert (klass->decode_slice);
1031   ret = klass->decode_slice (decoder, priv->current_picture, &slice);
1032   if (ret != GST_FLOW_OK) {
1033     GST_WARNING_OBJECT (decoder,
1034         "Subclass didn't want to decode picture %p (frame_num %d, poc %d)",
1035         priv->current_picture, priv->current_picture->system_frame_number,
1036         priv->current_picture->pic_order_cnt);
1037     return ret;
1038   }
1039 
1040   priv->state |= GST_MPEG2_DECODER_STATE_GOT_SLICE;
1041 
1042   return GST_FLOW_OK;
1043 }
1044 
1045 static GstFlowReturn
gst_mpeg2_decoder_decode_packet(GstMpeg2Decoder * decoder,GstMpegVideoPacket * packet)1046 gst_mpeg2_decoder_decode_packet (GstMpeg2Decoder * decoder,
1047     GstMpegVideoPacket * packet)
1048 {
1049   GstMpegVideoPacketExtensionCode ext_type;
1050   GstFlowReturn ret = GST_FLOW_OK;
1051 
1052   GST_LOG_OBJECT (decoder, "Parsing the packet 0x%x, size %d",
1053       packet->type, packet->size);
1054   switch (packet->type) {
1055     case GST_MPEG_VIDEO_PACKET_PICTURE:{
1056       ret = gst_mpeg2_decoder_finish_current_field (decoder);
1057       if (ret != GST_FLOW_OK)
1058         break;
1059 
1060       ret = gst_mpeg2_decoder_handle_picture (decoder, packet);
1061       break;
1062     }
1063     case GST_MPEG_VIDEO_PACKET_SEQUENCE:
1064       ret = gst_mpeg2_decoder_handle_sequence (decoder, packet);
1065       break;
1066     case GST_MPEG_VIDEO_PACKET_EXTENSION:
1067       ext_type = packet->data[packet->offset] >> 4;
1068       GST_LOG_OBJECT (decoder, "  Parsing the ext packet 0x%x", ext_type);
1069       switch (ext_type) {
1070         case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE:
1071           ret = gst_mpeg2_decoder_handle_sequence_ext (decoder, packet);
1072           break;
1073         case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY:
1074           ret = gst_mpeg2_decoder_handle_sequence_display_ext (decoder, packet);
1075           break;
1076         case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE:
1077           ret =
1078               gst_mpeg2_decoder_handle_sequence_scalable_ext (decoder, packet);
1079           break;
1080         case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX:
1081           ret = gst_mpeg2_decoder_handle_quant_matrix_ext (decoder, packet);
1082           break;
1083         case GST_MPEG_VIDEO_PACKET_EXT_PICTURE:
1084           ret = gst_mpeg2_decoder_handle_picture_ext (decoder, packet);
1085           break;
1086         default:
1087           /* Ignore unknown start-code extensions */
1088           break;
1089       }
1090       break;
1091     case GST_MPEG_VIDEO_PACKET_SEQUENCE_END:
1092       break;
1093     case GST_MPEG_VIDEO_PACKET_GOP:
1094       ret = gst_mpeg2_decoder_handle_gop (decoder, packet);
1095       break;
1096     case GST_MPEG_VIDEO_PACKET_USER_DATA:
1097       break;
1098     default:
1099       if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
1100           packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
1101         ret = gst_mpeg2_decoder_handle_slice (decoder, packet);
1102         break;
1103       }
1104       GST_WARNING_OBJECT (decoder, "unsupported packet type 0x%02x, ignore",
1105           packet->type);
1106       break;
1107   }
1108 
1109   return ret;
1110 }
1111 
1112 static void
gst_mpeg2_decoder_do_output_picture(GstMpeg2Decoder * decoder,GstMpeg2Picture * to_output,GstFlowReturn * ret)1113 gst_mpeg2_decoder_do_output_picture (GstMpeg2Decoder * decoder,
1114     GstMpeg2Picture * to_output, GstFlowReturn * ret)
1115 {
1116   GstVideoCodecFrame *frame = NULL;
1117   GstMpeg2DecoderPrivate *priv = decoder->priv;
1118   GstMpeg2DecoderOutputFrame output_frame;
1119 
1120   g_assert (ret != NULL);
1121 
1122   frame =
1123       gst_video_decoder_get_frame (GST_VIDEO_DECODER (decoder),
1124       to_output->system_frame_number);
1125 
1126   if (!frame) {
1127     GST_ERROR_OBJECT (decoder,
1128         "No available codec frame with frame number %d",
1129         to_output->system_frame_number);
1130     UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
1131 
1132     gst_mpeg2_picture_unref (to_output);
1133 
1134     return;
1135   }
1136 
1137   output_frame.frame = frame;
1138   output_frame.picture = to_output;
1139   output_frame.self = decoder;
1140   gst_queue_array_push_tail_struct (priv->output_queue, &output_frame);
1141   gst_mpeg2_decoder_drain_output_queue (decoder, priv->preferred_output_delay,
1142       ret);
1143 }
1144 
1145 static GstFlowReturn
gst_mpeg2_decoder_output_current_picture(GstMpeg2Decoder * decoder)1146 gst_mpeg2_decoder_output_current_picture (GstMpeg2Decoder * decoder)
1147 {
1148   GstMpeg2DecoderPrivate *priv = decoder->priv;
1149   GstMpeg2Picture *picture = priv->current_picture;
1150   GstFlowReturn ret = GST_FLOW_OK;
1151 
1152   if (!picture && priv->first_field) {
1153     GST_WARNING_OBJECT (decoder, "Missing the second field");
1154     picture = priv->first_field;
1155   }
1156 
1157   g_assert (picture);
1158 
1159   /* Update the presentation time */
1160   priv->current_frame->pts = priv->current_pts;
1161 
1162   gst_mpeg2_dpb_add (priv->dpb, picture);
1163 
1164   GST_LOG_OBJECT (decoder,
1165       "Add picture %p (frame_num %d, poc %d, type 0x%x), into DPB", picture,
1166       picture->system_frame_number, picture->pic_order_cnt, picture->type);
1167 
1168   while (gst_mpeg2_dpb_need_bump (priv->dpb)) {
1169     GstMpeg2Picture *to_output;
1170 
1171     to_output = gst_mpeg2_dpb_bump (priv->dpb);
1172     g_assert (to_output);
1173 
1174     gst_mpeg2_decoder_do_output_picture (decoder, to_output, &ret);
1175     if (ret != GST_FLOW_OK)
1176       break;
1177   }
1178 
1179   return ret;
1180 }
1181 
1182 static void
gst_mpeg2_decoder_clear_output_frame(GstMpeg2DecoderOutputFrame * output_frame)1183 gst_mpeg2_decoder_clear_output_frame (GstMpeg2DecoderOutputFrame * output_frame)
1184 {
1185   if (!output_frame)
1186     return;
1187 
1188   if (output_frame->frame) {
1189     gst_video_decoder_release_frame (GST_VIDEO_DECODER (output_frame->self),
1190         output_frame->frame);
1191     output_frame->frame = NULL;
1192   }
1193 
1194   gst_mpeg2_picture_clear (&output_frame->picture);
1195 }
1196 
1197 static GstFlowReturn
gst_mpeg2_decoder_handle_frame(GstVideoDecoder * decoder,GstVideoCodecFrame * frame)1198 gst_mpeg2_decoder_handle_frame (GstVideoDecoder * decoder,
1199     GstVideoCodecFrame * frame)
1200 {
1201   GstMpeg2Decoder *self = GST_MPEG2_DECODER (decoder);
1202   GstMpeg2DecoderPrivate *priv = self->priv;
1203   GstBuffer *in_buf = frame->input_buffer;
1204   GstMapInfo map_info;
1205   GstMpegVideoPacket packet;
1206   GstFlowReturn ret = GST_FLOW_OK;
1207   guint offset;
1208   gboolean last_one;
1209 
1210   GST_LOG_OBJECT (self, "handle frame, PTS: %" GST_TIME_FORMAT
1211       ", DTS: %" GST_TIME_FORMAT " system frame number is %d",
1212       GST_TIME_ARGS (GST_BUFFER_PTS (in_buf)),
1213       GST_TIME_ARGS (GST_BUFFER_DTS (in_buf)), frame->system_frame_number);
1214 
1215   priv->state &= ~GST_MPEG2_DECODER_STATE_GOT_SLICE;
1216 
1217   priv->current_frame = frame;
1218   gst_buffer_map (in_buf, &map_info, GST_MAP_READ);
1219 
1220   offset = 0;
1221   last_one = FALSE;
1222   while (gst_mpeg_video_parse (&packet, map_info.data, map_info.size, offset)) {
1223     /* The packet is the last one */
1224     if (packet.size == -1) {
1225       if (packet.offset < map_info.size) {
1226         packet.size = map_info.size - packet.offset;
1227         last_one = TRUE;
1228       } else {
1229         GST_WARNING_OBJECT (decoder, "Get a packet with wrong size");
1230         break;
1231       }
1232     }
1233 
1234     ret = gst_mpeg2_decoder_decode_packet (self, &packet);
1235     if (ret != GST_FLOW_OK) {
1236       gst_buffer_unmap (in_buf, &map_info);
1237       GST_WARNING_OBJECT (decoder, "failed to handle the packet type 0x%x",
1238           packet.type);
1239       goto failed;
1240     }
1241 
1242     if (last_one)
1243       break;
1244 
1245     offset = packet.offset;
1246   }
1247 
1248   gst_buffer_unmap (in_buf, &map_info);
1249 
1250   if (!priv->current_picture) {
1251     GST_ERROR_OBJECT (decoder, "no valid picture created");
1252     goto failed;
1253   }
1254 
1255   ret = gst_mpeg2_decoder_finish_current_picture (self);
1256   if (ret != GST_FLOW_OK) {
1257     GST_ERROR_OBJECT (decoder, "failed to decode the current picture");
1258     goto failed;
1259   }
1260 
1261   ret = gst_mpeg2_decoder_output_current_picture (self);
1262   gst_mpeg2_picture_clear (&priv->current_picture);
1263   gst_mpeg2_picture_clear (&priv->first_field);
1264   gst_video_codec_frame_unref (priv->current_frame);
1265   priv->current_frame = NULL;
1266   return ret;
1267 
1268 failed:
1269   {
1270     if (ret == GST_FLOW_ERROR) {
1271       GST_VIDEO_DECODER_ERROR (decoder, 1, STREAM, DECODE,
1272           ("failed to handle the frame %d", frame->system_frame_number), (NULL),
1273           ret);
1274     }
1275 
1276     gst_video_decoder_drop_frame (decoder, frame);
1277     gst_mpeg2_picture_clear (&priv->current_picture);
1278     gst_mpeg2_picture_clear (&priv->first_field);
1279     priv->current_frame = NULL;
1280 
1281     return ret;
1282   }
1283 }
1284 
1285 static void
gst_mpeg2_decoder_drain_output_queue(GstMpeg2Decoder * self,guint num,GstFlowReturn * ret)1286 gst_mpeg2_decoder_drain_output_queue (GstMpeg2Decoder * self, guint num,
1287     GstFlowReturn * ret)
1288 {
1289   GstMpeg2DecoderPrivate *priv = self->priv;
1290   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (self);
1291   GstFlowReturn flow_ret;
1292 
1293   g_assert (klass->output_picture);
1294 
1295   while (gst_queue_array_get_length (priv->output_queue) > num) {
1296     GstMpeg2DecoderOutputFrame *output_frame = (GstMpeg2DecoderOutputFrame *)
1297         gst_queue_array_pop_head_struct (priv->output_queue);
1298     GST_LOG_OBJECT (self,
1299         "Output picture %p (frame_num %d, poc %d, pts: %" GST_TIME_FORMAT
1300         "), from DPB",
1301         output_frame->picture, output_frame->picture->system_frame_number,
1302         output_frame->picture->pic_order_cnt,
1303         GST_TIME_ARGS (output_frame->frame->pts));
1304 
1305     flow_ret =
1306         klass->output_picture (self, output_frame->frame,
1307         output_frame->picture);
1308 
1309     UPDATE_FLOW_RETURN (ret, flow_ret);
1310   }
1311 }
1312