mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-30 02:58:24 +00:00
Adapts it slightly to work with spider, and adds one change suggested by the ffmpeg team
Original commit message from CVS: Adapts it slightly to work with spider, and adds one change suggested by the ffmpeg team
This commit is contained in:
parent
2d397aeedf
commit
1c7afe57e3
1 changed files with 30 additions and 31 deletions
|
@ -35,7 +35,7 @@ typedef struct _GstFFMpegDecAll {
|
||||||
|
|
||||||
GstPad *srcpad, *sinkpad;
|
GstPad *srcpad, *sinkpad;
|
||||||
|
|
||||||
AVCodecContext context;
|
AVCodecContext *context;
|
||||||
AVFrame picture;
|
AVFrame picture;
|
||||||
} GstFFMpegDecAll;
|
} GstFFMpegDecAll;
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ GST_PAD_TEMPLATE_FACTORY(sink_templ,
|
||||||
"gstffmpeg_sink_avivideo",
|
"gstffmpeg_sink_avivideo",
|
||||||
"video/avi",
|
"video/avi",
|
||||||
"format", GST_PROPS_STRING("strf_vids"),
|
"format", GST_PROPS_STRING("strf_vids"),
|
||||||
"compression", GST_PROPS_LIST (
|
/*"compression", GST_PROPS_LIST (
|
||||||
GST_PROPS_FOURCC (GST_MAKE_FOURCC('M','J','P','G')),
|
GST_PROPS_FOURCC (GST_MAKE_FOURCC('M','J','P','G')),
|
||||||
GST_PROPS_FOURCC (GST_MAKE_FOURCC('J','P','E','G')),
|
GST_PROPS_FOURCC (GST_MAKE_FOURCC('J','P','E','G')),
|
||||||
GST_PROPS_FOURCC (GST_MAKE_FOURCC('V','I','X','L')),
|
GST_PROPS_FOURCC (GST_MAKE_FOURCC('V','I','X','L')),
|
||||||
|
@ -139,7 +139,7 @@ GST_PAD_TEMPLATE_FACTORY(sink_templ,
|
||||||
GST_PROPS_FOURCC (GST_MAKE_FOURCC('M','P','4','3')),
|
GST_PROPS_FOURCC (GST_MAKE_FOURCC('M','P','4','3')),
|
||||||
GST_PROPS_FOURCC (GST_MAKE_FOURCC('W','M','V','1')),
|
GST_PROPS_FOURCC (GST_MAKE_FOURCC('W','M','V','1')),
|
||||||
GST_PROPS_FOURCC (GST_MAKE_FOURCC('W','M','V','2'))
|
GST_PROPS_FOURCC (GST_MAKE_FOURCC('W','M','V','2'))
|
||||||
),
|
),*/
|
||||||
"width", GST_PROPS_INT_RANGE (16, 4096),
|
"width", GST_PROPS_INT_RANGE (16, 4096),
|
||||||
"height", GST_PROPS_INT_RANGE (16, 4096)
|
"height", GST_PROPS_INT_RANGE (16, 4096)
|
||||||
),
|
),
|
||||||
|
@ -184,6 +184,7 @@ GST_PAD_TEMPLATE_FACTORY(sink_templ,
|
||||||
/* A number of functon prototypes are given so we can refer to them later. */
|
/* A number of functon prototypes are given so we can refer to them later. */
|
||||||
static void gst_ffmpegdecall_class_init (GstFFMpegDecAllClass *klass);
|
static void gst_ffmpegdecall_class_init (GstFFMpegDecAllClass *klass);
|
||||||
static void gst_ffmpegdecall_init (GstFFMpegDecAll *ffmpegdec);
|
static void gst_ffmpegdecall_init (GstFFMpegDecAll *ffmpegdec);
|
||||||
|
static void gst_ffmpegdecall_destroy (GObject *obj);
|
||||||
static void gst_ffmpegdecall_chain (GstPad *pad, GstBuffer *buffer);
|
static void gst_ffmpegdecall_chain (GstPad *pad, GstBuffer *buffer);
|
||||||
static GstPadConnectReturn gst_ffmpegdecall_connect (GstPad *pad, GstCaps *caps);
|
static GstPadConnectReturn gst_ffmpegdecall_connect (GstPad *pad, GstCaps *caps);
|
||||||
|
|
||||||
|
@ -228,7 +229,11 @@ gst_ffmpegdecall_get_type(void)
|
||||||
static void
|
static void
|
||||||
gst_ffmpegdecall_class_init (GstFFMpegDecAllClass *klass)
|
gst_ffmpegdecall_class_init (GstFFMpegDecAllClass *klass)
|
||||||
{
|
{
|
||||||
|
GObjectClass *obj_class = (GObjectClass*) klass;
|
||||||
|
|
||||||
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
|
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
obj_class->dispose = gst_ffmpegdecall_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -248,6 +253,16 @@ gst_ffmpegdecall_init(GstFFMpegDecAll *ffmpegdec)
|
||||||
ffmpegdec->sinkpad);
|
ffmpegdec->sinkpad);
|
||||||
gst_element_add_pad(GST_ELEMENT(ffmpegdec),
|
gst_element_add_pad(GST_ELEMENT(ffmpegdec),
|
||||||
ffmpegdec->srcpad);
|
ffmpegdec->srcpad);
|
||||||
|
|
||||||
|
ffmpegdec->context = avcodec_alloc_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ffmpegdecall_destroy (GObject *obj)
|
||||||
|
{
|
||||||
|
GstFFMpegDecAll *ffmpegdec = GST_FFMPEGDECALL(obj);
|
||||||
|
avcodec_close(ffmpegdec->context);
|
||||||
|
av_free(ffmpegdec->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstPadConnectReturn
|
static GstPadConnectReturn
|
||||||
|
@ -256,22 +271,18 @@ gst_ffmpegdecall_connect (GstPad *pad, GstCaps *caps)
|
||||||
GstFFMpegDecAll *ffmpegdec = GST_FFMPEGDECALL(gst_pad_get_parent(pad));
|
GstFFMpegDecAll *ffmpegdec = GST_FFMPEGDECALL(gst_pad_get_parent(pad));
|
||||||
enum CodecID id;
|
enum CodecID id;
|
||||||
AVCodec *plugin;
|
AVCodec *plugin;
|
||||||
GstCaps *newcaps;
|
|
||||||
|
|
||||||
if (!GST_CAPS_IS_FIXED(caps))
|
if (!GST_CAPS_IS_FIXED(caps))
|
||||||
return GST_PAD_CONNECT_DELAYED;
|
return GST_PAD_CONNECT_DELAYED;
|
||||||
|
|
||||||
avcodec_get_context_defaults(&ffmpegdec->context);
|
avcodec_get_context_defaults(ffmpegdec->context);
|
||||||
|
|
||||||
if ((id = gst_ffmpeg_caps_to_codecid(caps, &ffmpegdec->context)) == CODEC_ID_NONE) {
|
if ((id = gst_ffmpeg_caps_to_codecid(caps, ffmpegdec->context)) == CODEC_ID_NONE) {
|
||||||
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
||||||
"Failed to find corresponding codecID");
|
"Failed to find corresponding codecID");
|
||||||
return GST_PAD_CONNECT_REFUSED;
|
return GST_PAD_CONNECT_REFUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffmpegdec->context.codec_type == CODEC_TYPE_VIDEO)
|
|
||||||
ffmpegdec->context.pix_fmt = PIX_FMT_YUV420P /*ANY*/;
|
|
||||||
|
|
||||||
if ((plugin = avcodec_find_decoder(id)) == NULL) {
|
if ((plugin = avcodec_find_decoder(id)) == NULL) {
|
||||||
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
||||||
"Failed to find an avdecoder for id=%d", id);
|
"Failed to find an avdecoder for id=%d", id);
|
||||||
|
@ -280,28 +291,14 @@ gst_ffmpegdecall_connect (GstPad *pad, GstCaps *caps)
|
||||||
|
|
||||||
/* we dont send complete frames */
|
/* we dont send complete frames */
|
||||||
if (plugin->capabilities & CODEC_CAP_TRUNCATED)
|
if (plugin->capabilities & CODEC_CAP_TRUNCATED)
|
||||||
ffmpegdec->context.flags |= CODEC_FLAG_TRUNCATED;
|
ffmpegdec->context->flags |= CODEC_FLAG_TRUNCATED;
|
||||||
|
|
||||||
if (avcodec_open(&ffmpegdec->context, plugin)) {
|
if (avcodec_open(ffmpegdec->context, plugin)) {
|
||||||
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
||||||
"Failed to open FFMPEG codec for id=%d", id);
|
"Failed to open FFMPEG codec for id=%d", id);
|
||||||
return GST_PAD_CONNECT_REFUSED;
|
return GST_PAD_CONNECT_REFUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffmpegdec->context.width > 0 && ffmpegdec->context.height > 0) {
|
|
||||||
/* set caps on src pad based on context.pix_fmt && width/height */
|
|
||||||
newcaps = gst_ffmpeg_codecid_to_caps(CODEC_ID_RAWVIDEO,
|
|
||||||
&ffmpegdec->context);
|
|
||||||
if (!newcaps) {
|
|
||||||
GST_DEBUG(GST_CAT_PLUGIN_INFO,
|
|
||||||
"Failed to create caps for other end (pix_fmt=%d)",
|
|
||||||
ffmpegdec->context.pix_fmt);
|
|
||||||
return GST_PAD_CONNECT_REFUSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return gst_pad_try_set_caps(ffmpegdec->srcpad, newcaps);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GST_PAD_CONNECT_OK;
|
return GST_PAD_CONNECT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,9 +315,9 @@ gst_ffmpegdecall_chain (GstPad *pad, GstBuffer *inbuf)
|
||||||
size = GST_BUFFER_SIZE (inbuf);
|
size = GST_BUFFER_SIZE (inbuf);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ffmpegdec->context.frame_number++;
|
ffmpegdec->context->frame_number++;
|
||||||
|
|
||||||
len = avcodec_decode_video (&ffmpegdec->context, &ffmpegdec->picture,
|
len = avcodec_decode_video (ffmpegdec->context, &ffmpegdec->picture,
|
||||||
&have_picture, data, size);
|
&have_picture, data, size);
|
||||||
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
|
@ -333,17 +330,17 @@ gst_ffmpegdecall_chain (GstPad *pad, GstBuffer *inbuf)
|
||||||
guchar *picdata, *picdata2, *outdata, *outdata2;
|
guchar *picdata, *picdata2, *outdata, *outdata2;
|
||||||
gint xsize, i, width, height;
|
gint xsize, i, width, height;
|
||||||
|
|
||||||
height = ffmpegdec->context.height;
|
height = ffmpegdec->context->height;
|
||||||
width = ffmpegdec->context.width;
|
width = ffmpegdec->context->width;
|
||||||
|
|
||||||
if (!GST_PAD_CAPS(ffmpegdec->srcpad)) {
|
if (!GST_PAD_CAPS(ffmpegdec->srcpad)) {
|
||||||
GstCaps *newcaps = gst_ffmpeg_codecid_to_caps(CODEC_ID_RAWVIDEO,
|
GstCaps *newcaps = gst_ffmpeg_codecid_to_caps(CODEC_ID_RAWVIDEO,
|
||||||
&ffmpegdec->context);
|
ffmpegdec->context);
|
||||||
|
|
||||||
if (!newcaps) {
|
if (!newcaps) {
|
||||||
gst_element_error(GST_ELEMENT(ffmpegdec),
|
gst_element_error(GST_ELEMENT(ffmpegdec),
|
||||||
"Failed to create caps for ffmpeg (pix_fmt=%d)",
|
"Failed to create caps for ffmpeg (pix_fmt=%d)",
|
||||||
ffmpegdec->context.pix_fmt);
|
ffmpegdec->context->pix_fmt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +405,8 @@ plugin_init (GModule *module, GstPlugin *plugin)
|
||||||
&gst_ffmpegdecall_details);
|
&gst_ffmpegdecall_details);
|
||||||
g_return_val_if_fail(factory != NULL, FALSE);
|
g_return_val_if_fail(factory != NULL, FALSE);
|
||||||
|
|
||||||
|
gst_element_factory_set_rank(factory, GST_ELEMENT_RANK_PRIMARY);
|
||||||
|
|
||||||
gst_element_factory_add_pad_template(factory,
|
gst_element_factory_add_pad_template(factory,
|
||||||
GST_PAD_TEMPLATE_GET(src_templ));
|
GST_PAD_TEMPLATE_GET(src_templ));
|
||||||
gst_element_factory_add_pad_template(factory,
|
gst_element_factory_add_pad_template(factory,
|
||||||
|
|
Loading…
Reference in a new issue