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>
|
||||
|
||||
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps),
|
||||
|
|
|
@ -783,12 +783,17 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context)
|
|||
g_mask = 0x03e0;
|
||||
b_mask = 0x001f;
|
||||
break;
|
||||
case PIX_FMT_PAL8:
|
||||
bpp = depth = 8;
|
||||
endianness = G_BYTE_ORDER;
|
||||
break;
|
||||
default:
|
||||
/* give up ... */
|
||||
break;
|
||||
}
|
||||
|
||||
if (bpp != 0) {
|
||||
if (r_mask != 0) {
|
||||
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-rgb",
|
||||
"bpp", G_TYPE_INT, bpp,
|
||||
"depth", G_TYPE_INT, depth,
|
||||
|
@ -796,6 +801,15 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context)
|
|||
"green_mask", G_TYPE_INT, g_mask,
|
||||
"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) {
|
||||
caps = GST_FF_VID_CAPS_NEW ("video/x-raw-yuv",
|
||||
"format", GST_TYPE_FOURCC, fmt, NULL);
|
||||
|
@ -1012,8 +1026,8 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
|
|||
gint bpp = 0, rmask = 0, endianness = 0;
|
||||
|
||||
if (gst_structure_get_int (structure, "bpp", &bpp) &&
|
||||
gst_structure_get_int (structure, "endianness", &endianness) &&
|
||||
gst_structure_get_int (structure, "red_mask", &rmask)) {
|
||||
gst_structure_get_int (structure, "endianness", &endianness)) {
|
||||
if (gst_structure_get_int (structure, "red_mask", &rmask)) {
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||
|
@ -1041,6 +1055,12 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
|
|||
/* nothing */
|
||||
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;
|
||||
enum PixelFormat from_pixfmt, to_pixfmt;
|
||||
AVFrame *from_frame, *to_frame;
|
||||
AVPaletteControl *palette;
|
||||
GstCaps *sinkcaps;
|
||||
};
|
||||
|
||||
|
@ -227,6 +228,11 @@ gst_ffmpegcsp_pad_link (GstPad * pad, const GstCaps * caps)
|
|||
space->to_pixfmt = ctx->pix_fmt;
|
||||
} else {
|
||||
space->from_pixfmt = ctx->pix_fmt;
|
||||
|
||||
/* palette */
|
||||
if (space->palette)
|
||||
av_free (space->palette);
|
||||
space->palette = ctx->palctrl;
|
||||
}
|
||||
av_free (ctx);
|
||||
if (space->from_frame)
|
||||
|
@ -311,6 +317,7 @@ gst_ffmpegcsp_init (GstFFMpegCsp * space)
|
|||
|
||||
space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
|
||||
space->from_frame = space->to_frame = NULL;
|
||||
space->palette = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -344,25 +351,54 @@ gst_ffmpegcsp_chain (GstPad * pad, GstData * data)
|
|||
if (space->from_pixfmt == space->to_pixfmt) {
|
||||
outbuf = inbuf;
|
||||
} 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,
|
||||
space->width,
|
||||
space->height);
|
||||
space->width, 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);
|
||||
|
||||
/* convert */
|
||||
avpicture_fill ((AVPicture *) space->from_frame, GST_BUFFER_DATA (inbuf),
|
||||
space->from_pixfmt, space->width, space->height);
|
||||
avpicture_fill ((AVPicture *) space->from_frame, GST_BUFFER_DATA (inbuf2),
|
||||
from_pixfmt, space->width, space->height);
|
||||
avpicture_fill ((AVPicture *) space->to_frame, GST_BUFFER_DATA (outbuf),
|
||||
space->to_pixfmt, space->width, space->height);
|
||||
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);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
|
||||
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
|
||||
|
||||
if (inbuf != inbuf2)
|
||||
gst_buffer_unref (inbuf2);
|
||||
gst_buffer_unref (inbuf);
|
||||
}
|
||||
|
||||
|
@ -382,8 +418,11 @@ gst_ffmpegcsp_change_state (GstElement * element)
|
|||
av_free (space->from_frame);
|
||||
if (space->to_frame)
|
||||
av_free (space->to_frame);
|
||||
if (space->palette)
|
||||
av_free (space->palette);
|
||||
space->from_frame = NULL;
|
||||
space->to_frame = NULL;
|
||||
space->palette = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -437,6 +476,8 @@ gst_ffmpegcsp_register (GstPlugin * plugin)
|
|||
/* build templates */
|
||||
srctempl = gst_pad_template_new ("src",
|
||||
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);
|
||||
|
||||
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
|
||||
* it's own buffers and copy to our own buffer afterwards... */
|
||||
AVPicture pic;
|
||||
enum PixelFormat to_fmt =
|
||||
(ffmpegdec->context->pix_fmt == PIX_FMT_PAL8) ?
|
||||
PIX_FMT_RGBA32 : ffmpegdec->context->pix_fmt;
|
||||
gint size = avpicture_get_size (to_fmt,
|
||||
gint size = avpicture_get_size (ffmpegdec->context->pix_fmt,
|
||||
ffmpegdec->context->width,
|
||||
ffmpegdec->context->height);
|
||||
|
||||
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);
|
||||
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 */
|
||||
if (GST_CLOCK_TIME_IS_VALID (expected_ts)) {
|
||||
|
|
Loading…
Reference in a new issue