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