mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
ffmpeg: port to new memory API
This commit is contained in:
parent
b304fff551
commit
8095b31f9c
7 changed files with 117 additions and 57 deletions
|
@ -89,10 +89,10 @@ static void gst_ffmpegaudioresample_finalize (GObject * object);
|
||||||
static GstCaps *gst_ffmpegaudioresample_transform_caps (GstBaseTransform *
|
static GstCaps *gst_ffmpegaudioresample_transform_caps (GstBaseTransform *
|
||||||
trans, GstPadDirection direction, GstCaps * caps);
|
trans, GstPadDirection direction, GstCaps * caps);
|
||||||
static gboolean gst_ffmpegaudioresample_transform_size (GstBaseTransform *
|
static gboolean gst_ffmpegaudioresample_transform_size (GstBaseTransform *
|
||||||
trans, GstPadDirection direction, GstCaps * caps, guint size,
|
trans, GstPadDirection direction, GstCaps * caps, gsize size,
|
||||||
GstCaps * othercaps, guint * othersize);
|
GstCaps * othercaps, gsize * othersize);
|
||||||
static gboolean gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans,
|
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,
|
static gboolean gst_ffmpegaudioresample_set_caps (GstBaseTransform * trans,
|
||||||
GstCaps * incaps, GstCaps * outcaps);
|
GstCaps * incaps, GstCaps * outcaps);
|
||||||
static GstFlowReturn gst_ffmpegaudioresample_transform (GstBaseTransform *
|
static GstFlowReturn gst_ffmpegaudioresample_transform (GstBaseTransform *
|
||||||
|
@ -174,8 +174,8 @@ gst_ffmpegaudioresample_transform_caps (GstBaseTransform * trans,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
|
gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
|
||||||
GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
|
GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
|
||||||
guint * othersize)
|
gsize * othersize)
|
||||||
{
|
{
|
||||||
gint inrate, outrate;
|
gint inrate, outrate;
|
||||||
gint inchanns, outchanns;
|
gint inchanns, outchanns;
|
||||||
|
@ -207,7 +207,7 @@ gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
|
gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
|
||||||
guint * size)
|
gsize * size)
|
||||||
{
|
{
|
||||||
gint channels;
|
gint channels;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
|
@ -263,26 +263,34 @@ gst_ffmpegaudioresample_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
||||||
GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (trans);
|
GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (trans);
|
||||||
gint nbsamples;
|
gint nbsamples;
|
||||||
gint ret;
|
gint ret;
|
||||||
|
guint8 *indata, *outdata;
|
||||||
|
gsize insize, outsize;
|
||||||
|
|
||||||
gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
|
gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
|
||||||
nbsamples = GST_BUFFER_SIZE (inbuf) / (2 * resample->in_channels);
|
|
||||||
|
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_LOG_OBJECT (resample, "input buffer duration:%" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
|
GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
|
||||||
|
|
||||||
|
outdata = gst_buffer_map (outbuf, &outsize, NULL, GST_MAP_WRITE);
|
||||||
GST_DEBUG_OBJECT (resample,
|
GST_DEBUG_OBJECT (resample,
|
||||||
"audio_resample(ctx, output:%p [size:%d], input:%p [size:%d], nbsamples:%d",
|
"audio_resample(ctx, output:%p [size:%d], input:%p [size:%d], nbsamples:%d",
|
||||||
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf),
|
outdata, outsize, indata, insize, nbsamples);
|
||||||
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf), nbsamples);
|
|
||||||
|
|
||||||
ret = audio_resample (resample->res, (short *) GST_BUFFER_DATA (outbuf),
|
ret =
|
||||||
(short *) GST_BUFFER_DATA (inbuf), nbsamples);
|
audio_resample (resample->res, (short *) outdata, (short *) indata,
|
||||||
|
nbsamples);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (resample, "audio_resample returned %d", ret);
|
GST_DEBUG_OBJECT (resample, "audio_resample returned %d", ret);
|
||||||
|
|
||||||
GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale (ret, GST_SECOND,
|
GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale (ret, GST_SECOND,
|
||||||
resample->out_rate);
|
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_LOG_OBJECT (resample, "Output buffer duration:%" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
|
GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
|
||||||
|
|
|
@ -921,15 +921,6 @@ alloc_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf,
|
||||||
GST_PAD_CAPS (ffmpegdec->srcpad), outbuf);
|
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;
|
||||||
|
|
||||||
/* 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 {
|
} else {
|
||||||
GST_LOG_OBJECT (ffmpegdec,
|
GST_LOG_OBJECT (ffmpegdec,
|
||||||
"not calling pad_alloc, we have a pallete or downstream can't give 16 byte aligned buffers.");
|
"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;
|
GstFlowReturn ret;
|
||||||
gint clip_width, clip_height;
|
gint clip_width, clip_height;
|
||||||
|
guint8 *data;
|
||||||
|
|
||||||
/* take final clipped output size */
|
/* take final clipped output size */
|
||||||
if ((clip_width = ffmpegdec->format.video.clip_width) == -1)
|
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);
|
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 */
|
/* copy the right pointers and strides in the picture object */
|
||||||
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
|
gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
|
||||||
GST_BUFFER_DATA (buf), context->pix_fmt, width, height);
|
data, context->pix_fmt, width, height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CODEC_TYPE_AUDIO:
|
case CODEC_TYPE_AUDIO:
|
||||||
|
@ -1092,6 +1096,7 @@ gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
#else
|
#else
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
#endif
|
#endif
|
||||||
|
/* FIXME, unmap buffer data */
|
||||||
|
|
||||||
/* zero out the reference in ffmpeg */
|
/* zero out the reference in ffmpeg */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
|
@ -1543,6 +1548,8 @@ get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
|
||||||
} else {
|
} else {
|
||||||
AVPicture pic, *outpic;
|
AVPicture pic, *outpic;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
GST_LOG_OBJECT (ffmpegdec, "get output buffer");
|
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.
|
/* original ffmpeg code does not handle odd sizes correctly.
|
||||||
* This patched up version does */
|
* 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);
|
ffmpegdec->context->pix_fmt, width, height);
|
||||||
|
|
||||||
outpic = (AVPicture *) ffmpegdec->picture;
|
outpic = (AVPicture *) ffmpegdec->picture;
|
||||||
|
@ -1579,6 +1588,7 @@ get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
|
||||||
(guint) (outpic->data[2] - outpic->data[0]));
|
(guint) (outpic->data[2] - outpic->data[0]));
|
||||||
|
|
||||||
av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt, width, height);
|
av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt, width, height);
|
||||||
|
gst_buffer_unmap (*outbuf, data, size);
|
||||||
}
|
}
|
||||||
ffmpegdec->picture->reordered_opaque = -1;
|
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
|
/* palette is not part of raw video frame in gst and the size
|
||||||
* of the outgoing buffer needs to be adjusted accordingly */
|
* of the outgoing buffer needs to be adjusted accordingly */
|
||||||
if (ffmpegdec->context->palctrl != NULL)
|
if (ffmpegdec->context->palctrl != NULL) {
|
||||||
GST_BUFFER_SIZE (*outbuf) -= AVPALETTE_SIZE;
|
|
||||||
|
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. */
|
/* now see if we need to clip the buffer against the segment boundaries. */
|
||||||
if (G_UNLIKELY (!clip_video_buffer (ffmpegdec, *outbuf, out_timestamp,
|
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;
|
GstClockTime stop;
|
||||||
gint64 diff, ctime, cstop;
|
gint64 diff, ctime, cstop;
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
|
gsize size, offset;
|
||||||
|
|
||||||
|
size = gst_buffer_get_size (buf);
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
GST_LOG_OBJECT (dec,
|
GST_LOG_OBJECT (dec,
|
||||||
"timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
|
"timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
|
||||||
", size %u", GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
|
", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
|
||||||
GST_BUFFER_SIZE (buf));
|
size);
|
||||||
|
|
||||||
/* can't clip without TIME segment */
|
/* can't clip without TIME segment */
|
||||||
if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
|
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 " %"
|
GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
|
||||||
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
|
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
|
||||||
|
|
||||||
GST_BUFFER_SIZE (buf) -= diff;
|
offset += diff;
|
||||||
GST_BUFFER_DATA (buf) += diff;
|
size -= diff;
|
||||||
}
|
}
|
||||||
if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
|
if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
|
||||||
/* bring clipped time to bytes */
|
/* 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 " %"
|
GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
|
||||||
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
|
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_TIMESTAMP (buf) = ctime;
|
||||||
GST_BUFFER_DURATION (buf) = cstop - 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;
|
gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||||
GstClockTime out_timestamp, out_duration;
|
GstClockTime out_timestamp, out_duration;
|
||||||
gint64 out_offset;
|
gint64 out_offset;
|
||||||
|
int16_t *odata;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec,
|
GST_DEBUG_OBJECT (ffmpegdec,
|
||||||
"size:%d, offset:%" G_GINT64_FORMAT ", ts:%" GST_TIME_FORMAT ", dur:%"
|
"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,
|
new_aligned_buffer (AVCODEC_MAX_AUDIO_FRAME_SIZE,
|
||||||
GST_PAD_CAPS (ffmpegdec->srcpad));
|
GST_PAD_CAPS (ffmpegdec->srcpad));
|
||||||
|
|
||||||
len = avcodec_decode_audio2 (ffmpegdec->context,
|
odata = gst_buffer_map (*outbuf, NULL, NULL, GST_MAP_WRITE);
|
||||||
(int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
|
len = avcodec_decode_audio2 (ffmpegdec->context, odata, &have_data,
|
||||||
|
data, size);
|
||||||
GST_DEBUG_OBJECT (ffmpegdec,
|
GST_DEBUG_OBJECT (ffmpegdec,
|
||||||
"Decode audio: len=%d, have_data=%d", len, have_data);
|
"Decode audio: len=%d, have_data=%d", len, have_data);
|
||||||
|
|
||||||
if (len >= 0 && have_data > 0) {
|
if (len >= 0 && have_data > 0) {
|
||||||
|
/* Buffer size */
|
||||||
|
gst_buffer_unmap (*outbuf, odata, have_data);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
|
GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
|
||||||
if (!gst_ffmpegdec_negotiate (ffmpegdec, FALSE)) {
|
if (!gst_ffmpegdec_negotiate (ffmpegdec, FALSE)) {
|
||||||
gst_buffer_unref (*outbuf);
|
gst_buffer_unref (*outbuf);
|
||||||
|
@ -2074,9 +2097,6 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buffer size */
|
|
||||||
GST_BUFFER_SIZE (*outbuf) = have_data;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timestamps:
|
* Timestamps:
|
||||||
*
|
*
|
||||||
|
@ -2123,6 +2143,7 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
|
||||||
goto clipped;
|
goto clipped;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
gst_buffer_unmap (*outbuf, odata, 0);
|
||||||
gst_buffer_unref (*outbuf);
|
gst_buffer_unref (*outbuf);
|
||||||
*outbuf = NULL;
|
*outbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,17 +176,23 @@ gst_ffmpegdeinterlace_chain (GstPad * pad, GstBuffer * inbuf)
|
||||||
gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE,
|
gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE,
|
||||||
deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf);
|
deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf);
|
||||||
if (result == GST_FLOW_OK) {
|
if (result == GST_FLOW_OK) {
|
||||||
gst_ffmpeg_avpicture_fill (&deinterlace->from_frame,
|
guint8 *from_data, *to_data;
|
||||||
GST_BUFFER_DATA (inbuf), deinterlace->pixfmt, deinterlace->width,
|
gsize from_size, to_size;
|
||||||
deinterlace->height);
|
|
||||||
|
|
||||||
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);
|
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
|
||||||
|
|
||||||
avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame,
|
avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame,
|
||||||
deinterlace->pixfmt, deinterlace->width, deinterlace->height);
|
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);
|
result = gst_pad_push (deinterlace->srcpad, outbuf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1269,7 +1269,7 @@ no_info:
|
||||||
static void
|
static void
|
||||||
gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
|
gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
const guint8 *data;
|
||||||
AVInputFormat *in_plugin = (AVInputFormat *) priv;
|
AVInputFormat *in_plugin = (AVInputFormat *) priv;
|
||||||
gint res = 0;
|
gint res = 0;
|
||||||
guint64 length;
|
guint64 length;
|
||||||
|
@ -1296,7 +1296,7 @@ gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
|
||||||
AVProbeData probe_data;
|
AVProbeData probe_data;
|
||||||
|
|
||||||
probe_data.filename = "";
|
probe_data.filename = "";
|
||||||
probe_data.buf = data;
|
probe_data.buf = (guint8 *) data;
|
||||||
probe_data.buf_size = length;
|
probe_data.buf_size = length;
|
||||||
|
|
||||||
res = in_plugin->read_probe (&probe_data);
|
res = in_plugin->read_probe (&probe_data);
|
||||||
|
@ -1416,6 +1416,8 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
||||||
AVPicture src, dst;
|
AVPicture src, dst;
|
||||||
const gchar *plugin_name =
|
const gchar *plugin_name =
|
||||||
((GstFFMpegDemuxClass *) (G_OBJECT_GET_CLASS (demux)))->in_plugin->name;
|
((GstFFMpegDemuxClass *) (G_OBJECT_GET_CLASS (demux)))->in_plugin->name;
|
||||||
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
if (strcmp (plugin_name, "gif") == 0) {
|
if (strcmp (plugin_name, "gif") == 0) {
|
||||||
src.data[0] = pkt.data;
|
src.data[0] = pkt.data;
|
||||||
|
@ -1429,14 +1431,16 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
||||||
avstream->codec->height);
|
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->pix_fmt, avstream->codec->width,
|
||||||
avstream->codec->height);
|
avstream->codec->height);
|
||||||
|
|
||||||
av_picture_copy (&dst, &src, avstream->codec->pix_fmt,
|
av_picture_copy (&dst, &src, avstream->codec->pix_fmt,
|
||||||
avstream->codec->width, avstream->codec->height);
|
avstream->codec->width, avstream->codec->height);
|
||||||
|
gst_buffer_unmap (outbuf, data, size);
|
||||||
} else {
|
} else {
|
||||||
memcpy (GST_BUFFER_DATA (outbuf), pkt.data, outsize);
|
gst_buffer_fill (outbuf, 0, pkt.data, outsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||||
|
@ -1456,7 +1460,7 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Sending out buffer time:%" GST_TIME_FORMAT " size:%d",
|
"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);
|
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))
|
if (G_UNLIKELY (ffpipe->srcresult != GST_FLOW_OK))
|
||||||
goto ignore;
|
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);
|
gst_adapter_push (ffpipe->adapter, buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
while (gst_adapter_available (ffpipe->adapter) >= ffpipe->needed) {
|
while (gst_adapter_available (ffpipe->adapter) >= ffpipe->needed) {
|
||||||
|
|
|
@ -704,6 +704,7 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
AVPacket pkt;
|
AVPacket pkt;
|
||||||
gboolean need_free = FALSE;
|
gboolean need_free = FALSE;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
/* push out current buffer */
|
/* push out current buffer */
|
||||||
buf = gst_collect_pads_pop (ffmpegmux->collect,
|
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) {
|
if (strcmp (ffmpegmux->context->oformat->name, "gif") == 0) {
|
||||||
AVStream *st = ffmpegmux->context->streams[best_pad->padnum];
|
AVStream *st = ffmpegmux->context->streams[best_pad->padnum];
|
||||||
AVPicture src, dst;
|
AVPicture src, dst;
|
||||||
|
guint8 *data;
|
||||||
|
|
||||||
need_free = TRUE;
|
need_free = TRUE;
|
||||||
pkt.size = st->codec->width * st->codec->height * 3;
|
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.data[2] = NULL;
|
||||||
dst.linesize[0] = st->codec->width * 3;
|
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);
|
PIX_FMT_RGB24, st->codec->width, st->codec->height);
|
||||||
|
|
||||||
av_picture_copy (&dst, &src, PIX_FMT_RGB24,
|
av_picture_copy (&dst, &src, PIX_FMT_RGB24,
|
||||||
st->codec->width, st->codec->height);
|
st->codec->width, st->codec->height);
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
} else {
|
} else {
|
||||||
pkt.data = GST_BUFFER_DATA (buf);
|
pkt.data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
pkt.size = GST_BUFFER_SIZE (buf);
|
pkt.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt.stream_index = best_pad->padnum;
|
pkt.stream_index = best_pad->padnum;
|
||||||
|
@ -752,9 +756,12 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
else
|
else
|
||||||
pkt.duration = 0;
|
pkt.duration = 0;
|
||||||
av_write_frame (ffmpegmux->context, &pkt);
|
av_write_frame (ffmpegmux->context, &pkt);
|
||||||
gst_buffer_unref (buf);
|
if (need_free) {
|
||||||
if (need_free)
|
|
||||||
g_free (pkt.data);
|
g_free (pkt.data);
|
||||||
|
} else {
|
||||||
|
gst_buffer_unmap (buf, pkt.data, pkt.size);
|
||||||
|
}
|
||||||
|
gst_buffer_unref (buf);
|
||||||
} else {
|
} else {
|
||||||
/* close down */
|
/* close down */
|
||||||
av_write_trailer (ffmpegmux->context);
|
av_write_trailer (ffmpegmux->context);
|
||||||
|
|
|
@ -572,14 +572,18 @@ gst_post_proc_transform_ip (GstBaseTransform * btrans, GstBuffer * in)
|
||||||
gint stride[3];
|
gint stride[3];
|
||||||
guint8 *outplane[3];
|
guint8 *outplane[3];
|
||||||
guint8 *inplane[3];
|
guint8 *inplane[3];
|
||||||
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
/* postprocess the buffer ! */
|
/* postprocess the buffer ! */
|
||||||
postproc = (GstPostProc *) btrans;
|
postproc = (GstPostProc *) btrans;
|
||||||
|
|
||||||
|
data = gst_buffer_map (in, &size, NULL, GST_MAP_READWRITE);
|
||||||
|
|
||||||
stride[0] = postproc->ystride;
|
stride[0] = postproc->ystride;
|
||||||
stride[1] = postproc->ustride;
|
stride[1] = postproc->ustride;
|
||||||
stride[2] = postproc->vstride;
|
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[1] = inplane[1] = outplane[0] + postproc->ysize;
|
||||||
outplane[2] = inplane[2] = outplane[1] + postproc->usize;
|
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->width, postproc->height, (int8_t *) "", 0,
|
||||||
postproc->mode, postproc->context, 0);
|
postproc->mode, postproc->context, 0);
|
||||||
|
|
||||||
|
gst_buffer_unmap (in, data, size);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ static GstCaps *gst_ffmpegscale_transform_caps (GstBaseTransform * trans,
|
||||||
static void gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
|
static void gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
|
||||||
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
|
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
|
||||||
static gboolean gst_ffmpegscale_get_unit_size (GstBaseTransform * trans,
|
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,
|
static gboolean gst_ffmpegscale_set_caps (GstBaseTransform * trans,
|
||||||
GstCaps * incaps, GstCaps * outcaps);
|
GstCaps * incaps, GstCaps * outcaps);
|
||||||
static GstFlowReturn gst_ffmpegscale_transform (GstBaseTransform * trans,
|
static GstFlowReturn gst_ffmpegscale_transform (GstBaseTransform * trans,
|
||||||
|
@ -475,7 +475,7 @@ gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ffmpegscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
|
gst_ffmpegscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
|
||||||
guint * size)
|
gsize * size)
|
||||||
{
|
{
|
||||||
gint width, height;
|
gint width, height;
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
|
@ -678,18 +678,26 @@ gst_ffmpegscale_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
||||||
guint8 *in_data[3] = { NULL, NULL, NULL };
|
guint8 *in_data[3] = { NULL, NULL, NULL };
|
||||||
guint8 *out_data[3] = { NULL, NULL, NULL };
|
guint8 *out_data[3] = { NULL, NULL, NULL };
|
||||||
gint i;
|
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++) {
|
for (i = 0; i < 3; i++) {
|
||||||
/* again; stay close to the ffmpeg offset way */
|
/* again; stay close to the ffmpeg offset way */
|
||||||
if (!i || scale->in_offset[i])
|
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])
|
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,
|
sws_scale (scale->ctx, (const guint8 **) in_data, scale->in_stride, 0,
|
||||||
scale->in_height, out_data, scale->out_stride);
|
scale->in_height, out_data, scale->out_stride);
|
||||||
|
|
||||||
|
gst_buffer_unmap (inbuf, indata, insize);
|
||||||
|
gst_buffer_unmap (outbuf, outdata, outsize);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue