ffmpeg: port to new memory API

This commit is contained in:
Wim Taymans 2011-04-04 13:18:13 +02:00
parent b304fff551
commit 8095b31f9c
7 changed files with 117 additions and 57 deletions

View file

@ -89,10 +89,10 @@ static void gst_ffmpegaudioresample_finalize (GObject * object);
static GstCaps *gst_ffmpegaudioresample_transform_caps (GstBaseTransform *
trans, GstPadDirection direction, GstCaps * caps);
static gboolean gst_ffmpegaudioresample_transform_size (GstBaseTransform *
trans, GstPadDirection direction, GstCaps * caps, guint size,
GstCaps * othercaps, guint * othersize);
trans, GstPadDirection direction, GstCaps * caps, gsize size,
GstCaps * othercaps, gsize * othersize);
static gboolean gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, guint * size);
GstCaps * caps, gsize * size);
static gboolean gst_ffmpegaudioresample_set_caps (GstBaseTransform * trans,
GstCaps * incaps, GstCaps * outcaps);
static GstFlowReturn gst_ffmpegaudioresample_transform (GstBaseTransform *
@ -174,8 +174,8 @@ gst_ffmpegaudioresample_transform_caps (GstBaseTransform * trans,
static gboolean
gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
guint * othersize)
GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
gsize * othersize)
{
gint inrate, outrate;
gint inchanns, outchanns;
@ -207,7 +207,7 @@ gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
static gboolean
gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size)
gsize * size)
{
gint channels;
GstStructure *structure;
@ -263,26 +263,34 @@ gst_ffmpegaudioresample_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (trans);
gint nbsamples;
gint ret;
guint8 *indata, *outdata;
gsize insize, outsize;
gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
nbsamples = GST_BUFFER_SIZE (inbuf) / (2 * resample->in_channels);
gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
nbsamples = insize / (2 * resample->in_channels);
GST_LOG_OBJECT (resample, "input buffer duration:%" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
outdata = gst_buffer_map (outbuf, &outsize, NULL, GST_MAP_WRITE);
GST_DEBUG_OBJECT (resample,
"audio_resample(ctx, output:%p [size:%d], input:%p [size:%d], nbsamples:%d",
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf),
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf), nbsamples);
outdata, outsize, indata, insize, nbsamples);
ret = audio_resample (resample->res, (short *) GST_BUFFER_DATA (outbuf),
(short *) GST_BUFFER_DATA (inbuf), nbsamples);
ret =
audio_resample (resample->res, (short *) outdata, (short *) indata,
nbsamples);
GST_DEBUG_OBJECT (resample, "audio_resample returned %d", ret);
GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale (ret, GST_SECOND,
resample->out_rate);
GST_BUFFER_SIZE (outbuf) = ret * 2 * resample->out_channels;
outsize = ret * 2 * resample->out_channels;
gst_buffer_unmap (outbuf, outdata, outsize);
gst_buffer_unmap (inbuf, indata, insize);
GST_LOG_OBJECT (resample, "Output buffer duration:%" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));

View file

