mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
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:
parent
5ce7edc931
commit
d8f7d245f4
6 changed files with 458 additions and 514 deletions
25
ChangeLog
25
ChangeLog
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue