mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-03 15:06:34 +00:00
ffmpeg: use bufferpool instead of pad_alloc
This commit is contained in:
parent
6d4cdb2877
commit
195f2afea6
4 changed files with 88 additions and 54 deletions
|
@ -68,6 +68,7 @@ struct _GstFFMpegDec
|
||||||
AVCodecContext *context;
|
AVCodecContext *context;
|
||||||
AVFrame *picture;
|
AVFrame *picture;
|
||||||
gboolean opened;
|
gboolean opened;
|
||||||
|
GstBufferPool *pool;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
@ -136,9 +137,6 @@ struct _GstFFMpegDec
|
||||||
|
|
||||||
/* reverse playback queue */
|
/* reverse playback queue */
|
||||||
GList *queued;
|
GList *queued;
|
||||||
|
|
||||||
/* Can downstream allocate 16bytes aligned data. */
|
|
||||||
gboolean can_allocate_aligned;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstFFMpegDecClass GstFFMpegDecClass;
|
typedef struct _GstFFMpegDecClass GstFFMpegDecClass;
|
||||||
|
@ -433,9 +431,6 @@ gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec)
|
||||||
ffmpegdec->format.video.fps_n = -1;
|
ffmpegdec->format.video.fps_n = -1;
|
||||||
ffmpegdec->format.video.old_fps_n = -1;
|
ffmpegdec->format.video.old_fps_n = -1;
|
||||||
gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
|
gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
/* We initially assume downstream can allocate 16 bytes aligned buffers */
|
|
||||||
ffmpegdec->can_allocate_aligned = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -443,15 +438,14 @@ gst_ffmpegdec_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
|
GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
|
||||||
|
|
||||||
if (ffmpegdec->context != NULL) {
|
if (ffmpegdec->context != NULL)
|
||||||
av_free (ffmpegdec->context);
|
av_free (ffmpegdec->context);
|
||||||
ffmpegdec->context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ffmpegdec->picture != NULL) {
|
if (ffmpegdec->picture != NULL)
|
||||||
av_free (ffmpegdec->picture);
|
av_free (ffmpegdec->picture);
|
||||||
ffmpegdec->picture = NULL;
|
|
||||||
}
|
if (ffmpegdec->pool)
|
||||||
|
gst_object_unref (ffmpegdec->pool);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -913,12 +907,10 @@ alloc_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf,
|
||||||
fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
|
fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
|
||||||
width, height);
|
width, height);
|
||||||
|
|
||||||
if (!ffmpegdec->context->palctrl && ffmpegdec->can_allocate_aligned) {
|
if (!ffmpegdec->context->palctrl) {
|
||||||
GST_LOG_OBJECT (ffmpegdec, "calling pad_alloc");
|
GST_LOG_OBJECT (ffmpegdec, "calling pad_alloc");
|
||||||
/* no pallete, we can use the buffer size to alloc */
|
/* no pallete, we can use the buffer size to alloc */
|
||||||
ret = gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad,
|
ret = gst_buffer_pool_acquire_buffer (ffmpegdec->pool, outbuf, NULL);
|
||||||
GST_BUFFER_OFFSET_NONE, fsize,
|
|
||||||
GST_PAD_CAPS (ffmpegdec->srcpad), outbuf);
|
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||||
goto alloc_failed;
|
goto alloc_failed;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1031,15 +1023,6 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
|
|
||||||
/* FIXME, unmap me later */
|
/* FIXME, unmap me later */
|
||||||
data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
|
||||||
if (((uintptr_t) data) % 16) {
|
|
||||||
/* If buffer isn't 128-bit aligned, create a memaligned one ourselves */
|
|
||||||
gst_buffer_unmap (buf, data, size);
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec,
|
|
||||||
"Downstream can't allocate aligned buffers.");
|
|
||||||
ffmpegdec->can_allocate_aligned = FALSE;
|
|
||||||
return avcodec_default_get_buffer (context, picture);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the right pointers and strides in the picture object */
|
/* copy the right pointers and strides in the picture object */
|
||||||
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
|
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
|
||||||
|
@ -1188,6 +1171,48 @@ no_par:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_ffmpegdec_bufferpool (GstFFMpegDec * ffmpegdec, GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstQuery *query;
|
||||||
|
GstBufferPool *pool = NULL;
|
||||||
|
guint alignment, prefix, size;
|
||||||
|
GstStructure *config;
|
||||||
|
|
||||||
|
/* find a pool for the negotiated caps now */
|
||||||
|
query = gst_query_new_allocation (caps, TRUE);
|
||||||
|
|
||||||
|
if (gst_pad_peer_query (ffmpegdec->srcpad, query)) {
|
||||||
|
/* we got configuration from our peer, parse them */
|
||||||
|
gst_query_parse_allocation_params (query, &alignment, &prefix, &size,
|
||||||
|
&pool);
|
||||||
|
} else {
|
||||||
|
alignment = 16;
|
||||||
|
prefix = 0;
|
||||||
|
size = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
|
||||||
|
ffmpegdec->context->width, ffmpegdec->context->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pool == NULL) {
|
||||||
|
/* we did not get a pool, make one ourselves then */
|
||||||
|
pool = gst_buffer_pool_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
gst_buffer_pool_config_set (config, caps, size, 0, 0, prefix, 0,
|
||||||
|
MAX (alignment, 16));
|
||||||
|
gst_buffer_pool_set_config (pool, config);
|
||||||
|
|
||||||
|
if (ffmpegdec->pool)
|
||||||
|
gst_object_unref (ffmpegdec->pool);
|
||||||
|
ffmpegdec->pool = pool;
|
||||||
|
|
||||||
|
/* and activate */
|
||||||
|
gst_buffer_pool_set_active (pool, TRUE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec, gboolean force)
|
gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec, gboolean force)
|
||||||
{
|
{
|
||||||
|
@ -1297,6 +1322,10 @@ gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec, gboolean force)
|
||||||
if (!gst_pad_set_caps (ffmpegdec->srcpad, caps))
|
if (!gst_pad_set_caps (ffmpegdec->srcpad, caps))
|
||||||
goto caps_failed;
|
goto caps_failed;
|
||||||
|
|
||||||
|
/* now figure out a bufferpool */
|
||||||
|
if (!gst_ffmpegdec_bufferpool (ffmpegdec, caps))
|
||||||
|
goto no_bufferpool;
|
||||||
|
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1329,6 +1358,15 @@ caps_failed:
|
||||||
oclass->in_plugin->name));
|
oclass->in_plugin->name));
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
no_bufferpool:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
|
||||||
|
("Could not create bufferpool for fmpeg decoder (%s)",
|
||||||
|
oclass->in_plugin->name));
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2782,7 +2820,11 @@ gst_ffmpegdec_change_state (GstElement * element, GstStateChange transition)
|
||||||
g_free (ffmpegdec->padded);
|
g_free (ffmpegdec->padded);
|
||||||
ffmpegdec->padded = NULL;
|
ffmpegdec->padded = NULL;
|
||||||
ffmpegdec->padded_size = 0;
|
ffmpegdec->padded_size = 0;
|
||||||
ffmpegdec->can_allocate_aligned = TRUE;
|
if (ffmpegdec->pool) {
|
||||||
|
gst_buffer_pool_set_active (ffmpegdec->pool, FALSE);
|
||||||
|
gst_object_unref (ffmpegdec->pool);
|
||||||
|
}
|
||||||
|
ffmpegdec->pool = NULL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -166,14 +166,12 @@ gst_ffmpegdeinterlace_chain (GstPad * pad, GstBuffer * inbuf)
|
||||||
GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad));
|
GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad));
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
|
|
||||||
result =
|
|
||||||
gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE,
|
|
||||||
deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf);
|
|
||||||
if (result == GST_FLOW_OK) {
|
|
||||||
guint8 *from_data, *to_data;
|
guint8 *from_data, *to_data;
|
||||||
gsize from_size, to_size;
|
gsize from_size, to_size;
|
||||||
|
|
||||||
|
outbuf = gst_buffer_new_and_alloc (deinterlace->to_size);
|
||||||
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (deinterlace->srcpad));
|
||||||
|
|
||||||
from_data = gst_buffer_map (inbuf, &from_size, NULL, GST_MAP_READ);
|
from_data = gst_buffer_map (inbuf, &from_size, NULL, GST_MAP_READ);
|
||||||
gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, from_data,
|
gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, from_data,
|
||||||
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
|
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
|
||||||
|
@ -190,7 +188,6 @@ gst_ffmpegdeinterlace_chain (GstPad * pad, GstBuffer * inbuf)
|
||||||
gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
|
gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
|
||||||
|
|
||||||
result = gst_pad_push (deinterlace->srcpad, outbuf);
|
result = gst_pad_push (deinterlace->srcpad, outbuf);
|
||||||
}
|
|
||||||
|
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
|
|
||||||
|
|
|
@ -1398,16 +1398,12 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
||||||
else
|
else
|
||||||
outsize = pkt.size;
|
outsize = pkt.size;
|
||||||
|
|
||||||
stream->last_flow = gst_pad_alloc_buffer_and_set_caps (srcpad,
|
outbuf = gst_buffer_new_and_alloc (outsize);
|
||||||
GST_CLOCK_TIME_NONE, outsize, GST_PAD_CAPS (srcpad), &outbuf);
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (srcpad));
|
||||||
|
|
||||||
if ((ret = gst_ffmpegdemux_aggregated_flow (demux)) != GST_FLOW_OK)
|
if ((ret = gst_ffmpegdemux_aggregated_flow (demux)) != GST_FLOW_OK)
|
||||||
goto no_buffer;
|
goto no_buffer;
|
||||||
|
|
||||||
/* If the buffer allocation failed, don't try sending it ! */
|
|
||||||
if (stream->last_flow != GST_FLOW_OK)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* copy the data from packet into the target buffer
|
/* copy the data from packet into the target buffer
|
||||||
* and do conversions for raw video packets */
|
* and do conversions for raw video packets */
|
||||||
if (rawvideo) {
|
if (rawvideo) {
|
||||||
|
|
|
@ -165,9 +165,8 @@ gst_ffmpegdata_write (URLContext * h, const unsigned char *buf, int size)
|
||||||
g_return_val_if_fail (h->flags != URL_RDONLY, -EIO);
|
g_return_val_if_fail (h->flags != URL_RDONLY, -EIO);
|
||||||
|
|
||||||
/* create buffer and push data further */
|
/* create buffer and push data further */
|
||||||
if (gst_pad_alloc_buffer_and_set_caps (info->pad,
|
outbuf = gst_buffer_new_and_alloc (size);
|
||||||
info->offset, size, GST_PAD_CAPS (info->pad), &outbuf) != GST_FLOW_OK)
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (info->pad));
|
||||||
return 0;
|
|
||||||
|
|
||||||
gst_buffer_fill (outbuf, 0, buf, size);
|
gst_buffer_fill (outbuf, 0, buf, size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue