mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
ext/ffmpeg/gstffmpegdec.c: Re-re-enable get_/release_buffer functions, removes a few more percent of our CPU usage (#...
Original commit message from CVS: Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net> * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_init), (gst_ffmpegdec_open), (gst_ffmpegdec_connect), (gst_ffmpegdec_get_buffer), (gst_ffmpegdec_release_buffer), (gst_ffmpegdec_frame), (gst_ffmpegdec_change_state): Re-re-enable get_/release_buffer functions, removes a few more percent of our CPU usage (#301783).
This commit is contained in:
parent
1cf3d1b494
commit
d840f938cd
2 changed files with 102 additions and 38 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2005-05-06 Luca Ognibene <luogni@tin.it>
|
||||||
|
|
||||||
|
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
|
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_init),
|
||||||
|
(gst_ffmpegdec_open), (gst_ffmpegdec_connect),
|
||||||
|
(gst_ffmpegdec_get_buffer), (gst_ffmpegdec_release_buffer),
|
||||||
|
(gst_ffmpegdec_frame), (gst_ffmpegdec_change_state):
|
||||||
|
Re-re-enable get_/release_buffer functions, removes a few more
|
||||||
|
percent of our CPU usage (#301783).
|
||||||
|
|
||||||
2005-05-02 Luca Ognibene <luogni@tin.it>
|
2005-05-02 Luca Ognibene <luogni@tin.it>
|
||||||
|
|
||||||
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "gstffmpeg.h"
|
#include "gstffmpeg.h"
|
||||||
#include "gstffmpegcodecmap.h"
|
#include "gstffmpegcodecmap.h"
|
||||||
|
|
||||||
|
//#define FORCE_OUR_GET_BUFFER
|
||||||
|
|
||||||
typedef struct _GstFFMpegDec GstFFMpegDec;
|
typedef struct _GstFFMpegDec GstFFMpegDec;
|
||||||
|
|
||||||
struct _GstFFMpegDec
|
struct _GstFFMpegDec
|
||||||
|
@ -64,6 +66,8 @@ struct _GstFFMpegDec
|
||||||
AVCodecParserContext *pctx;
|
AVCodecParserContext *pctx;
|
||||||
GstBuffer *pcache;
|
GstBuffer *pcache;
|
||||||
|
|
||||||
|
GstBuffer *last_buffer;
|
||||||
|
|
||||||
GValue *par; /* pixel aspect ratio of incoming data */
|
GValue *par; /* pixel aspect ratio of incoming data */
|
||||||
|
|
||||||
gint hurry_up, lowres;
|
gint hurry_up, lowres;
|
||||||
|
@ -128,13 +132,13 @@ static void gst_ffmpegdec_set_property (GObject * object,
|
||||||
static void gst_ffmpegdec_get_property (GObject * object,
|
static void gst_ffmpegdec_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
#if 0
|
static gboolean gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec);
|
||||||
|
|
||||||
/* some sort of bufferpool handling, but different */
|
/* some sort of bufferpool handling, but different */
|
||||||
static int gst_ffmpegdec_get_buffer (AVCodecContext * context,
|
static int gst_ffmpegdec_get_buffer (AVCodecContext * context,
|
||||||
AVFrame * picture);
|
AVFrame * picture);
|
||||||
static void gst_ffmpegdec_release_buffer (AVCodecContext * context,
|
static void gst_ffmpegdec_release_buffer (AVCodecContext * context,
|
||||||
AVFrame * picture);
|
AVFrame * picture);
|
||||||
#endif
|
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
|
@ -277,6 +281,8 @@ gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec)
|
||||||
ffmpegdec->waiting_for_key = FALSE;
|
ffmpegdec->waiting_for_key = FALSE;
|
||||||
ffmpegdec->hurry_up = ffmpegdec->lowres = 0;
|
ffmpegdec->hurry_up = ffmpegdec->lowres = 0;
|
||||||
|
|
||||||
|
ffmpegdec->last_buffer = NULL;
|
||||||
|
|
||||||
GST_FLAG_SET (ffmpegdec, GST_ELEMENT_EVENT_AWARE);
|
GST_FLAG_SET (ffmpegdec, GST_ELEMENT_EVENT_AWARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,6 +422,8 @@ gst_ffmpegdec_open (GstFFMpegDec *ffmpegdec)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ffmpegdec->next_ts = 0;
|
ffmpegdec->next_ts = 0;
|
||||||
|
|
||||||
|
ffmpegdec->last_buffer = NULL;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -435,12 +443,10 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps)
|
||||||
/* set defaults */
|
/* set defaults */
|
||||||
avcodec_get_context_defaults (ffmpegdec->context);
|
avcodec_get_context_defaults (ffmpegdec->context);
|
||||||
|
|
||||||
#if 0
|
/* set buffer functions */
|
||||||
/* set buffer functions */
|
|
||||||
ffmpegdec->context->get_buffer = gst_ffmpegdec_get_buffer;
|
ffmpegdec->context->get_buffer = gst_ffmpegdec_get_buffer;
|
||||||
ffmpegdec->context->release_buffer = gst_ffmpegdec_release_buffer;
|
ffmpegdec->context->release_buffer = gst_ffmpegdec_release_buffer;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* get size and so */
|
/* get size and so */
|
||||||
gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
|
gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
|
||||||
oclass->in_plugin->type, caps, ffmpegdec->context);
|
oclass->in_plugin->type, caps, ffmpegdec->context);
|
||||||
|
@ -478,23 +484,51 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps)
|
||||||
return GST_PAD_LINK_OK;
|
return GST_PAD_LINK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int
|
static int
|
||||||
gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
{
|
{
|
||||||
GstBuffer *buf = NULL;
|
GstBuffer *buf = NULL;
|
||||||
gulong bufsize = 0;
|
gulong bufsize = 0;
|
||||||
|
GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) context->opaque;
|
||||||
|
int width = context->width;
|
||||||
|
int height = context->height;
|
||||||
|
|
||||||
switch (context->codec_type) {
|
switch (context->codec_type) {
|
||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
|
|
||||||
|
avcodec_align_dimensions(context, &width, &height);
|
||||||
|
|
||||||
bufsize = avpicture_get_size (context->pix_fmt,
|
bufsize = avpicture_get_size (context->pix_fmt,
|
||||||
context->width, context->height);
|
width, height);
|
||||||
buf = gst_buffer_new_and_alloc (bufsize);
|
|
||||||
|
if((width != context->width) || (height != context->height)) {
|
||||||
|
#ifdef FORCE_OUR_GET_BUFFER
|
||||||
|
context->width = width;
|
||||||
|
context->height = height;
|
||||||
|
#else
|
||||||
|
/* revert to ffmpeg's default functions */
|
||||||
|
ffmpegdec->context->get_buffer = avcodec_default_get_buffer;
|
||||||
|
ffmpegdec->context->release_buffer = avcodec_default_release_buffer;
|
||||||
|
|
||||||
|
return avcodec_default_get_buffer(context, picture);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_ffmpegdec_negotiate (ffmpegdec)) {
|
||||||
|
GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
|
||||||
|
("Failed to link ffmpeg decoder to next element"));
|
||||||
|
return avcodec_default_get_buffer(context, picture);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = gst_pad_alloc_buffer (ffmpegdec->srcpad, GST_BUFFER_OFFSET_NONE, bufsize);
|
||||||
|
ffmpegdec->last_buffer = buf;
|
||||||
|
|
||||||
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
|
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
|
||||||
GST_BUFFER_DATA (buf),
|
GST_BUFFER_DATA (buf),
|
||||||
context->pix_fmt, context->width, context->height);
|
context->pix_fmt, context->width, context->height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CODEC_TYPE_AUDIO:
|
case CODEC_TYPE_AUDIO:
|
||||||
default:
|
default:
|
||||||
g_assert (0);
|
g_assert (0);
|
||||||
|
@ -509,7 +543,7 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
* so that we don't need to copy data */
|
* so that we don't need to copy data */
|
||||||
picture->type = FF_BUFFER_TYPE_USER;
|
picture->type = FF_BUFFER_TYPE_USER;
|
||||||
picture->age = G_MAXINT;
|
picture->age = G_MAXINT;
|
||||||
picture->base[0] = (int8_t *) buf;
|
picture->opaque = buf;
|
||||||
gst_buffer_ref (buf);
|
gst_buffer_ref (buf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -519,8 +553,13 @@ static void
|
||||||
gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
GstBuffer *buf = GST_BUFFER (picture->base[0]);
|
GstBuffer *buf = GST_BUFFER (picture->opaque);
|
||||||
|
GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) context->opaque;
|
||||||
|
|
||||||
|
g_return_if_fail (buf != NULL);
|
||||||
|
g_return_if_fail (picture->type == FF_BUFFER_TYPE_USER);
|
||||||
|
|
||||||
|
ffmpegdec->last_buffer = NULL;
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
/* zero out the reference in ffmpeg */
|
/* zero out the reference in ffmpeg */
|
||||||
|
@ -529,7 +568,6 @@ gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
picture->linesize[i] = 0;
|
picture->linesize[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec)
|
gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec)
|
||||||
|
@ -622,12 +660,15 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
|
||||||
(GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
|
(GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
gint have_data, len = 0;
|
gint have_data, len = 0;
|
||||||
|
|
||||||
ffmpegdec->context->frame_number++;
|
ffmpegdec->context->frame_number++;
|
||||||
|
|
||||||
switch (oclass->in_plugin->type) {
|
switch (oclass->in_plugin->type) {
|
||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
ffmpegdec->picture->pict_type = -1; /* in case we skip frames */
|
ffmpegdec->picture->pict_type = -1; /* in case we skip frames */
|
||||||
|
|
||||||
|
ffmpegdec->context->opaque = ffmpegdec;
|
||||||
|
|
||||||
len = avcodec_decode_video (ffmpegdec->context,
|
len = avcodec_decode_video (ffmpegdec->context,
|
||||||
ffmpegdec->picture, &have_data, data, size);
|
ffmpegdec->picture, &have_data, data, size);
|
||||||
GST_DEBUG_OBJECT (ffmpegdec,
|
GST_DEBUG_OBJECT (ffmpegdec,
|
||||||
|
@ -640,31 +681,36 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
|
||||||
/* libavcodec constantly crashes on stupid buffer allocation
|
/* libavcodec constantly crashes on stupid buffer allocation
|
||||||
* 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;
|
|
||||||
gint fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
|
if (ffmpegdec->picture->opaque != NULL) {
|
||||||
|
outbuf = (GstBuffer *) ffmpegdec->picture->opaque;
|
||||||
|
}else {
|
||||||
|
AVPicture pic;
|
||||||
|
gint fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
|
||||||
ffmpegdec->context->width, ffmpegdec->context->height);
|
ffmpegdec->context->width, ffmpegdec->context->height);
|
||||||
|
|
||||||
ffmpegdec->waiting_for_key = FALSE;
|
if (!gst_ffmpegdec_negotiate (ffmpegdec))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
outbuf = gst_pad_alloc_buffer (ffmpegdec->srcpad, GST_BUFFER_OFFSET_NONE, fsize);
|
||||||
|
|
||||||
if (!gst_ffmpegdec_negotiate (ffmpegdec))
|
/* original ffmpeg code does not handle odd sizes correctly.
|
||||||
return -1;
|
* This patched up version does */
|
||||||
|
gst_ffmpeg_avpicture_fill (&pic, GST_BUFFER_DATA (outbuf),
|
||||||
|
ffmpegdec->context->pix_fmt,
|
||||||
|
ffmpegdec->context->width, ffmpegdec->context->height);
|
||||||
|
|
||||||
outbuf = gst_pad_alloc_buffer (ffmpegdec->srcpad, GST_BUFFER_OFFSET_NONE, fsize);
|
/* the original convert function did not do the right thing, this
|
||||||
|
* is a patched up version that adjust widht/height so that the
|
||||||
/* original ffmpeg code does not handle odd sizes correctly.
|
* ffmpeg one works correctly. */
|
||||||
* This patched up version does */
|
gst_ffmpeg_img_convert (&pic, ffmpegdec->context->pix_fmt,
|
||||||
gst_ffmpeg_avpicture_fill (&pic, GST_BUFFER_DATA (outbuf),
|
(AVPicture *) ffmpegdec->picture,
|
||||||
ffmpegdec->context->pix_fmt,
|
ffmpegdec->context->pix_fmt,
|
||||||
ffmpegdec->context->width, ffmpegdec->context->height);
|
ffmpegdec->context->width,
|
||||||
|
ffmpegdec->context->height);
|
||||||
/* the original convert function did not do the right thing, this
|
}
|
||||||
* is a patched up version that adjust widht/height so that the
|
|
||||||
* ffmpeg one works correctly. */
|
ffmpegdec->waiting_for_key = FALSE;
|
||||||
gst_ffmpeg_img_convert (&pic, ffmpegdec->context->pix_fmt,
|
|
||||||
(AVPicture *) ffmpegdec->picture,
|
|
||||||
ffmpegdec->context->pix_fmt,
|
|
||||||
ffmpegdec->context->width,
|
|
||||||
ffmpegdec->context->height);
|
|
||||||
|
|
||||||
/* note that ffmpeg sometimes gets the FPS wrong.
|
/* note that ffmpeg sometimes gets the FPS wrong.
|
||||||
* For B-frame containing movies, we get all pictures delayed
|
* For B-frame containing movies, we get all pictures delayed
|
||||||
|
@ -747,7 +793,7 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
|
||||||
g_assert (0);
|
g_assert (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < 0 || have_data < 0) {
|
if (len < 0 || have_data < 0) {
|
||||||
GST_ERROR_OBJECT (ffmpegdec,
|
GST_ERROR_OBJECT (ffmpegdec,
|
||||||
"ffdec_%s: decoding error (len: %d, have_data: %d)",
|
"ffdec_%s: decoding error (len: %d, have_data: %d)",
|
||||||
|
@ -761,8 +807,9 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
|
||||||
/* this is where I lost my last clue on ffmpeg... */
|
/* this is where I lost my last clue on ffmpeg... */
|
||||||
*got_data = 1; //(ffmpegdec->pctx || have_data) ? 1 : 0;
|
*got_data = 1; //(ffmpegdec->pctx || have_data) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_data) {
|
if (have_data) {
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec, "Decoded data, now pushing (%"
|
GST_DEBUG_OBJECT (ffmpegdec, "Decoded data, now pushing (%"
|
||||||
GST_TIME_FORMAT ")", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
|
GST_TIME_FORMAT ")", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
|
||||||
|
|
||||||
|
@ -955,6 +1002,12 @@ gst_ffmpegdec_change_state (GstElement * element)
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_PAUSED_TO_READY:
|
case GST_STATE_PAUSED_TO_READY:
|
||||||
|
if (ffmpegdec->last_buffer != NULL) {
|
||||||
|
gst_buffer_unref (ffmpegdec->last_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* closing context.. unref buffers? */
|
||||||
|
|
||||||
gst_ffmpegdec_close (ffmpegdec);
|
gst_ffmpegdec_close (ffmpegdec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue