ext/mpeg2dec/gstmpeg2dec.*: Crop if decoding size is not the actual image size (#163676).

Original commit message from CVS:
Reviewed by:  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
* ext/mpeg2dec/gstmpeg2dec.c: (crop_buffer),
(gst_mpeg2dec_alloc_buffer):
* ext/mpeg2dec/gstmpeg2dec.h:
Crop if decoding size is not the actual image size (#163676).
This commit is contained in:
Ronald S. Bultje 2005-01-17 13:54:30 +00:00
parent 4bf3fdb065
commit c68357a3a6
3 changed files with 97 additions and 6 deletions

View file

@ -1,3 +1,12 @@
2005-01-17 Francis Labonte <francis_labonte@hotmail.com>
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/mpeg2dec/gstmpeg2dec.c: (crop_buffer),
(gst_mpeg2dec_alloc_buffer):
* ext/mpeg2dec/gstmpeg2dec.h:
Crop if decoding size is not the actual image size (#163676).
2005-01-17 Steve Baker <steve@stevebaker.org>
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>

View file

@ -88,8 +88,7 @@ src_templ (void)
GstCaps *caps;
GstStructure *structure;
GValue list = { 0 }
, fps =
{
, fps = {
0}
, fmt = {
0};
@ -177,6 +176,8 @@ static void gst_mpeg2dec_chain (GstPad * pad, GstData * _data);
static GstElementClass *parent_class = NULL;
static GstBuffer *crop_buffer (GstMpeg2dec * mpeg2dec, GstBuffer * input);
/*static guint gst_mpeg2dec_signals[LAST_SIGNAL] = { 0 };*/
GType
@ -336,12 +337,84 @@ gst_mpeg2dec_get_index (GstElement * element)
return mpeg2dec->index;
}
static GstBuffer *
crop_buffer (GstMpeg2dec * mpeg2dec, GstBuffer * input)
{
unsigned char *in_data;
unsigned char *out_data;
uint h_subsample;
uint v_subsample;
uint line;
GstBuffer *outbuf = input;
/*We crop only if the target region is smaller than the input one */
if ((mpeg2dec->decoded_width > mpeg2dec->width) ||
(mpeg2dec->decoded_height > mpeg2dec->height)) {
/* If we don't know about the format, we just return the original
* buffer.
*/
if (mpeg2dec->format == MPEG2DEC_FORMAT_I422 ||
mpeg2dec->format == MPEG2DEC_FORMAT_I420 ||
mpeg2dec->format == MPEG2DEC_FORMAT_YV12) {
/*FIXME: I have tried to use gst_buffer_copy_on_write, but it
* still have some artifact, so I'me allocating new buffer
* for each frame decoded...
*/
if (mpeg2dec->format == MPEG2DEC_FORMAT_I422) {
outbuf =
gst_buffer_new_and_alloc (mpeg2dec->width * mpeg2dec->height * 2);
h_subsample = 2;
v_subsample = 1;
} else {
outbuf =
gst_buffer_new_and_alloc (mpeg2dec->width * mpeg2dec->height * 1.5);
h_subsample = 2;
v_subsample = 2;
}
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (input);
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (input);
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (input);
/* Copy Y first */
in_data = GST_BUFFER_DATA (input);
out_data = GST_BUFFER_DATA (outbuf);
for (line = 0; line < mpeg2dec->height; line++) {
memcpy (out_data, in_data, mpeg2dec->width);
out_data += mpeg2dec->width;
in_data += mpeg2dec->decoded_width;
}
/* Now copy U & V */
in_data =
GST_BUFFER_DATA (input) +
mpeg2dec->decoded_width * mpeg2dec->decoded_height;
for (line = 0; line < mpeg2dec->height / v_subsample; line++) {
memcpy (out_data, in_data, mpeg2dec->width / h_subsample);
memcpy (out_data +
mpeg2dec->width * mpeg2dec->height / (v_subsample * h_subsample),
in_data +
mpeg2dec->decoded_width * mpeg2dec->decoded_height / (v_subsample *
h_subsample), mpeg2dec->width / h_subsample);
out_data += mpeg2dec->width / h_subsample;
in_data += mpeg2dec->decoded_width / h_subsample;
}
gst_buffer_unref (input);
}
}
return outbuf;
}
static GstBuffer *
gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
gint64 offset)
{
GstBuffer *outbuf = NULL;
gint size = mpeg2dec->width * mpeg2dec->height;
gint size = mpeg2dec->decoded_width * mpeg2dec->decoded_height;
guint8 *buf[3], *out;
const mpeg2_picture_t *picture;
@ -585,10 +658,12 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
{
gint i;
mpeg2dec->width = info->sequence->width;
mpeg2dec->height = info->sequence->height;
mpeg2dec->width = info->sequence->picture_width;
mpeg2dec->height = info->sequence->picture_height;
mpeg2dec->pixel_width = info->sequence->pixel_width;
mpeg2dec->pixel_height = info->sequence->pixel_height;
mpeg2dec->decoded_width = info->sequence->width;
mpeg2dec->decoded_height = info->sequence->height;
mpeg2dec->total_frames = 0;
/* find framerate */
@ -771,6 +846,11 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
if ((mpeg2dec->decoded_height > mpeg2dec->height) ||
(mpeg2dec->decoded_width > mpeg2dec->width))
outbuf = crop_buffer (mpeg2dec, outbuf);
gst_pad_push (mpeg2dec->srcpad, GST_DATA (outbuf));
}
} else if (info->display_fbuf && !info->display_fbuf->id) {
@ -1272,7 +1352,7 @@ gst_mpeg2dec_get_property (GObject * object, guint prop_id, GValue * value,
static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_element_register (plugin, "mpeg2dec", GST_RANK_PRIMARY,
if (!gst_element_register (plugin, "mpeg2dec", GST_RANK_SECONDARY,
GST_TYPE_MPEG2DEC))
return FALSE;

View file

@ -81,6 +81,8 @@ struct _GstMpeg2dec {
Mpeg2decFormat format;
gint width;
gint height;
gint decoded_width;
gint decoded_height;
gint pixel_width;
gint pixel_height;
gint frame_rate_code;