mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
ext/ffmpeg/: Move palette handling over from the decoder to the colorspace conversion plugin (where you would expect ...
Original commit message from CVS: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_pixfmt_to_caps), (gst_ffmpeg_caps_to_pixfmt): * ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_pad_link), (gst_ffmpegcsp_init), (gst_ffmpegcsp_chain), (gst_ffmpegcsp_change_state), (gst_ffmpegcsp_register): * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain): Move palette handling over from the decoder to the colorspace conversion plugin (where you would expect it).
This commit is contained in:
parent
7c945b8254
commit
79d1288887
4 changed files with 117 additions and 67 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2004-10-02 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
|
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_pixfmt_to_caps),
|
||||||
|
(gst_ffmpeg_caps_to_pixfmt):
|
||||||
|
* ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_pad_link),
|
||||||
|
(gst_ffmpegcsp_init), (gst_ffmpegcsp_chain),
|
||||||
|
(gst_ffmpegcsp_change_state), (gst_ffmpegcsp_register):
|
||||||
|
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_chain):
|
||||||
|
Move palette handling over from the decoder to the colorspace
|
||||||
|
conversion plugin (where you would expect it).
|
||||||
|
|
||||||
2004-10-01 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
2004-10-01 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps),
|
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps),
|
||||||
|
|
|
@ -783,19 +783,33 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context)
|
||||||
g_mask = 0x03e0;
|
g_mask = 0x03e0;
|
||||||
b_mask = 0x001f;
|
b_mask = 0x001f;
|
||||||
break;
|
break;
|
||||||
|
case PIX_FMT_PAL8:
|
||||||
|
bpp = depth = 8;
|
||||||
|
endianness = G_BYTE_ORDER;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* give up ... */
|
/* give up ... */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpp != 0) {
|
if (bpp != 0) {
|
||||||
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-rgb",
|
if (r_mask != 0) {
|
||||||
"bpp", G_TYPE_INT, bpp,
|
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-rgb",
|
||||||
"depth", G_TYPE_INT, depth,
|
"bpp", G_TYPE_INT, bpp,
|
||||||
"red_mask", G_TYPE_INT, r_mask,
|
"depth", G_TYPE_INT, depth,
|
||||||
"green_mask", G_TYPE_INT, g_mask,
|
"red_mask", G_TYPE_INT, r_mask,
|
||||||
"blue_mask", G_TYPE_INT, b_mask,
|
"green_mask", G_TYPE_INT, g_mask,
|
||||||
"endianness", G_TYPE_INT, endianness, NULL);
|
"blue_mask", G_TYPE_INT, b_mask,
|
||||||
|
"endianness", G_TYPE_INT, endianness, NULL);
|
||||||
|
} else {
|
||||||
|
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-rgb",
|
||||||
|
"bpp", G_TYPE_INT, bpp,
|
||||||
|
"depth", G_TYPE_INT, depth,
|
||||||
|
"endianness", G_TYPE_INT, endianness, NULL);
|
||||||
|
if (context) {
|
||||||
|
gst_ffmpeg_set_palette (caps, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (fmt) {
|
} else if (fmt) {
|
||||||
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-yuv",
|
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-yuv",
|
||||||
"format", GST_TYPE_FOURCC, fmt, NULL);
|
"format", GST_TYPE_FOURCC, fmt, NULL);
|
||||||
|
@ -1012,34 +1026,40 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
|
||||||
gint bpp = 0, rmask = 0, endianness = 0;
|
gint bpp = 0, rmask = 0, endianness = 0;
|
||||||
|
|
||||||
if (gst_structure_get_int (structure, "bpp", &bpp) &&
|
if (gst_structure_get_int (structure, "bpp", &bpp) &&
|
||||||
gst_structure_get_int (structure, "endianness", &endianness) &&
|
gst_structure_get_int (structure, "endianness", &endianness)) {
|
||||||
gst_structure_get_int (structure, "red_mask", &rmask)) {
|
if (gst_structure_get_int (structure, "red_mask", &rmask)) {
|
||||||
switch (bpp) {
|
switch (bpp) {
|
||||||
case 32:
|
case 32:
|
||||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||||
if (rmask == 0x00ff0000)
|
if (rmask == 0x00ff0000)
|
||||||
#else
|
#else
|
||||||
if (rmask == 0x0000ff00)
|
if (rmask == 0x0000ff00)
|
||||||
#endif
|
#endif
|
||||||
context->pix_fmt = PIX_FMT_RGBA32;
|
context->pix_fmt = PIX_FMT_RGBA32;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
if (rmask == 0x0000FF)
|
if (rmask == 0x0000FF)
|
||||||
context->pix_fmt = PIX_FMT_BGR24;
|
context->pix_fmt = PIX_FMT_BGR24;
|
||||||
else
|
else
|
||||||
context->pix_fmt = PIX_FMT_RGB24;
|
context->pix_fmt = PIX_FMT_RGB24;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
if (endianness == G_BYTE_ORDER)
|
if (endianness == G_BYTE_ORDER)
|
||||||
context->pix_fmt = PIX_FMT_RGB565;
|
context->pix_fmt = PIX_FMT_RGB565;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
if (endianness == G_BYTE_ORDER)
|
if (endianness == G_BYTE_ORDER)
|
||||||
context->pix_fmt = PIX_FMT_RGB555;
|
context->pix_fmt = PIX_FMT_RGB555;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* nothing */
|
/* nothing */
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bpp == 8) {
|
||||||
|
context->pix_fmt = PIX_FMT_PAL8;
|
||||||
|
gst_ffmpeg_get_palette (caps, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct _GstFFMpegCsp
|
||||||
gfloat fps;
|
gfloat fps;
|
||||||
enum PixelFormat from_pixfmt, to_pixfmt;
|
enum PixelFormat from_pixfmt, to_pixfmt;
|
||||||
AVFrame *from_frame, *to_frame;
|
AVFrame *from_frame, *to_frame;
|
||||||
|
AVPaletteControl *palette;
|
||||||
GstCaps *sinkcaps;
|
GstCaps *sinkcaps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,6 +228,11 @@ gst_ffmpegcsp_pad_link (GstPad * pad, const GstCaps * caps)
|
||||||
space->to_pixfmt = ctx->pix_fmt;
|
space->to_pixfmt = ctx->pix_fmt;
|
||||||
} else {
|
} else {
|
||||||
space->from_pixfmt = ctx->pix_fmt;
|
space->from_pixfmt = ctx->pix_fmt;
|
||||||
|
|
||||||
|
/* palette */
|
||||||
|
if (space->palette)
|
||||||
|
av_free (space->palette);
|
||||||
|
space->palette = ctx->palctrl;
|
||||||
}
|
}
|
||||||
av_free (ctx);
|
av_free (ctx);
|
||||||
if (space->from_frame)
|
if (space->from_frame)
|
||||||
|
@ -311,6 +317,7 @@ gst_ffmpegcsp_init (GstFFMpegCsp * space)
|
||||||
|
|
||||||
space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
|
space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
|
||||||
space->from_frame = space->to_frame = NULL;
|
space->from_frame = space->to_frame = NULL;
|
||||||
|
space->palette = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -344,25 +351,54 @@ gst_ffmpegcsp_chain (GstPad * pad, GstData * data)
|
||||||
if (space->from_pixfmt == space->to_pixfmt) {
|
if (space->from_pixfmt == space->to_pixfmt) {
|
||||||
outbuf = inbuf;
|
outbuf = inbuf;
|
||||||
} else {
|
} else {
|
||||||
/* use bufferpool here */
|
enum PixelFormat from_pixfmt =
|
||||||
|
(space->from_pixfmt == PIX_FMT_PAL8) ?
|
||||||
|
PIX_FMT_RGBA32 : space->from_pixfmt;
|
||||||
guint size = avpicture_get_size (space->to_pixfmt,
|
guint size = avpicture_get_size (space->to_pixfmt,
|
||||||
space->width,
|
space->width, space->height);
|
||||||
space->height);
|
GstBuffer *inbuf2;
|
||||||
|
|
||||||
|
if (from_pixfmt != space->from_pixfmt) {
|
||||||
|
/* manual conversion from palette to RGBA32 */
|
||||||
|
gint x, y, pix, wd = space->width;
|
||||||
|
guint8 *dest;
|
||||||
|
guint32 conv;
|
||||||
|
AVPaletteControl *pal = space->palette;
|
||||||
|
|
||||||
|
inbuf2 = gst_buffer_new_and_alloc (4 *
|
||||||
|
space->width * space->height);
|
||||||
|
dest = GST_BUFFER_DATA (inbuf2);
|
||||||
|
|
||||||
|
for (y = 0; y < space->height; y++) {
|
||||||
|
for (x = 0; x < space->width; x++) {
|
||||||
|
pix = GST_BUFFER_DATA (inbuf)[y * wd + x];
|
||||||
|
conv = pal->palette[pix];
|
||||||
|
dest[(y * wd + x) * 4] = ((guint8 *) &conv)[0];
|
||||||
|
dest[(y * wd + x) * 4 + 1] = ((guint8 *) &conv)[1];
|
||||||
|
dest[(y * wd + x) * 4 + 2] = ((guint8 *) &conv)[2];
|
||||||
|
dest[(y * wd + x) * 4 + 3] = ((guint8 *) &conv)[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inbuf2 = inbuf;
|
||||||
|
}
|
||||||
|
|
||||||
outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE, size);
|
outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE, size);
|
||||||
|
|
||||||
/* convert */
|
/* convert */
|
||||||
avpicture_fill ((AVPicture *) space->from_frame, GST_BUFFER_DATA (inbuf),
|
avpicture_fill ((AVPicture *) space->from_frame, GST_BUFFER_DATA (inbuf2),
|
||||||
space->from_pixfmt, space->width, space->height);
|
from_pixfmt, space->width, space->height);
|
||||||
avpicture_fill ((AVPicture *) space->to_frame, GST_BUFFER_DATA (outbuf),
|
avpicture_fill ((AVPicture *) space->to_frame, GST_BUFFER_DATA (outbuf),
|
||||||
space->to_pixfmt, space->width, space->height);
|
space->to_pixfmt, space->width, space->height);
|
||||||
img_convert ((AVPicture *) space->to_frame, space->to_pixfmt,
|
img_convert ((AVPicture *) space->to_frame, space->to_pixfmt,
|
||||||
(AVPicture *) space->from_frame, space->from_pixfmt,
|
(AVPicture *) space->from_frame, from_pixfmt,
|
||||||
space->width, space->height);
|
space->width, space->height);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
|
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
|
||||||
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
|
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
|
||||||
|
|
||||||
|
if (inbuf != inbuf2)
|
||||||
|
gst_buffer_unref (inbuf2);
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,8 +418,11 @@ gst_ffmpegcsp_change_state (GstElement * element)
|
||||||
av_free (space->from_frame);
|
av_free (space->from_frame);
|
||||||
if (space->to_frame)
|
if (space->to_frame)
|
||||||
av_free (space->to_frame);
|
av_free (space->to_frame);
|
||||||
|
if (space->palette)
|
||||||
|
av_free (space->palette);
|
||||||
space->from_frame = NULL;
|
space->from_frame = NULL;
|
||||||
space->to_frame = NULL;
|
space->to_frame = NULL;
|
||||||
|
space->palette = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,6 +476,8 @@ gst_ffmpegcsp_register (GstPlugin * plugin)
|
||||||
/* build templates */
|
/* build templates */
|
||||||
srctempl = gst_pad_template_new ("src",
|
srctempl = gst_pad_template_new ("src",
|
||||||
GST_PAD_SRC, GST_PAD_ALWAYS, gst_caps_copy (caps));
|
GST_PAD_SRC, GST_PAD_ALWAYS, gst_caps_copy (caps));
|
||||||
|
|
||||||
|
/* the sink template will do palette handling as well... */
|
||||||
sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps);
|
sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps);
|
||||||
|
|
||||||
return gst_element_register (plugin, "ffcolorspace",
|
return gst_element_register (plugin, "ffcolorspace",
|
||||||
|
|
|
@ -409,40 +409,18 @@ gst_ffmpegdec_chain (GstPad * pad, GstData * _data)
|
||||||
* errors inside. This drives me crazy, so we let it allocate
|
* errors inside. This drives me crazy, so we let it allocate
|
||||||
* it's own buffers and copy to our own buffer afterwards... */
|
* it's own buffers and copy to our own buffer afterwards... */
|
||||||
AVPicture pic;
|
AVPicture pic;
|
||||||
enum PixelFormat to_fmt =
|
gint size = avpicture_get_size (ffmpegdec->context->pix_fmt,
|
||||||
(ffmpegdec->context->pix_fmt == PIX_FMT_PAL8) ?
|
|
||||||
PIX_FMT_RGBA32 : ffmpegdec->context->pix_fmt;
|
|
||||||
gint size = avpicture_get_size (to_fmt,
|
|
||||||
ffmpegdec->context->width,
|
ffmpegdec->context->width,
|
||||||
ffmpegdec->context->height);
|
ffmpegdec->context->height);
|
||||||
|
|
||||||
outbuf = gst_buffer_new_and_alloc (size);
|
outbuf = gst_buffer_new_and_alloc (size);
|
||||||
avpicture_fill (&pic, GST_BUFFER_DATA (outbuf), to_fmt,
|
avpicture_fill (&pic, GST_BUFFER_DATA (outbuf),
|
||||||
|
ffmpegdec->context->pix_fmt,
|
||||||
|
ffmpegdec->context->width, ffmpegdec->context->height);
|
||||||
|
img_convert (&pic, ffmpegdec->context->pix_fmt,
|
||||||
|
(AVPicture *) ffmpegdec->picture,
|
||||||
|
ffmpegdec->context->pix_fmt,
|
||||||
ffmpegdec->context->width, ffmpegdec->context->height);
|
ffmpegdec->context->width, ffmpegdec->context->height);
|
||||||
if (to_fmt == ffmpegdec->context->pix_fmt) {
|
|
||||||
img_convert (&pic, ffmpegdec->context->pix_fmt,
|
|
||||||
(AVPicture *) ffmpegdec->picture,
|
|
||||||
ffmpegdec->context->pix_fmt,
|
|
||||||
ffmpegdec->context->width, ffmpegdec->context->height);
|
|
||||||
} else {
|
|
||||||
/* manual conversion from palette to RGBA32 */
|
|
||||||
gint x, y, pix, ws = ffmpegdec->picture->linesize[0],
|
|
||||||
wd = ffmpegdec->context->width;
|
|
||||||
guint8 *dest = GST_BUFFER_DATA (outbuf);
|
|
||||||
guint32 conv;
|
|
||||||
AVPaletteControl *pal = ffmpegdec->context->palctrl;
|
|
||||||
|
|
||||||
for (y = 0; y < ffmpegdec->context->height; y++) {
|
|
||||||
for (x = 0; x < ffmpegdec->context->width; x++) {
|
|
||||||
pix = ffmpegdec->picture->data[0][y * ws + x];
|
|
||||||
conv = pal->palette[pix];
|
|
||||||
dest[(y * wd + x) * 4] = ((guint8 *) &conv)[0];
|
|
||||||
dest[(y * wd + x) * 4 + 1] = ((guint8 *) &conv)[1];
|
|
||||||
dest[(y * wd + x) * 4 + 2] = ((guint8 *) &conv)[2];
|
|
||||||
dest[(y * wd + x) * 4 + 3] = ((guint8 *) &conv)[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* note that ffmpeg sometimes gets the FPS wrong */
|
/* note that ffmpeg sometimes gets the FPS wrong */
|
||||||
if (GST_CLOCK_TIME_IS_VALID (expected_ts)) {
|
if (GST_CLOCK_TIME_IS_VALID (expected_ts)) {
|
||||||
|
|
Loading…
Reference in a new issue