ext/ffmpeg/gstffmpegcodecmap.*: Change some function names to reflect that they don't really _return_ something, but ...

Original commit message from CVS:
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_get_palette),
(gst_ffmpeg_set_palette), (gst_ffmpeg_codecid_to_caps),
(gst_ffmpeg_pixfmt_to_caps), (gst_ffmpeg_caps_to_smpfmt),
(gst_ffmpeg_caps_to_pixfmt), (gst_ffmpeg_caps_with_codectype),
(gst_ffmpeg_caps_with_codecid), (gst_ffmpeg_caps_to_codecid):
* ext/ffmpeg/gstffmpegcodecmap.h:
Change some function names to reflect that they don't really
_return_ something, but rather _use_ something to fill a
AVCodecContext. s/to/with/. Restructure the extradata handling,
it's now not picking up the type from the caps but rather
using the type as provided in the function. This is a lot
cleaner. Implement MS RLE palette pickup.
* ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_pad_link):
* ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_connect):
Sync with the above function name changes.
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_close),
(gst_ffmpegdec_open), (gst_ffmpegdec_connect),
(gst_ffmpegdec_chain), (gst_ffmpegdec_change_state):
Add some hacks to convert palette-based raw image formats to
RGBA32. Ugly, but I don't know how else to handle palette-based
RGB, since img_convert() (and thus ffcolorspace) doesn't accept
a palette as argument.
This commit is contained in:
Ronald S. Bultje 2004-04-16 01:28:36 +00:00
parent 5ce7edc931
commit d8f7d245f4
6 changed files with 458 additions and 514 deletions

View file

