mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
Fix rowstrides
Original commit message from CVS: Fix rowstrides
This commit is contained in:
parent
ae541a6e16
commit
db93fd53ad
3 changed files with 63 additions and 38 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2005-02-18 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* ext/jpeg/gstjpegdec.c: (gst_jpegdec_chain):
|
||||||
|
* ext/jpeg/gstjpegenc.c: (gst_jpegenc_resync), (gst_jpegenc_chain):
|
||||||
|
Use same rowstrides for I420 as used everywhere else.
|
||||||
|
|
||||||
2005-02-17 Tim-Philipp Müller <tim at centricular dot net>
|
2005-02-17 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst/avi/gstavidemux.c: (gst_avi_demux_invert):
|
* gst/avi/gstavidemux.c: (gst_avi_demux_invert):
|
||||||
|
|
|
@ -37,18 +37,24 @@ GstElementDetails gst_jpegdec_details = {
|
||||||
GST_DEBUG_CATEGORY (jpegdec_debug);
|
GST_DEBUG_CATEGORY (jpegdec_debug);
|
||||||
#define GST_CAT_DEFAULT jpegdec_debug
|
#define GST_CAT_DEFAULT jpegdec_debug
|
||||||
|
|
||||||
/* JpegDec signals and args */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* FILL ME */
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
/* These macros are adapted from videotestsrc.c
|
||||||
{
|
* and/or gst-plugins/gst/games/gstvideoimage.c */
|
||||||
ARG_0
|
#define ROUND_UP_2(x) (((x)+1)&~1)
|
||||||
/* FILL ME */
|
#define ROUND_UP_4(x) (((x)+3)&~3)
|
||||||
};
|
#define ROUND_UP_8(x) (((x)+7)&~7)
|
||||||
|
|
||||||
|
/* I420 */
|
||||||
|
#define I420_Y_ROWSTRIDE(width) (ROUND_UP_4(width))
|
||||||
|
#define I420_U_ROWSTRIDE(width) (ROUND_UP_8(width)/2)
|
||||||
|
#define I420_V_ROWSTRIDE(width) ((ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
|
||||||
|
|
||||||
|
#define I420_Y_OFFSET(w,h) (0)
|
||||||
|
#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*ROUND_UP_2(h)))
|
||||||
|
#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*ROUND_UP_2(h)/2))
|
||||||
|
|
||||||
|
#define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*ROUND_UP_2(h)/2))
|
||||||
|
|
||||||
|
|
||||||
static void gst_jpegdec_base_init (gpointer g_class);
|
static void gst_jpegdec_base_init (gpointer g_class);
|
||||||
static void gst_jpegdec_class_init (GstJpegDec * klass);
|
static void gst_jpegdec_class_init (GstJpegDec * klass);
|
||||||
|
@ -375,7 +381,7 @@ gst_jpegdec_chain (GstPad * pad, GstData * _data)
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
|
||||||
/*GstMeta *meta; */
|
/*GstMeta *meta; */
|
||||||
gint width, height, width2;
|
gint width, height;
|
||||||
guchar *base[3];
|
guchar *base[3];
|
||||||
gint i, j, k;
|
gint i, j, k;
|
||||||
gint r_h, r_v;
|
gint r_h, r_v;
|
||||||
|
@ -443,7 +449,7 @@ gst_jpegdec_chain (GstPad * pad, GstData * _data)
|
||||||
/* FIXME: someone needs to do the work to figure out how to correctly
|
/* FIXME: someone needs to do the work to figure out how to correctly
|
||||||
* calculate an output size that takes into account everything libjpeg
|
* calculate an output size that takes into account everything libjpeg
|
||||||
* needs, like padding for DCT size and so on. */
|
* needs, like padding for DCT size and so on. */
|
||||||
outsize = width * height + width * height / 2;
|
outsize = I420_SIZE (width, height);
|
||||||
outbuf = gst_pad_alloc_buffer (jpegdec->srcpad, GST_BUFFER_OFFSET_NONE,
|
outbuf = gst_pad_alloc_buffer (jpegdec->srcpad, GST_BUFFER_OFFSET_NONE,
|
||||||
outsize);
|
outsize);
|
||||||
outdata = GST_BUFFER_DATA (outbuf);
|
outdata = GST_BUFFER_DATA (outbuf);
|
||||||
|
@ -453,28 +459,25 @@ gst_jpegdec_chain (GstPad * pad, GstData * _data)
|
||||||
height, outsize);
|
height, outsize);
|
||||||
|
|
||||||
/* mind the swap, jpeglib outputs blue chroma first */
|
/* mind the swap, jpeglib outputs blue chroma first */
|
||||||
/* FIXME: this needs stride love */
|
base[0] = outdata + I420_Y_OFFSET (width, height);
|
||||||
base[0] = outdata;
|
base[1] = outdata + I420_U_OFFSET (width, height);
|
||||||
base[1] = base[0] + width * height;
|
base[2] = outdata + I420_V_OFFSET (width, height);
|
||||||
base[2] = base[1] + width * height / 4;
|
|
||||||
|
|
||||||
width2 = width >> 1;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (jpegdec, "decompressing %u",
|
GST_LOG_OBJECT (jpegdec, "decompressing %u",
|
||||||
jpegdec->cinfo.rec_outbuf_height);
|
jpegdec->cinfo.rec_outbuf_height);
|
||||||
for (i = 0; i < height; i += r_v * DCTSIZE) {
|
for (i = 0; i < height; i += r_v * DCTSIZE) {
|
||||||
for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
|
for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
|
||||||
jpegdec->line[0][j] = base[0];
|
jpegdec->line[0][j] = base[0];
|
||||||
base[0] += width;
|
base[0] += I420_Y_ROWSTRIDE (width);
|
||||||
if (r_v == 2) {
|
if (r_v == 2) {
|
||||||
jpegdec->line[0][j + 1] = base[0];
|
jpegdec->line[0][j + 1] = base[0];
|
||||||
base[0] += width;
|
base[0] += I420_Y_ROWSTRIDE (width);
|
||||||
}
|
}
|
||||||
jpegdec->line[1][k] = base[1];
|
jpegdec->line[1][k] = base[1];
|
||||||
jpegdec->line[2][k] = base[2];
|
jpegdec->line[2][k] = base[2];
|
||||||
if (r_v == 2 || k & 1) {
|
if (r_v == 2 || k & 1) {
|
||||||
base[1] += width2;
|
base[1] += I420_U_ROWSTRIDE (width);
|
||||||
base[2] += width2;
|
base[2] += I420_V_ROWSTRIDE (width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*g_print ("%d\n", jpegdec->cinfo.output_scanline); */
|
/*g_print ("%d\n", jpegdec->cinfo.output_scanline); */
|
||||||
|
|
|
@ -39,6 +39,23 @@ GST_DEBUG_CATEGORY (jpegenc_debug);
|
||||||
|
|
||||||
#define JPEG_DEFAULT_QUALITY 85
|
#define JPEG_DEFAULT_QUALITY 85
|
||||||
|
|
||||||
|
/* These macros are adapted from videotestsrc.c
|
||||||
|
* and/or gst-plugins/gst/games/gstvideoimage.c */
|
||||||
|
#define ROUND_UP_2(x) (((x)+1)&~1)
|
||||||
|
#define ROUND_UP_4(x) (((x)+3)&~3)
|
||||||
|
#define ROUND_UP_8(x) (((x)+7)&~7)
|
||||||
|
|
||||||
|
/* I420 */
|
||||||
|
#define I420_Y_ROWSTRIDE(width) (ROUND_UP_4(width))
|
||||||
|
#define I420_U_ROWSTRIDE(width) (ROUND_UP_8(width)/2)
|
||||||
|
#define I420_V_ROWSTRIDE(width) ((ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
|
||||||
|
|
||||||
|
#define I420_Y_OFFSET(w,h) (0)
|
||||||
|
#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*ROUND_UP_2(h)))
|
||||||
|
#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*ROUND_UP_2(h)/2))
|
||||||
|
|
||||||
|
#define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*ROUND_UP_2(h)/2))
|
||||||
|
|
||||||
/* JpegEnc signals and args */
|
/* JpegEnc signals and args */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -291,7 +308,6 @@ gst_jpegenc_link (GstPad * pad, const GstCaps * caps)
|
||||||
static void
|
static void
|
||||||
gst_jpegenc_resync (GstJpegEnc * jpegenc)
|
gst_jpegenc_resync (GstJpegEnc * jpegenc)
|
||||||
{
|
{
|
||||||
guint size = 0;
|
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
|
||||||
GST_DEBUG ("gst_jpegenc_resync: resync");
|
GST_DEBUG ("gst_jpegenc_resync: resync");
|
||||||
|
@ -311,14 +327,14 @@ gst_jpegenc_resync (GstJpegEnc * jpegenc)
|
||||||
#if 0
|
#if 0
|
||||||
switch (jpegenc->format) {
|
switch (jpegenc->format) {
|
||||||
case GST_COLORSPACE_RGB24:
|
case GST_COLORSPACE_RGB24:
|
||||||
size = 3;
|
jpegenc->bufsize = jpegenc->width * jpegenc->height * 3;
|
||||||
GST_DEBUG ("gst_jpegenc_resync: setting format to RGB24");
|
GST_DEBUG ("gst_jpegenc_resync: setting format to RGB24");
|
||||||
jpegenc->cinfo.in_color_space = JCS_RGB;
|
jpegenc->cinfo.in_color_space = JCS_RGB;
|
||||||
jpegenc->cinfo.raw_data_in = FALSE;
|
jpegenc->cinfo.raw_data_in = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_COLORSPACE_YUV420P:
|
case GST_COLORSPACE_YUV420P:
|
||||||
#endif
|
#endif
|
||||||
size = 2;
|
jpegenc->bufsize = I420_SIZE (jpegenc->width, jpegenc->height);
|
||||||
jpegenc->cinfo.raw_data_in = TRUE;
|
jpegenc->cinfo.raw_data_in = TRUE;
|
||||||
jpegenc->cinfo.in_color_space = JCS_YCbCr;
|
jpegenc->cinfo.in_color_space = JCS_YCbCr;
|
||||||
GST_DEBUG ("gst_jpegenc_resync: setting format to YUV420P");
|
GST_DEBUG ("gst_jpegenc_resync: setting format to YUV420P");
|
||||||
|
@ -343,12 +359,11 @@ gst_jpegenc_resync (GstJpegEnc * jpegenc)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf ("gst_jpegenc_resync: unsupported colorspace, using RGB\n");
|
printf ("gst_jpegenc_resync: unsupported colorspace, using RGB\n");
|
||||||
size = 3;
|
jpegenc->bufsize = jpegenc->width * jpegenc->height * 3;
|
||||||
jpegenc->cinfo.in_color_space = JCS_RGB;
|
jpegenc->cinfo.in_color_space = JCS_RGB;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
jpegenc->bufsize = jpegenc->width * jpegenc->height * size;
|
|
||||||
|
|
||||||
jpeg_suppress_tables (&jpegenc->cinfo, TRUE);
|
jpeg_suppress_tables (&jpegenc->cinfo, TRUE);
|
||||||
//jpeg_suppress_tables(&jpegenc->cinfo, FALSE);
|
//jpeg_suppress_tables(&jpegenc->cinfo, FALSE);
|
||||||
|
@ -367,7 +382,7 @@ gst_jpegenc_chain (GstPad * pad, GstData * _data)
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
|
||||||
/* GstMeta *meta; */
|
/* GstMeta *meta; */
|
||||||
guint height, width, width2;
|
guint height, width;
|
||||||
guchar *base[3];
|
guchar *base[3];
|
||||||
gint i, j, k;
|
gint i, j, k;
|
||||||
|
|
||||||
|
@ -394,9 +409,9 @@ gst_jpegenc_chain (GstPad * pad, GstData * _data)
|
||||||
width = jpegenc->width;
|
width = jpegenc->width;
|
||||||
height = jpegenc->height;
|
height = jpegenc->height;
|
||||||
|
|
||||||
base[0] = data;
|
base[0] = data + I420_Y_OFFSET (width, height);
|
||||||
base[1] = base[0] + width * height;
|
base[1] = data + I420_U_OFFSET (width, height);
|
||||||
base[2] = base[1] + width * height / 4;
|
base[2] = data + I420_V_OFFSET (width, height);
|
||||||
|
|
||||||
jpegenc->jdest.next_output_byte = outdata;
|
jpegenc->jdest.next_output_byte = outdata;
|
||||||
jpegenc->jdest.free_in_buffer = outsize;
|
jpegenc->jdest.free_in_buffer = outsize;
|
||||||
|
@ -405,22 +420,23 @@ gst_jpegenc_chain (GstPad * pad, GstData * _data)
|
||||||
jpeg_set_quality (&jpegenc->cinfo, jpegenc->quality, TRUE);
|
jpeg_set_quality (&jpegenc->cinfo, jpegenc->quality, TRUE);
|
||||||
jpeg_start_compress (&jpegenc->cinfo, TRUE);
|
jpeg_start_compress (&jpegenc->cinfo, TRUE);
|
||||||
|
|
||||||
width2 = width >> 1;
|
|
||||||
GST_DEBUG ("gst_jpegdec_chain: compressing");
|
GST_DEBUG ("gst_jpegdec_chain: compressing");
|
||||||
|
|
||||||
for (i = 0; i < height; i += 2 * DCTSIZE) {
|
for (i = 0; i < height; i += 2 * DCTSIZE) {
|
||||||
for (j = 0, k = 0; j < 2 * DCTSIZE; j += 2, k++) {
|
/*g_print ("next scanline: %d\n", jpegenc->cinfo.next_scanline); */
|
||||||
|
for (j = 0, k = 0; j < (2 * DCTSIZE); j += 2, k++) {
|
||||||
jpegenc->line[0][j] = base[0];
|
jpegenc->line[0][j] = base[0];
|
||||||
base[0] += width;
|
base[0] += I420_Y_ROWSTRIDE (width);
|
||||||
jpegenc->line[0][j + 1] = base[0];
|
jpegenc->line[0][j + 1] = base[0];
|
||||||
base[0] += width;
|
base[0] += I420_Y_ROWSTRIDE (width);
|
||||||
jpegenc->line[1][k] = base[1];
|
jpegenc->line[1][k] = base[1];
|
||||||
base[1] += width2;
|
base[1] += I420_U_ROWSTRIDE (width);
|
||||||
jpegenc->line[2][k] = base[2];
|
jpegenc->line[2][k] = base[2];
|
||||||
base[2] += width2;
|
base[2] += I420_V_ROWSTRIDE (width);
|
||||||
}
|
}
|
||||||
jpeg_write_raw_data (&jpegenc->cinfo, jpegenc->line, 2 * DCTSIZE);
|
jpeg_write_raw_data (&jpegenc->cinfo, jpegenc->line, 2 * DCTSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
jpeg_finish_compress (&jpegenc->cinfo);
|
jpeg_finish_compress (&jpegenc->cinfo);
|
||||||
GST_DEBUG ("gst_jpegdec_chain: compressing done");
|
GST_DEBUG ("gst_jpegdec_chain: compressing done");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue