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