+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),
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) {
- caps = GST_FF_VID_CAPS_NEW ("video/x-raw-rgb",
- "bpp", G_TYPE_INT, bpp,
- "depth", G_TYPE_INT, depth,
- "red_mask", G_TYPE_INT, r_mask,
- "green_mask", G_TYPE_INT, g_mask,
- "blue_mask", G_TYPE_INT, b_mask,
- "endianness", G_TYPE_INT, endianness, NULL);
+ if (r_mask != 0) {
+ caps = GST_FF_VID_CAPS_NEW ("video/x-raw-rgb",
+ "bpp", G_TYPE_INT, bpp,
+ "depth", G_TYPE_INT, depth,
+ "red_mask", G_TYPE_INT, r_mask,
+ "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);
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)) {
- switch (bpp) {
- case 32:
+ 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)
- if (rmask == 0x00ff0000)
+ if (rmask == 0x00ff0000)
#else
- if (rmask == 0x0000ff00)
+ if (rmask == 0x0000ff00)
#endif
- context->pix_fmt = PIX_FMT_RGBA32;
- break;
- case 24:
- if (rmask == 0x0000FF)
- context->pix_fmt = PIX_FMT_BGR24;
- else
- context->pix_fmt = PIX_FMT_RGB24;
- break;
- case 16:
- if (endianness == G_BYTE_ORDER)
- context->pix_fmt = PIX_FMT_RGB565;
- break;
- case 15:
- if (endianness == G_BYTE_ORDER)
- context->pix_fmt = PIX_FMT_RGB555;
- break;
- default:
- /* nothing */
- break;
+ context->pix_fmt = PIX_FMT_RGBA32;
+ break;
+ case 24:
+ if (rmask == 0x0000FF)
+ context->pix_fmt = PIX_FMT_BGR24;
+ else
+ context->pix_fmt = PIX_FMT_RGB24;
+ break;
+ case 16:
+ if (endianness == G_BYTE_ORDER)
+ context->pix_fmt = PIX_FMT_RGB565;
+ break;
+ case 15:
+ if (endianness == G_BYTE_ORDER)
+ context->pix_fmt = PIX_FMT_RGB555;
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+ } else {
+ if (bpp == 8) {
+ context->pix_fmt = PIX_FMT_PAL8;
+ gst_ffmpeg_get_palette (caps, context);
+ }
}
}
}
gfloat fps;
enum PixelFormat from_pixfmt, to_pixfmt;
AVFrame *from_frame, *to_frame;
+ AVPaletteControl *palette;
GstCaps *sinkcaps;
};
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)
space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
space->from_frame = space->to_frame = NULL;
+ space->palette = NULL;
}
static void
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);
}
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;
}
/* 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",
* 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);
+ img_convert (&pic, ffmpegdec->context->pix_fmt,
+ (AVPicture *) ffmpegdec->picture,
+ 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)) {