mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 20:59:44 +00:00
ffmpegviddec: Port to 0.11 again
No support for video meta, cropping, etc. yet
This commit is contained in:
parent
85f0dcb1e8
commit
6ff10a922a
1 changed files with 105 additions and 47 deletions
|
@ -24,7 +24,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef HAVE_FFMPEG_UNINSTALLED
|
#ifdef HAVE_LIBAV_UNINSTALLED
|
||||||
#include <avcodec.h>
|
#include <avcodec.h>
|
||||||
#else
|
#else
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
@ -91,7 +91,6 @@ struct _GstFFMpegVidDecClass
|
||||||
AVCodec *in_plugin;
|
AVCodec *in_plugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_FFMPEGDEC \
|
#define GST_TYPE_FFMPEGDEC \
|
||||||
(gst_ffmpegviddec_get_type())
|
(gst_ffmpegviddec_get_type())
|
||||||
#define GST_FFMPEGDEC(obj) \
|
#define GST_FFMPEGDEC(obj) \
|
||||||
|
@ -155,7 +154,7 @@ static void gst_ffmpegviddec_release_buffer (AVCodecContext * context,
|
||||||
static GstFlowReturn gst_ffmpegviddec_finish (GstVideoDecoder * decoder);
|
static GstFlowReturn gst_ffmpegviddec_finish (GstVideoDecoder * decoder);
|
||||||
static void gst_ffmpegviddec_drain (GstFFMpegVidDec * ffmpegdec);
|
static void gst_ffmpegviddec_drain (GstFFMpegVidDec * ffmpegdec);
|
||||||
|
|
||||||
#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("ffdec-params")
|
#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
|
@ -174,7 +173,7 @@ gst_ffmpegviddec_lowres_get_type (void)
|
||||||
};
|
};
|
||||||
|
|
||||||
ffmpegdec_lowres_type =
|
ffmpegdec_lowres_type =
|
||||||
g_enum_register_static ("GstFFMpegVidDecLowres", ffmpegdec_lowres);
|
g_enum_register_static ("GstLibAVVidDecLowres", ffmpegdec_lowres);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ffmpegdec_lowres_type;
|
return ffmpegdec_lowres_type;
|
||||||
|
@ -196,8 +195,7 @@ gst_ffmpegviddec_skipframe_get_type (void)
|
||||||
};
|
};
|
||||||
|
|
||||||
ffmpegdec_skipframe_type =
|
ffmpegdec_skipframe_type =
|
||||||
g_enum_register_static ("GstFFMpegVidDecSkipFrame",
|
g_enum_register_static ("GstLibAVVidDecSkipFrame", ffmpegdec_skipframe);
|
||||||
ffmpegdec_skipframe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ffmpegdec_skipframe_type;
|
return ffmpegdec_skipframe_type;
|
||||||
|
@ -218,9 +216,9 @@ gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
|
||||||
g_assert (in_plugin != NULL);
|
g_assert (in_plugin != NULL);
|
||||||
|
|
||||||
/* construct the element details struct */
|
/* construct the element details struct */
|
||||||
longname = g_strdup_printf ("FFmpeg %s decoder", in_plugin->long_name);
|
longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
|
||||||
description = g_strdup_printf ("FFmpeg %s decoder", in_plugin->name);
|
description = g_strdup_printf ("libav %s decoder", in_plugin->name);
|
||||||
gst_element_class_set_details_simple (element_class, longname,
|
gst_element_class_set_metadata (element_class, longname,
|
||||||
"Codec/Decoder/Video", description,
|
"Codec/Decoder/Video", description,
|
||||||
"Wim Taymans <wim.taymans@gmail.com>, "
|
"Wim Taymans <wim.taymans@gmail.com>, "
|
||||||
"Ronald Bultje <rbultje@ronald.bitfreak.net>, "
|
"Ronald Bultje <rbultje@ronald.bitfreak.net>, "
|
||||||
|
@ -232,11 +230,9 @@ gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
|
||||||
sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
|
sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
|
||||||
if (!sinkcaps) {
|
if (!sinkcaps) {
|
||||||
GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
|
GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
|
||||||
sinkcaps = gst_caps_from_string ("unknown/unknown");
|
sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
|
||||||
}
|
}
|
||||||
srccaps =
|
srccaps = gst_caps_new_empty_simple ("video/x-raw");
|
||||||
gst_caps_from_string
|
|
||||||
("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray");
|
|
||||||
|
|
||||||
/* pad templates */
|
/* pad templates */
|
||||||
sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
|
sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
|
||||||
|
@ -283,7 +279,7 @@ gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (gobject_class, PROP_DEBUG_MV,
|
g_object_class_install_property (gobject_class, PROP_DEBUG_MV,
|
||||||
g_param_spec_boolean ("debug-mv", "Debug motion vectors",
|
g_param_spec_boolean ("debug-mv", "Debug motion vectors",
|
||||||
"Whether ffmpeg should print motion vectors on top of the image",
|
"Whether libav should print motion vectors on top of the image",
|
||||||
DEFAULT_DEBUG_MV, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_DEBUG_MV, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
caps = klass->in_plugin->capabilities;
|
caps = klass->in_plugin->capabilities;
|
||||||
|
@ -378,7 +374,7 @@ gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
|
||||||
ffmpegdec->opened = TRUE;
|
ffmpegdec->opened = TRUE;
|
||||||
ffmpegdec->is_realvideo = FALSE;
|
ffmpegdec->is_realvideo = FALSE;
|
||||||
|
|
||||||
GST_LOG_OBJECT (ffmpegdec, "Opened ffmpeg codec %s, id %d",
|
GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
|
||||||
oclass->in_plugin->name, oclass->in_plugin->id);
|
oclass->in_plugin->name, oclass->in_plugin->id);
|
||||||
|
|
||||||
switch (oclass->in_plugin->id) {
|
switch (oclass->in_plugin->id) {
|
||||||
|
@ -401,7 +397,7 @@ gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
|
||||||
could_not_open:
|
could_not_open:
|
||||||
{
|
{
|
||||||
gst_ffmpegviddec_close (ffmpegdec);
|
gst_ffmpegviddec_close (ffmpegdec);
|
||||||
GST_DEBUG_OBJECT (ffmpegdec, "ffdec_%s: Failed to open FFMPEG codec",
|
GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
|
||||||
oclass->in_plugin->name);
|
oclass->in_plugin->name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -562,6 +558,8 @@ alloc_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
|
||||||
fsize = GST_VIDEO_INFO_SIZE (&ffmpegdec->output_state->info);
|
fsize = GST_VIDEO_INFO_SIZE (&ffmpegdec->output_state->info);
|
||||||
|
|
||||||
if (!ffmpegdec->context->palctrl && ffmpegdec->can_allocate_aligned) {
|
if (!ffmpegdec->context->palctrl && ffmpegdec->can_allocate_aligned) {
|
||||||
|
GstMapInfo minfo;
|
||||||
|
|
||||||
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 =
|
ret =
|
||||||
|
@ -571,12 +569,19 @@ alloc_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
|
||||||
goto alloc_failed;
|
goto alloc_failed;
|
||||||
|
|
||||||
/* If buffer isn't 128-bit aligned, create a memaligned one ourselves */
|
/* If buffer isn't 128-bit aligned, create a memaligned one ourselves */
|
||||||
if (((uintptr_t) GST_BUFFER_DATA (frame->output_buffer)) % 16) {
|
if (!gst_buffer_map (frame->output_buffer, &minfo,
|
||||||
|
GST_MAP_READ | GST_MAP_WRITE))
|
||||||
|
goto alloc_failed;
|
||||||
|
|
||||||
|
if (((uintptr_t) minfo.data) % 16) {
|
||||||
|
gst_buffer_unmap (frame->output_buffer, &minfo);
|
||||||
GST_DEBUG_OBJECT (ffmpegdec,
|
GST_DEBUG_OBJECT (ffmpegdec,
|
||||||
"Downstream can't allocate aligned buffers.");
|
"Downstream can't allocate aligned buffers.");
|
||||||
ffmpegdec->can_allocate_aligned = FALSE;
|
ffmpegdec->can_allocate_aligned = FALSE;
|
||||||
gst_buffer_unref (frame->output_buffer);
|
gst_buffer_unref (frame->output_buffer);
|
||||||
frame->output_buffer = new_aligned_buffer (fsize, NULL);
|
frame->output_buffer = new_aligned_buffer (fsize);
|
||||||
|
} else {
|
||||||
|
gst_buffer_unmap (frame->output_buffer, &minfo);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (ffmpegdec,
|
GST_LOG_OBJECT (ffmpegdec,
|
||||||
|
@ -585,7 +590,7 @@ alloc_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
|
||||||
* fsize contains the size of the palette, so the overall size
|
* fsize contains the size of the palette, so the overall size
|
||||||
* is bigger than ffmpegcolorspace's unit size, which will
|
* is bigger than ffmpegcolorspace's unit size, which will
|
||||||
* prompt GstBaseTransform to complain endlessly ... */
|
* prompt GstBaseTransform to complain endlessly ... */
|
||||||
frame->output_buffer = new_aligned_buffer (fsize, NULL);
|
frame->output_buffer = new_aligned_buffer (fsize);
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,10 +610,38 @@ alloc_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstVideoCodecFrame *frame;
|
||||||
|
gboolean mapped;
|
||||||
|
GstVideoFrame vframe;
|
||||||
|
} GstFFMpegVidDecVideoFrame;
|
||||||
|
|
||||||
|
static GstFFMpegVidDecVideoFrame *
|
||||||
|
gst_ffmpegviddec_video_frame_new (GstVideoCodecFrame * frame)
|
||||||
|
{
|
||||||
|
GstFFMpegVidDecVideoFrame *dframe;
|
||||||
|
|
||||||
|
dframe = g_slice_new0 (GstFFMpegVidDecVideoFrame);
|
||||||
|
dframe->frame = gst_video_codec_frame_ref (frame);
|
||||||
|
|
||||||
|
return dframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ffmpegviddec_video_frame_free (GstFFMpegVidDecVideoFrame * frame)
|
||||||
|
{
|
||||||
|
if (frame->mapped)
|
||||||
|
gst_video_frame_unmap (&frame->vframe);
|
||||||
|
gst_video_codec_frame_unref (frame->frame);
|
||||||
|
g_slice_free (GstFFMpegVidDecVideoFrame, frame);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
{
|
{
|
||||||
GstVideoCodecFrame *frame;
|
GstVideoCodecFrame *frame;
|
||||||
|
GstFFMpegVidDecVideoFrame *dframe;
|
||||||
GstFFMpegVidDec *ffmpegdec;
|
GstFFMpegVidDec *ffmpegdec;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint coded_width, coded_height;
|
gint coded_width, coded_height;
|
||||||
|
@ -617,7 +650,6 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
GstVideoInfo *info;
|
GstVideoInfo *info;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
|
||||||
ffmpegdec = (GstFFMpegVidDec *) context->opaque;
|
ffmpegdec = (GstFFMpegVidDec *) context->opaque;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec, "getting buffer");
|
GST_DEBUG_OBJECT (ffmpegdec, "getting buffer");
|
||||||
|
@ -633,7 +665,7 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
if (G_UNLIKELY (frame == NULL))
|
if (G_UNLIKELY (frame == NULL))
|
||||||
goto no_frame;
|
goto no_frame;
|
||||||
|
|
||||||
picture->opaque = frame;
|
picture->opaque = dframe = gst_ffmpegviddec_video_frame_new (frame);
|
||||||
|
|
||||||
if (!ffmpegdec->current_dr) {
|
if (!ffmpegdec->current_dr) {
|
||||||
GST_LOG_OBJECT (ffmpegdec, "direct rendering disabled, fallback alloc");
|
GST_LOG_OBJECT (ffmpegdec, "direct rendering disabled, fallback alloc");
|
||||||
|
@ -676,12 +708,19 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
|
|
||||||
/* Fill avpicture */
|
/* Fill avpicture */
|
||||||
info = &ffmpegdec->output_state->info;
|
info = &ffmpegdec->output_state->info;
|
||||||
|
if (!gst_video_frame_map (&dframe->vframe, info, dframe->frame->output_buffer,
|
||||||
|
GST_MAP_READ | GST_MAP_WRITE)) {
|
||||||
|
GST_LOG_OBJECT (ffmpegdec, "failed to map frame, fallback alloc");
|
||||||
|
gst_buffer_unref (frame->output_buffer);
|
||||||
|
frame->output_buffer = NULL;
|
||||||
|
return avcodec_default_get_buffer (context, picture);
|
||||||
|
}
|
||||||
|
dframe->mapped = TRUE;
|
||||||
|
|
||||||
for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
|
for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
|
||||||
if (c < GST_VIDEO_INFO_N_PLANES (info)) {
|
if (c < GST_VIDEO_INFO_N_PLANES (info)) {
|
||||||
picture->data[c] =
|
picture->data[c] = GST_VIDEO_FRAME_PLANE_DATA (&dframe->vframe, c);
|
||||||
GST_BUFFER_DATA (frame->output_buffer) +
|
picture->linesize[c] = GST_VIDEO_FRAME_COMP_STRIDE (&dframe->vframe, c);
|
||||||
GST_VIDEO_INFO_PLANE_OFFSET (info, c);
|
|
||||||
picture->linesize[c] = GST_VIDEO_INFO_PLANE_STRIDE (info, c);
|
|
||||||
} else {
|
} else {
|
||||||
picture->data[c] = NULL;
|
picture->data[c] = NULL;
|
||||||
picture->linesize[c] = 0;
|
picture->linesize[c] = 0;
|
||||||
|
@ -710,12 +749,13 @@ static void
|
||||||
gst_ffmpegviddec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
gst_ffmpegviddec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
GstVideoCodecFrame *frame;
|
GstFFMpegVidDecVideoFrame *frame;
|
||||||
GstFFMpegVidDec *ffmpegdec;
|
GstFFMpegVidDec *ffmpegdec;
|
||||||
|
|
||||||
ffmpegdec = (GstFFMpegVidDec *) context->opaque;
|
ffmpegdec = (GstFFMpegVidDec *) context->opaque;
|
||||||
frame = (GstVideoCodecFrame *) picture->opaque;
|
frame = (GstFFMpegVidDecVideoFrame *) picture->opaque;
|
||||||
GST_DEBUG_OBJECT (ffmpegdec, "release frame %d", frame->system_frame_number);
|
GST_DEBUG_OBJECT (ffmpegdec, "release frame %d",
|
||||||
|
frame->frame->system_frame_number);
|
||||||
|
|
||||||
/* check if it was our buffer */
|
/* check if it was our buffer */
|
||||||
if (picture->type != FF_BUFFER_TYPE_USER) {
|
if (picture->type != FF_BUFFER_TYPE_USER) {
|
||||||
|
@ -726,7 +766,7 @@ gst_ffmpegviddec_release_buffer (AVCodecContext * context, AVFrame * picture)
|
||||||
/* we remove the opaque data now */
|
/* we remove the opaque data now */
|
||||||
picture->opaque = NULL;
|
picture->opaque = NULL;
|
||||||
|
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_ffmpegviddec_video_frame_free (frame);
|
||||||
|
|
||||||
/* zero out the reference in ffmpeg */
|
/* zero out the reference in ffmpeg */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
|
@ -906,6 +946,7 @@ get_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
AVPicture pic, *outpic;
|
AVPicture pic, *outpic;
|
||||||
|
GstVideoFrame vframe;
|
||||||
GstVideoInfo *info;
|
GstVideoInfo *info;
|
||||||
gint c;
|
gint c;
|
||||||
|
|
||||||
|
@ -919,12 +960,14 @@ get_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
|
||||||
* This patched up version does */
|
* This patched up version does */
|
||||||
/* Fill avpicture */
|
/* Fill avpicture */
|
||||||
info = &ffmpegdec->output_state->info;
|
info = &ffmpegdec->output_state->info;
|
||||||
|
if (!gst_video_frame_map (&vframe, info, frame->output_buffer,
|
||||||
|
GST_MAP_READ | GST_MAP_WRITE))
|
||||||
|
goto alloc_failed;
|
||||||
|
|
||||||
for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
|
for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
|
||||||
if (c < GST_VIDEO_INFO_N_COMPONENTS (info)) {
|
if (c < GST_VIDEO_INFO_N_COMPONENTS (info)) {
|
||||||
pic.data[c] =
|
pic.data[c] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, c);
|
||||||
GST_BUFFER_DATA (frame->output_buffer) +
|
pic.linesize[c] = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, c);
|
||||||
GST_VIDEO_INFO_COMP_OFFSET (info, c);
|
|
||||||
pic.linesize[c] = GST_VIDEO_INFO_COMP_STRIDE (info, c);
|
|
||||||
} else {
|
} else {
|
||||||
pic.data[c] = NULL;
|
pic.data[c] = NULL;
|
||||||
pic.linesize[c] = 0;
|
pic.linesize[c] = 0;
|
||||||
|
@ -942,6 +985,8 @@ get_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
|
||||||
av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt,
|
av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt,
|
||||||
GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
|
GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
|
||||||
|
|
||||||
|
gst_video_frame_unmap (&vframe);
|
||||||
|
|
||||||
ffmpegdec->picture->reordered_opaque = -1;
|
ffmpegdec->picture->reordered_opaque = -1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -985,6 +1030,7 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
gboolean decode;
|
gboolean decode;
|
||||||
gint skip_frame = AVDISCARD_DEFAULT;
|
gint skip_frame = AVDISCARD_DEFAULT;
|
||||||
GstVideoCodecFrame *out_frame;
|
GstVideoCodecFrame *out_frame;
|
||||||
|
GstFFMpegVidDecVideoFrame *out_dframe;
|
||||||
AVPacket packet;
|
AVPacket packet;
|
||||||
|
|
||||||
*ret = GST_FLOW_OK;
|
*ret = GST_FLOW_OK;
|
||||||
|
@ -1034,6 +1080,16 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
|
|
||||||
/* now decode the frame */
|
/* now decode the frame */
|
||||||
gst_avpacket_init (&packet, data, size);
|
gst_avpacket_init (&packet, data, size);
|
||||||
|
|
||||||
|
if (ffmpegdec->context->palctrl) {
|
||||||
|
guint8 *pal;
|
||||||
|
|
||||||
|
pal = av_packet_new_side_data (&packet, AV_PKT_DATA_PALETTE,
|
||||||
|
AVPALETTE_SIZE);
|
||||||
|
memcpy (pal, ffmpegdec->context->palctrl->palette, AVPALETTE_SIZE);
|
||||||
|
GST_DEBUG_OBJECT (ffmpegdec, "copy pal %p %p", &packet, pal);
|
||||||
|
}
|
||||||
|
|
||||||
len = avcodec_decode_video2 (ffmpegdec->context,
|
len = avcodec_decode_video2 (ffmpegdec->context,
|
||||||
ffmpegdec->picture, &have_data, &packet);
|
ffmpegdec->picture, &have_data, &packet);
|
||||||
|
|
||||||
|
@ -1054,7 +1110,8 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
/* get the output picture timing info again */
|
/* get the output picture timing info again */
|
||||||
out_frame = ffmpegdec->picture->opaque;
|
out_dframe = ffmpegdec->picture->opaque;
|
||||||
|
out_frame = out_dframe->frame;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec,
|
GST_DEBUG_OBJECT (ffmpegdec,
|
||||||
"pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
|
"pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
|
||||||
|
@ -1133,15 +1190,9 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
frame->n_fields = ffmpegdec->picture->repeat_pict;
|
frame->n_fields = ffmpegdec->picture->repeat_pict;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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 (out_frame->output_buffer) -= AVPALETTE_SIZE;
|
|
||||||
|
|
||||||
/* mark as keyframe or delta unit */
|
/* mark as keyframe or delta unit */
|
||||||
if (ffmpegdec->picture->top_field_first)
|
if (ffmpegdec->picture->top_field_first)
|
||||||
GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame, GST_VIDEO_CODEC_FRAME_FLAG_TFF);
|
GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
|
||||||
|
|
||||||
|
|
||||||
*ret =
|
*ret =
|
||||||
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
|
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
|
||||||
|
@ -1214,7 +1265,7 @@ gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
|
|
||||||
if (len < 0 || have_data < 0) {
|
if (len < 0 || have_data < 0) {
|
||||||
GST_WARNING_OBJECT (ffmpegdec,
|
GST_WARNING_OBJECT (ffmpegdec,
|
||||||
"ffdec_%s: decoding error (len: %d, have_data: %d)",
|
"avdec_%s: decoding error (len: %d, have_data: %d)",
|
||||||
oclass->in_plugin->name, len, have_data);
|
oclass->in_plugin->name, len, have_data);
|
||||||
*got_data = 0;
|
*got_data = 0;
|
||||||
goto beach;
|
goto beach;
|
||||||
|
@ -1267,7 +1318,8 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
|
||||||
{
|
{
|
||||||
GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
|
GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
|
||||||
guint8 *data, *bdata;
|
guint8 *data, *bdata;
|
||||||
gint size, bsize, len, have_data;
|
gint size, len, have_data, bsize;
|
||||||
|
GstMapInfo minfo;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
/* do early keyframe check pretty bad to rely on the keyframe flag in the
|
/* do early keyframe check pretty bad to rely on the keyframe flag in the
|
||||||
|
@ -1284,11 +1336,17 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
|
||||||
GST_LOG_OBJECT (ffmpegdec,
|
GST_LOG_OBJECT (ffmpegdec,
|
||||||
"Received new data of size %u, pts:%"
|
"Received new data of size %u, pts:%"
|
||||||
GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
|
GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
|
||||||
GST_BUFFER_SIZE (frame->input_buffer),
|
gst_buffer_get_size (frame->input_buffer),
|
||||||
GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->duration));
|
GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->duration));
|
||||||
|
|
||||||
bdata = GST_BUFFER_DATA (frame->input_buffer);
|
frame->input_buffer = gst_buffer_make_writable (frame->input_buffer);
|
||||||
bsize = GST_BUFFER_SIZE (frame->input_buffer);
|
if (!gst_buffer_map (frame->input_buffer, &minfo,
|
||||||
|
GST_MAP_READ | GST_MAP_WRITE)) {
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bdata = minfo.data;
|
||||||
|
bsize = minfo.size;
|
||||||
|
|
||||||
if (ffmpegdec->do_padding) {
|
if (ffmpegdec->do_padding) {
|
||||||
/* add padding */
|
/* add padding */
|
||||||
|
@ -1576,7 +1634,7 @@ gst_ffmpegviddec_register (GstPlugin * plugin)
|
||||||
/* construct the type */
|
/* construct the type */
|
||||||
plugin_name = g_strdup ((gchar *) in_plugin->name);
|
plugin_name = g_strdup ((gchar *) in_plugin->name);
|
||||||
g_strdelimit (plugin_name, NULL, '_');
|
g_strdelimit (plugin_name, NULL, '_');
|
||||||
type_name = g_strdup_printf ("ffdec_%s", plugin_name);
|
type_name = g_strdup_printf ("avdec_%s", plugin_name);
|
||||||
g_free (plugin_name);
|
g_free (plugin_name);
|
||||||
|
|
||||||
type = g_type_from_name (type_name);
|
type = g_type_from_name (type_name);
|
||||||
|
|
Loading…
Reference in a new issue