mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
- Fix decode error, CVS libmpeg2 has a new state
Original commit message from CVS: - Fix decode error, CVS libmpeg2 has a new state - use libmpeg2 pts handling for better sync - cleanups
This commit is contained in:
parent
d27545a678
commit
d8b37c7162
2 changed files with 48 additions and 20 deletions
|
@ -207,15 +207,13 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec *mpeg2dec, const mpeg2_info_t *info)
|
|||
GstBuffer *outbuf = NULL;
|
||||
gint size = mpeg2dec->width * mpeg2dec->height;
|
||||
guint8 *buf[3], *out;
|
||||
const picture_t *picture;
|
||||
|
||||
if (mpeg2dec->peerpool) {
|
||||
outbuf = gst_buffer_new_from_pool (mpeg2dec->peerpool, 0, 0);
|
||||
}
|
||||
if (!outbuf) {
|
||||
outbuf = gst_buffer_new ();
|
||||
|
||||
GST_BUFFER_SIZE (outbuf) = (size * 3) / 2;
|
||||
GST_BUFFER_DATA (outbuf) = g_malloc0 ((size * 3)/2);
|
||||
outbuf = gst_buffer_new_and_alloc ((size * 3) / 2);
|
||||
}
|
||||
|
||||
out = GST_BUFFER_DATA (outbuf);
|
||||
|
@ -233,10 +231,15 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec *mpeg2dec, const mpeg2_info_t *info)
|
|||
gst_buffer_ref (outbuf);
|
||||
mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf);
|
||||
|
||||
if (info->current_picture && (info->current_picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_I)
|
||||
picture = info->current_picture;
|
||||
|
||||
if (picture && (picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_I)
|
||||
{
|
||||
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_KEY_UNIT);
|
||||
else
|
||||
}
|
||||
else {
|
||||
GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_KEY_UNIT);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -313,9 +316,7 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
|
|||
//mpeg2dec->decoder->is_sequence_needed = 1;
|
||||
GST_DEBUG (GST_CAT_EVENT, "mpeg2dec: discont\n");
|
||||
mpeg2dec->first = TRUE;
|
||||
mpeg2dec->frames_per_PTS = 0;
|
||||
mpeg2dec->last_PTS = -1;
|
||||
mpeg2dec->adjust = 0;
|
||||
mpeg2dec->next_time = 0;
|
||||
mpeg2dec->discont_pending = TRUE;
|
||||
gst_pad_event_default (pad, event);
|
||||
|
@ -341,7 +342,9 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
|
|||
info = mpeg2_info (mpeg2dec->decoder);
|
||||
end = data + size;
|
||||
|
||||
mpeg2_pts (mpeg2dec->decoder, GSTTIME_TO_MPEGTIME (pts));
|
||||
mpeg2_buffer (mpeg2dec->decoder, data, end);
|
||||
|
||||
while (!done) {
|
||||
state = mpeg2_parse (mpeg2dec->decoder);
|
||||
switch (state) {
|
||||
|
@ -352,6 +355,7 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
|
|||
mpeg2dec->pixel_width = info->sequence->pixel_width;
|
||||
mpeg2dec->pixel_height = info->sequence->pixel_height;
|
||||
mpeg2dec->total_frames = 0;
|
||||
mpeg2dec->frame_period = info->sequence->frame_period * GST_USECOND / 27;
|
||||
|
||||
if (!gst_mpeg2dec_negotiate_format (mpeg2dec)) {
|
||||
gst_element_error (GST_ELEMENT (mpeg2dec), "could not negotiate format");
|
||||
|
@ -361,6 +365,8 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
|
|||
gst_mpeg2dec_alloc_buffer (mpeg2dec, info);
|
||||
break;
|
||||
}
|
||||
case STATE_SEQUENCE_REPEATED:
|
||||
break;
|
||||
case STATE_GOP:
|
||||
break;
|
||||
case STATE_PICTURE:
|
||||
|
@ -387,13 +393,30 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
|
|||
GstBuffer *outbuf = NULL;
|
||||
|
||||
if (info->display_fbuf && info->display_fbuf->id) {
|
||||
const picture_t *picture;
|
||||
|
||||
outbuf = (GstBuffer *) info->display_fbuf->id;
|
||||
picture = info->display_picture;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = mpeg2dec->next_time;
|
||||
mpeg2dec->next_time += info->sequence->frame_period * GST_USECOND / 27;
|
||||
if (picture->flags & PIC_FLAG_PTS) {
|
||||
GstClockTime time = MPEGTIME_TO_GSTTIME (picture->pts);
|
||||
|
||||
if (mpeg2dec->discont_pending ||
|
||||
(mpeg2dec->first && !GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_KEY_UNIT))) {
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = time;
|
||||
|
||||
mpeg2dec->next_time = time + mpeg2dec->frame_period;
|
||||
}
|
||||
else {
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = mpeg2dec->next_time;
|
||||
mpeg2dec->next_time += mpeg2dec->frame_period;
|
||||
}
|
||||
|
||||
/*
|
||||
if (picture->flags & PIC_FLAG_SKIP ||
|
||||
mpeg2dec->discont_pending ||
|
||||
(mpeg2dec->first && !GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_KEY_UNIT)))
|
||||
{
|
||||
*/
|
||||
if (picture->flags & PIC_FLAG_SKIP) {
|
||||
gst_buffer_unref (outbuf);
|
||||
}
|
||||
else {
|
||||
|
@ -412,11 +435,15 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
|
|||
done = TRUE;
|
||||
break;
|
||||
/* error */
|
||||
default:
|
||||
case STATE_INVALID:
|
||||
gst_element_error (GST_ELEMENT (mpeg2dec), "fatal error");
|
||||
done = TRUE;
|
||||
break;
|
||||
default:
|
||||
g_warning ("%s: unhandled state %d, FIXME",
|
||||
gst_element_get_name (GST_ELEMENT (mpeg2dec)),
|
||||
state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
gst_buffer_unref(buf);
|
||||
|
@ -520,8 +547,8 @@ gst_mpeg2dec_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
|||
case GST_FORMAT_BYTES:
|
||||
scale = 6 * (mpeg2dec->width * mpeg2dec->height >> 2);
|
||||
case GST_FORMAT_UNITS:
|
||||
if (info->sequence && info->sequence->frame_period) {
|
||||
*dest_value = src_value * scale * 27 / (info->sequence->frame_period * GST_USECOND);
|
||||
if (info->sequence && mpeg2dec->frame_period) {
|
||||
*dest_value = src_value * scale / mpeg2dec->frame_period;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -533,7 +560,7 @@ gst_mpeg2dec_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
|||
case GST_FORMAT_DEFAULT:
|
||||
*dest_format = GST_FORMAT_TIME;
|
||||
case GST_FORMAT_TIME:
|
||||
*dest_value = src_value * info->sequence->frame_period * GST_USECOND / 27;
|
||||
*dest_value = src_value * mpeg2dec->frame_period;
|
||||
break;
|
||||
case GST_FORMAT_BYTES:
|
||||
*dest_value = src_value * 6 * ((mpeg2dec->width * mpeg2dec->height) >> 2);
|
||||
|
@ -745,10 +772,9 @@ gst_mpeg2dec_change_state (GstElement *element)
|
|||
mpeg2dec->width = -1;
|
||||
mpeg2dec->height = -1;
|
||||
mpeg2dec->first = TRUE;
|
||||
mpeg2dec->frames_per_PTS = 0;
|
||||
mpeg2dec->last_PTS = -1;
|
||||
mpeg2dec->adjust = 0;
|
||||
mpeg2dec->discont_pending = TRUE;
|
||||
mpeg2dec->frame_period = 0;
|
||||
break;
|
||||
}
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
|
|
|
@ -43,6 +43,9 @@ extern "C" {
|
|||
#define GST_IS_MPEG2DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEG2DEC))
|
||||
|
||||
#define MPEGTIME_TO_GSTTIME(time) (((time) * (GST_MSECOND/10)) / 9LL)
|
||||
#define GSTTIME_TO_MPEGTIME(time) (((time) * 9LL) / (GST_MSECOND/10))
|
||||
|
||||
typedef struct _GstMpeg2dec GstMpeg2dec;
|
||||
typedef struct _GstMpeg2decClass GstMpeg2decClass;
|
||||
|
||||
|
@ -70,8 +73,6 @@ struct _GstMpeg2dec {
|
|||
gboolean discont_pending;
|
||||
gint64 next_time;
|
||||
gint64 last_PTS;
|
||||
gint frames_per_PTS;
|
||||
gint adjust;
|
||||
|
||||
/* video state */
|
||||
Mpeg2decFormat format;
|
||||
|
@ -81,6 +82,7 @@ struct _GstMpeg2dec {
|
|||
gint pixel_height;
|
||||
gint frame_rate_code;
|
||||
gint64 total_frames;
|
||||
gint64 frame_period;
|
||||
};
|
||||
|
||||
struct _GstMpeg2decClass {
|
||||
|
|
Loading…
Reference in a new issue