@ -1,3 +1,28 @@
2004-04-15 Ronald Bultje <rbultje@ronald.bitfreak.net>
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_get_palette),
(gst_ffmpeg_set_palette), (gst_ffmpeg_codecid_to_caps),
(gst_ffmpeg_pixfmt_to_caps), (gst_ffmpeg_caps_to_smpfmt),
(gst_ffmpeg_caps_to_pixfmt), (gst_ffmpeg_caps_with_codectype),
(gst_ffmpeg_caps_with_codecid), (gst_ffmpeg_caps_to_codecid):
* ext/ffmpeg/gstffmpegcodecmap.h:
Change some function names to reflect that they don't really
_return_ something, but rather _use_ something to fill a
AVCodecContext. s/to/with/. Restructure the extradata handling,
it's now not picking up the type from the caps but rather
using the type as provided in the function. This is a lot
cleaner. Implement MS RLE palette pickup.
* ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_pad_link):
* ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_connect):
Sync with the above function name changes.
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_close),
(gst_ffmpegdec_open), (gst_ffmpegdec_connect),
(gst_ffmpegdec_chain), (gst_ffmpegdec_change_state):
Add some hacks to convert palette-based raw image formats to
RGBA32. Ugly, but I don't know how else to handle palette-based
RGB, since img_convert() (and thus ffcolorspace) doesn't accept
a palette as argument.
2004-04-14 Thomas Vander Stichele <thomas at apestaart dot org>
* everything: updated upstream source to 2004-04-11 23:00 GMT

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,8 @@
#endif
#include <gst/gst.h>
/* _codecid_to_caps () gets the GstCaps that belongs to
/*
* _codecid_to_caps () gets the GstCaps that belongs to
* a certain CodecID for a pad with compressed data.
*/
@ -36,7 +37,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
AVCodecContext *context,
gboolean encode);
/* _codectype_to_caps () gets the GstCaps that belongs to
/*
* _codectype_to_caps () gets the GstCaps that belongs to
* a certain CodecType for a pad with uncompressed data.
*/
@ -44,25 +46,39 @@ GstCaps *
gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
AVCodecContext *context);
/* caps_to_codecid () transforms a GstCaps that belongs to
/*
* caps_to_codecid () transforms a GstCaps that belongs to
* a pad for compressed data to (optionally) a filled-in
* context and a codecID
* context and a codecID.
*/
enum CodecID
gst_ffmpeg_caps_to_codecid (const GstCaps *caps,
gst_ffmpeg_caps_to_codecid (const GstCaps *caps,
AVCodecContext *context);
/* caps_to_codectype () transforms a GstCaps that belongs to
* a pad for uncompressed data to a filled-in context
/*
* caps_with_codecid () transforms a GstCaps for a known codec
* ID into a filled-in context.
*/
void
gst_ffmpeg_caps_to_codectype (enum CodecType type,
const GstCaps *caps,
AVCodecContext *context);
gst_ffmpeg_caps_with_codecid (enum CodecID codec_id,
enum CodecType codec_type,
const GstCaps *caps,
AVCodecContext *context);
/* _formatid_to_caps () is meant for muxers/demuxers, it
/*
* caps_with_codectype () transforms a GstCaps that belongs to
* a pad for uncompressed data to a filled-in context.
*/
void
gst_ffmpeg_caps_with_codectype (enum CodecType type,
const GstCaps *caps,
AVCodecContext *context);
/*
* _formatid_to_caps () is meant for muxers/demuxers, it
* transforms a name (ffmpeg way of ID'ing these, why don't
* they have unique numerical IDs?) to the corresponding
* caps belonging to that mux-format

View file

@ -195,7 +195,7 @@ gst_ffmpegcsp_pad_link (GstPad * pad, const GstCaps * caps)
ctx->width = width;
ctx->height = height;
ctx->pix_fmt = PIX_FMT_NB;
gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, caps, ctx);
gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, caps, ctx);
if (ctx->pix_fmt == PIX_FMT_NB) {
av_free (ctx);

View file

@ -211,6 +211,43 @@ gst_ffmpegdec_dispose (GObject * object)
av_free (ffmpegdec->picture);
}
static void
gst_ffmpegdec_close (GstFFMpegDec *ffmpegdec)
{
if (!ffmpegdec->opened)
return;
avcodec_close (ffmpegdec->context);
ffmpegdec->opened = FALSE;
if (ffmpegdec->context->palctrl) {
av_free (ffmpegdec->context->palctrl);
ffmpegdec->context->palctrl = NULL;
}
if (ffmpegdec->context->extradata) {
av_free (ffmpegdec->context->extradata);
ffmpegdec->context->extradata = NULL;
}
}
static gboolean
gst_ffmpegdec_open (GstFFMpegDec *ffmpegdec)
{
GstFFMpegDecClass *oclass =
(GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
ffmpegdec->opened = TRUE;
if (avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0) {
gst_ffmpegdec_close (ffmpegdec);
GST_DEBUG ("ffdec_%s: Failed to open FFMPEG codec",
oclass->in_plugin->name);
return FALSE;
}
return TRUE;
}
static GstPadLinkReturn
gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps)
{
@ -219,10 +256,7 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps)
(GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
/* close old session */
if (ffmpegdec->opened) {
avcodec_close (ffmpegdec->context);
ffmpegdec->opened = FALSE;
}
gst_ffmpegdec_close (ffmpegdec);
/* set defaults */
avcodec_get_context_defaults (ffmpegdec->context);
@ -234,8 +268,8 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps)
#endif
/* get size and so */
gst_ffmpeg_caps_to_codectype (oclass->in_plugin->type,
caps, ffmpegdec->context);
gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
oclass->in_plugin->type, caps, ffmpegdec->context);
/* we dont send complete frames - FIXME: we need a 'framed' property
* in caps */
@ -250,17 +284,8 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps)
/* open codec - we don't select an output pix_fmt yet,
* simply because we don't know! We only get it
* during playback... */
if (avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0) {
avcodec_close (ffmpegdec->context);
GST_DEBUG ("ffdec_%s: Failed to open FFMPEG codec",
oclass->in_plugin->name);
return GST_PAD_LINK_REFUSED;
}
/* done! */
ffmpegdec->opened = TRUE;
return GST_PAD_LINK_OK;
return gst_ffmpegdec_open (ffmpegdec) ?
GST_PAD_LINK_OK : GST_PAD_LINK_REFUSED;
}
#if 0
@ -364,18 +389,40 @@ 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;
gint size = avpicture_get_size (ffmpegdec->context->pix_fmt,
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,
ffmpegdec->context->width,
ffmpegdec->context->height);
outbuf = gst_buffer_new_and_alloc (size);
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,
avpicture_fill (&pic, GST_BUFFER_DATA (outbuf), to_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];
}
}
}
/* this isn't necessarily true, but it's better than nothing */
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
@ -409,9 +456,13 @@ gst_ffmpegdec_chain (GstPad * pad, GstData * _data)
if (have_data) {
if (!GST_PAD_CAPS (ffmpegdec->srcpad)) {
GstCaps *caps;
enum PixelFormat orig_fmt = ffmpegdec->context->pix_fmt;
ffmpegdec->context->pix_fmt = (orig_fmt == PIX_FMT_PAL8) ?
PIX_FMT_RGBA32 : orig_fmt;
caps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type,
ffmpegdec->context);
ffmpegdec->context->pix_fmt = orig_fmt;
if (caps == NULL ||
!gst_pad_set_explicit_caps (ffmpegdec->srcpad, caps)) {
GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
@ -441,10 +492,7 @@ gst_ffmpegdec_change_state (GstElement * element)
switch (transition) {
case GST_STATE_PAUSED_TO_READY:
if (ffmpegdec->opened) {
avcodec_close (ffmpegdec->context);
ffmpegdec->opened = FALSE;
}
gst_ffmpegdec_close (ffmpegdec);
break;
}

View file

@ -316,7 +316,7 @@ gst_ffmpegenc_connect (GstPad * pad, const GstCaps * caps)
ffmpegenc->context->flags |= CODEC_FLAG_EMU_EDGE;
/* fetch pix_fmt and so on */
gst_ffmpeg_caps_to_codectype (oclass->in_plugin->type,
gst_ffmpeg_caps_with_codectype (oclass->in_plugin->type,
caps, ffmpegenc->context);
pix_fmt = ffmpegenc->context->pix_fmt;