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:
parent
4bf3fdb065
commit
c68357a3a6
@ -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>
|
2005-01-17 Steve Baker <steve@stevebaker.org>
|
||||||
|
|
||||||
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
@ -88,8 +88,7 @@ src_templ (void)
|
|||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
GValue list = { 0 }
|
GValue list = { 0 }
|
||||||
, fps =
|
, fps = {
|
||||||
{
|
|
||||||
0}
|
0}
|
||||||
, fmt = {
|
, fmt = {
|
||||||
0};
|
0};
|
||||||
@ -177,6 +176,8 @@ static void gst_mpeg2dec_chain (GstPad * pad, GstData * _data);
|
|||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
|
static GstBuffer *crop_buffer (GstMpeg2dec * mpeg2dec, GstBuffer * input);
|
||||||
|
|
||||||
/*static guint gst_mpeg2dec_signals[LAST_SIGNAL] = { 0 };*/
|
/*static guint gst_mpeg2dec_signals[LAST_SIGNAL] = { 0 };*/
|
||||||
|
|
||||||
GType
|
GType
|
||||||
@ -336,12 +337,84 @@ gst_mpeg2dec_get_index (GstElement * element)
|
|||||||
return mpeg2dec->index;
|
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 *
|
static GstBuffer *
|
||||||
gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
|
gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
|
||||||
gint64 offset)
|
gint64 offset)
|
||||||
{
|
{
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
gint size = mpeg2dec->width * mpeg2dec->height;
|
gint size = mpeg2dec->decoded_width * mpeg2dec->decoded_height;
|
||||||
guint8 *buf[3], *out;
|
guint8 *buf[3], *out;
|
||||||
const mpeg2_picture_t *picture;
|
const mpeg2_picture_t *picture;
|
||||||
|
|
||||||
@ -585,10 +658,12 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
mpeg2dec->width = info->sequence->width;
|
mpeg2dec->width = info->sequence->picture_width;
|
||||||
mpeg2dec->height = info->sequence->height;
|
mpeg2dec->height = info->sequence->picture_height;
|
||||||
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->decoded_width = info->sequence->width;
|
||||||
|
mpeg2dec->decoded_height = info->sequence->height;
|
||||||
mpeg2dec->total_frames = 0;
|
mpeg2dec->total_frames = 0;
|
||||||
|
|
||||||
/* find framerate */
|
/* find framerate */
|
||||||
@ -771,6 +846,11 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||||||
GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
|
GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (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));
|
gst_pad_push (mpeg2dec->srcpad, GST_DATA (outbuf));
|
||||||
}
|
}
|
||||||
} else if (info->display_fbuf && !info->display_fbuf->id) {
|
} 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
|
static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
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))
|
GST_TYPE_MPEG2DEC))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ struct _GstMpeg2dec {
|
|||||||
Mpeg2decFormat format;
|
Mpeg2decFormat format;
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
|
gint decoded_width;
|
||||||
|
gint decoded_height;
|
||||||
gint pixel_width;
|
gint pixel_width;
|
||||||
gint pixel_height;
|
gint pixel_height;
|
||||||
gint frame_rate_code;
|
gint frame_rate_code;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user