@ -921,15 +921,6 @@ alloc_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf,
GST_PAD_CAPS (ffmpegdec->srcpad), outbuf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto alloc_failed;
/* If buffer isn't 128-bit aligned, create a memaligned one ourselves */
if (((uintptr_t) GST_BUFFER_DATA (*outbuf)) % 16) {
GST_DEBUG_OBJECT (ffmpegdec,
"Downstream can't allocate aligned buffers.");
ffmpegdec->can_allocate_aligned = FALSE;
gst_buffer_unref (*outbuf);
*outbuf = new_aligned_buffer (fsize, GST_PAD_CAPS (ffmpegdec->srcpad));
}
} else {
GST_LOG_OBJECT (ffmpegdec,
"not calling pad_alloc, we have a pallete or downstream can't give 16 byte aligned buffers.");
@ -1003,6 +994,7 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
{
GstFlowReturn ret;
gint clip_width, clip_height;
guint8 *data;
/* take final clipped output size */
if ((clip_width = ffmpegdec->format.video.clip_width) == -1)
@ -1032,9 +1024,21 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
return avcodec_default_get_buffer (context, picture);
}
/* FIXME, unmap me later */
data = gst_buffer_map (buf, NULL, 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, 0);
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 */
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
GST_BUFFER_DATA (buf), context->pix_fmt, width, height);
data, context->pix_fmt, width, height);
break;
}
case CODEC_TYPE_AUDIO:
@ -1092,6 +1096,7 @@ gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
#else
gst_buffer_unref (buf);
#endif
/* FIXME, unmap buffer data */
/* zero out the reference in ffmpeg */
for (i = 0; i < 4; i++) {
@ -1543,6 +1548,8 @@ get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
} else {
AVPicture pic, *outpic;
gint width, height;
guint8 *data;
gsize size;
GST_LOG_OBJECT (ffmpegdec, "get output buffer");
@ -1567,7 +1574,9 @@ get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
/* original ffmpeg code does not handle odd sizes correctly.
* This patched up version does */
gst_ffmpeg_avpicture_fill (&pic, GST_BUFFER_DATA (*outbuf),
data = gst_buffer_map (*outbuf, &size, NULL, GST_MAP_WRITE);
gst_ffmpeg_avpicture_fill (&pic, data,
ffmpegdec->context->pix_fmt, width, height);
outpic = (AVPicture *) ffmpegdec->picture;
@ -1579,6 +1588,7 @@ get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
(guint) (outpic->data[2] - outpic->data[0]));
av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt, width, height);
gst_buffer_unmap (*outbuf, data, size);
}
ffmpegdec->picture->reordered_opaque = -1;
@ -1928,8 +1938,11 @@ gst_ffmpegdec_video_frame (GstFFMpegDec * ffmpegdec,
/* palette is not part of raw video frame in gst and the size
* of the outgoing buffer needs to be adjusted accordingly */
if (ffmpegdec->context->palctrl != NULL)
GST_BUFFER_SIZE (*outbuf) -= AVPALETTE_SIZE;
if (ffmpegdec->context->palctrl != NULL) {
gst_buffer_resize (*outbuf, 0,
gst_buffer_get_size (*outbuf) - AVPALETTE_SIZE);
}
/* now see if we need to clip the buffer against the segment boundaries. */
if (G_UNLIKELY (!clip_video_buffer (ffmpegdec, *outbuf, out_timestamp,
@ -1979,11 +1992,15 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
GstClockTime stop;
gint64 diff, ctime, cstop;
gboolean res = TRUE;
gsize size, offset;
size = gst_buffer_get_size (buf);
offset = 0;
GST_LOG_OBJECT (dec,
"timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
", size %u", GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
GST_BUFFER_SIZE (buf));
", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
size);
/* can't clip without TIME segment */
if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
@ -2011,8 +2028,8 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
GST_BUFFER_SIZE (buf) -= diff;
GST_BUFFER_DATA (buf) += diff;
offset += diff;
size -= diff;
}
if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
/* bring clipped time to bytes */
@ -2023,8 +2040,9 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
GST_BUFFER_SIZE (buf) -= diff;
size -= diff;
}
gst_buffer_resize (buf, offset, size);
GST_BUFFER_TIMESTAMP (buf) = ctime;
GST_BUFFER_DURATION (buf) = cstop - ctime;
@ -2049,6 +2067,7 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
GstClockTime out_timestamp, out_duration;
gint64 out_offset;
int16_t *odata;
GST_DEBUG_OBJECT (ffmpegdec,
"size:%d, offset:%" G_GINT64_FORMAT ", ts:%" GST_TIME_FORMAT ", dur:%"
@ -2060,12 +2079,16 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
new_aligned_buffer (AVCODEC_MAX_AUDIO_FRAME_SIZE,
GST_PAD_CAPS (ffmpegdec->srcpad));
len = avcodec_decode_audio2 (ffmpegdec->context,
(int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
odata = gst_buffer_map (*outbuf, NULL, NULL, GST_MAP_WRITE);
len = avcodec_decode_audio2 (ffmpegdec->context, odata, &have_data,
data, size);
GST_DEBUG_OBJECT (ffmpegdec,
"Decode audio: len=%d, have_data=%d", len, have_data);
if (len >= 0 && have_data > 0) {
/* Buffer size */
gst_buffer_unmap (*outbuf, odata, have_data);
GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
if (!gst_ffmpegdec_negotiate (ffmpegdec, FALSE)) {
gst_buffer_unref (*outbuf);
@ -2074,9 +2097,6 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
goto beach;
}
/* Buffer size */
GST_BUFFER_SIZE (*outbuf) = have_data;
/*
* Timestamps:
*
@ -2123,6 +2143,7 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
goto clipped;
} else {
gst_buffer_unmap (*outbuf, odata, 0);
gst_buffer_unref (*outbuf);
*outbuf = NULL;
}

View file

@ -176,17 +176,23 @@ gst_ffmpegdeinterlace_chain (GstPad * pad, GstBuffer * inbuf)
gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE,
deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf);
if (result == GST_FLOW_OK) {
gst_ffmpeg_avpicture_fill (&deinterlace->from_frame,
GST_BUFFER_DATA (inbuf), deinterlace->pixfmt, deinterlace->width,
deinterlace->height);
guint8 *from_data, *to_data;
gsize from_size, to_size;
gst_ffmpeg_avpicture_fill (&deinterlace->to_frame, GST_BUFFER_DATA (outbuf),
from_data = gst_buffer_map (inbuf, &from_size, NULL, GST_MAP_READ);
gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, from_data,
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
to_data = gst_buffer_map (outbuf, &to_size, NULL, GST_MAP_WRITE);
gst_ffmpeg_avpicture_fill (&deinterlace->to_frame, to_data,
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame,
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
gst_buffer_unmap (outbuf, to_data, to_size);
gst_buffer_unmap (inbuf, from_data, from_size);
gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
result = gst_pad_push (deinterlace->srcpad, outbuf);
}

View file

@ -1269,7 +1269,7 @@ no_info:
static void
gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
{
guint8 *data;
const guint8 *data;
AVInputFormat *in_plugin = (AVInputFormat *) priv;
gint res = 0;
guint64 length;
@ -1296,7 +1296,7 @@ gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
AVProbeData probe_data;
probe_data.filename = "";
probe_data.buf = data;
probe_data.buf = (guint8 *) data;
probe_data.buf_size = length;
res = in_plugin->read_probe (&probe_data);
@ -1416,6 +1416,8 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
AVPicture src, dst;
const gchar *plugin_name =
((GstFFMpegDemuxClass *) (G_OBJECT_GET_CLASS (demux)))->in_plugin->name;
guint8 *data;
gsize size;
if (strcmp (plugin_name, "gif") == 0) {
src.data[0] = pkt.data;
@ -1429,14 +1431,16 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
avstream->codec->height);
}
gst_ffmpeg_avpicture_fill (&dst, GST_BUFFER_DATA (outbuf),
data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_WRITE);
gst_ffmpeg_avpicture_fill (&dst, data,
avstream->codec->pix_fmt, avstream->codec->width,
avstream->codec->height);
av_picture_copy (&dst, &src, avstream->codec->pix_fmt,
avstream->codec->width, avstream->codec->height);
gst_buffer_unmap (outbuf, data, size);
} else {
memcpy (GST_BUFFER_DATA (outbuf), pkt.data, outsize);
gst_buffer_fill (outbuf, 0, pkt.data, outsize);
}
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
@ -1456,7 +1460,7 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
GST_DEBUG_OBJECT (demux,
"Sending out buffer time:%" GST_TIME_FORMAT " size:%d",
GST_TIME_ARGS (timestamp), GST_BUFFER_SIZE (outbuf));
GST_TIME_ARGS (timestamp), gst_buffer_get_size (outbuf));
ret = stream->last_flow = gst_pad_push (srcpad, outbuf);
@ -1668,7 +1672,7 @@ gst_ffmpegdemux_chain (GstPad * sinkpad, GstBuffer * buffer)
if (G_UNLIKELY (ffpipe->srcresult != GST_FLOW_OK))
goto ignore;
GST_DEBUG ("Giving a buffer of %d bytes", GST_BUFFER_SIZE (buffer));
GST_DEBUG ("Giving a buffer of %d bytes", gst_buffer_get_size (buffer));
gst_adapter_push (ffpipe->adapter, buffer);
buffer = NULL;
while (gst_adapter_available (ffpipe->adapter) >= ffpipe->needed) {

View file

@ -704,6 +704,7 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
GstBuffer *buf;
AVPacket pkt;
gboolean need_free = FALSE;
gsize size;
/* push out current buffer */
buf = gst_collect_pads_pop (ffmpegmux->collect,
@ -719,6 +720,7 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
if (strcmp (ffmpegmux->context->oformat->name, "gif") == 0) {
AVStream *st = ffmpegmux->context->streams[best_pad->padnum];
AVPicture src, dst;
guint8 *data;
need_free = TRUE;
pkt.size = st->codec->width * st->codec->height * 3;
@ -729,14 +731,16 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
dst.data[2] = NULL;
dst.linesize[0] = st->codec->width * 3;
gst_ffmpeg_avpicture_fill (&src, GST_BUFFER_DATA (buf),
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
gst_ffmpeg_avpicture_fill (&src, data,
PIX_FMT_RGB24, st->codec->width, st->codec->height);
av_picture_copy (&dst, &src, PIX_FMT_RGB24,
st->codec->width, st->codec->height);
gst_buffer_unmap (buf, data, size);
} else {
pkt.data = GST_BUFFER_DATA (buf);
pkt.size = GST_BUFFER_SIZE (buf);
pkt.data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
pkt.size = size;
}
pkt.stream_index = best_pad->padnum;
@ -752,9 +756,12 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
else
pkt.duration = 0;
av_write_frame (ffmpegmux->context, &pkt);
gst_buffer_unref (buf);
if (need_free)
if (need_free) {
g_free (pkt.data);
} else {
gst_buffer_unmap (buf, pkt.data, pkt.size);
}
gst_buffer_unref (buf);
} else {
/* close down */
av_write_trailer (ffmpegmux->context);

View file

@ -572,14 +572,18 @@ gst_post_proc_transform_ip (GstBaseTransform * btrans, GstBuffer * in)
gint stride[3];
guint8 *outplane[3];
guint8 *inplane[3];
guint8 *data;
gsize size;
/* postprocess the buffer ! */
postproc = (GstPostProc *) btrans;
data = gst_buffer_map (in, &size, NULL, GST_MAP_READWRITE);
stride[0] = postproc->ystride;
stride[1] = postproc->ustride;
stride[2] = postproc->vstride;
outplane[0] = inplane[0] = GST_BUFFER_DATA (in);
outplane[0] = inplane[0] = data;
outplane[1] = inplane[1] = outplane[0] + postproc->ysize;
outplane[2] = inplane[2] = outplane[1] + postproc->usize;
@ -590,6 +594,8 @@ gst_post_proc_transform_ip (GstBaseTransform * btrans, GstBuffer * in)
postproc->width, postproc->height, (int8_t *) "", 0,
postproc->mode, postproc->context, 0);
gst_buffer_unmap (in, data, size);
return GST_FLOW_OK;
}

View file

@ -176,7 +176,7 @@ static GstCaps *gst_ffmpegscale_transform_caps (GstBaseTransform * trans,
static void gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static gboolean gst_ffmpegscale_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, guint * size);
GstCaps * caps, gsize * size);
static gboolean gst_ffmpegscale_set_caps (GstBaseTransform * trans,
GstCaps * incaps, GstCaps * outcaps);
static GstFlowReturn gst_ffmpegscale_transform (GstBaseTransform * trans,
@ -475,7 +475,7 @@ gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
static gboolean
gst_ffmpegscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size)
gsize * size)
{
gint width, height;
GstVideoFormat format;
@ -678,18 +678,26 @@ gst_ffmpegscale_transform (GstBaseTransform * trans, GstBuffer * inbuf,
guint8 *in_data[3] = { NULL, NULL, NULL };
guint8 *out_data[3] = { NULL, NULL, NULL };
gint i;
guint8 *indata, *outdata;
gsize insize, outsize;
indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
outdata = gst_buffer_map (outbuf, &outsize, NULL, GST_MAP_WRITE);
for (i = 0; i < 3; i++) {
/* again; stay close to the ffmpeg offset way */
if (!i || scale->in_offset[i])
in_data[i] = GST_BUFFER_DATA (inbuf) + scale->in_offset[i];
in_data[i] = indata + scale->in_offset[i];
if (!i || scale->out_offset[i])
out_data[i] = GST_BUFFER_DATA (outbuf) + scale->out_offset[i];
out_data[i] = outdata + scale->out_offset[i];
}
sws_scale (scale->ctx, (const guint8 **) in_data, scale->in_stride, 0,
scale->in_height, out_data, scale->out_stride);
gst_buffer_unmap (inbuf, indata, insize);
gst_buffer_unmap (outbuf, outdata, outsize);
return GST_FLOW_OK;
}