mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-14 13:21:28 +00:00
ext/ffmpeg/: fix typo in RGB masks, and move back to "old" colorspace capsnego code until whoever wrote this new crap...
Original commit message from CVS: 2003-12-24 Ronald Bultje <rbultje@ronald.bitfreak.net> * ext/ffmpeg/gstffmpegcodecmap.c: * ext/ffmpeg/gstffmpegcolorspace.c: (gst_ffmpegcsp_getcaps), (gst_ffmpegcsp_srcconnect_func), (gst_ffmpegcsp_sinkconnect), (gst_ffmpegcsp_srcconnect), (gst_ffmpegcsp_get_type), (gst_ffmpegcsp_base_init), (gst_ffmpegcsp_class_init), (gst_ffmpegcsp_init), (gst_ffmpegcsp_chain), (gst_ffmpegcsp_change_state), (gst_ffmpegcsp_set_property), (gst_ffmpegcsp_get_property), (gst_ffmpegcsp_register): fix typo in RGB masks, and move back to "old" colorspace capsnego code until whoever wrote this new crap has actually tested it so that it works. And yes, this works, keep it that way please.
This commit is contained in:
parent
5153d56e2c
commit
2a754af351
2 changed files with 256 additions and 155 deletions
|
@ -932,9 +932,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps *caps,
|
|||
break;
|
||||
case 32:
|
||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||
if (rmask == 0xff0000) {
|
||||
if (rmask == 0x00ff0000) {
|
||||
#else
|
||||
if (rmask == 0x0000ff) {
|
||||
if (rmask == 0x0000ff00) {
|
||||
#endif
|
||||
pix_fmt = PIX_FMT_RGBA32;
|
||||
}
|
||||
|
|
|
@ -32,19 +32,16 @@
|
|||
|
||||
#include "gstffmpegcodecmap.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (debug_ffmpeg_csp);
|
||||
#define GST_CAT_DEFAULT debug_ffmpeg_csp
|
||||
|
||||
#define GST_TYPE_FFMPEG_CSP \
|
||||
#define GST_TYPE_FFMPEGCSP \
|
||||
(gst_ffmpegcsp_get_type())
|
||||
#define GST_FFMPEG_CSP(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEG_CSP,GstFFMpegCsp))
|
||||
#define GST_FFMPEG_CSP_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEG_CSP,GstFFMpegCsp))
|
||||
#define GST_IS_FFMPEG_CSP(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEG_CSP))
|
||||
#define GST_IS_FFMPEG_CSP_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEG_CSP))
|
||||
#define GST_FFMPEGCSP(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGCSP,GstFFMpegCsp))
|
||||
#define GST_FFMPEGCSP_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGCSP,GstFFMpegCsp))
|
||||
#define GST_IS_FFMPEGCSP(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGCSP))
|
||||
#define GST_IS_FFMPEGCSP_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGCSP))
|
||||
|
||||
typedef struct _GstFFMpegCsp GstFFMpegCsp;
|
||||
typedef struct _GstFFMpegCspClass GstFFMpegCspClass;
|
||||
|
@ -52,18 +49,16 @@ typedef struct _GstFFMpegCspClass GstFFMpegCspClass;
|
|||
struct _GstFFMpegCsp {
|
||||
GstElement element;
|
||||
|
||||
GstPad * sinkpad;
|
||||
GstPad * srcpad;
|
||||
gboolean need_caps_nego;
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
gdouble fps;
|
||||
|
||||
enum PixelFormat from_pixfmt;
|
||||
enum PixelFormat to_pixfmt;
|
||||
AVFrame * from_frame;
|
||||
AVFrame * to_frame;
|
||||
gint width, height;
|
||||
gfloat fps;
|
||||
enum PixelFormat
|
||||
from_pixfmt,
|
||||
to_pixfmt;
|
||||
AVFrame *from_frame,
|
||||
*to_frame;
|
||||
GstCaps *sinkcaps;
|
||||
};
|
||||
|
||||
struct _GstFFMpegCspClass {
|
||||
|
@ -91,92 +86,160 @@ enum {
|
|||
|
||||
static GType gst_ffmpegcsp_get_type (void);
|
||||
|
||||
static void gst_ffmpegcsp_base_init (gpointer g_class);
|
||||
static void gst_ffmpegcsp_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_ffmpegcsp_init (GTypeInstance *instance, gpointer g_class);
|
||||
static void gst_ffmpegcsp_base_init (GstFFMpegCspClass *klass);
|
||||
static void gst_ffmpegcsp_class_init (GstFFMpegCspClass *klass);
|
||||
static void gst_ffmpegcsp_init (GstFFMpegCsp *space);
|
||||
|
||||
static void gst_ffmpegcsp_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gst_ffmpegcsp_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_connect (GstPad *pad,
|
||||
gst_ffmpegcsp_sinkconnect (GstPad *pad,
|
||||
const GstCaps *caps);
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_try_connect (GstPad *pad,
|
||||
AVCodecContext *ctx,
|
||||
double fps);
|
||||
gst_ffmpegcsp_srcconnect (GstPad *pad,
|
||||
const GstCaps *caps);
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_srcconnect_func (GstPad *pad,
|
||||
const GstCaps *caps,
|
||||
gboolean newcaps);
|
||||
|
||||
static void gst_ffmpegcsp_chain (GstPad *pad,
|
||||
GstData *data);
|
||||
static GstElementStateReturn
|
||||
gst_ffmpegcsp_change_state (GstElement *element);
|
||||
|
||||
static GstPadTemplate *srctempl, *sinktempl;
|
||||
static GstElementClass *parent_class = NULL;
|
||||
/*static guint gst_ffmpegcsp_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
/* does caps nego on a pad */
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_try_connect (GstPad *pad, AVCodecContext *ctx, double fps)
|
||||
static GstCaps *
|
||||
gst_ffmpegcsp_getcaps (GstPad *pad)
|
||||
{
|
||||
gint i, ret;
|
||||
GstFFMpegCsp *space;
|
||||
gboolean try_all = (ctx->pix_fmt != PIX_FMT_NB);
|
||||
GstCaps *caps;
|
||||
GstCaps *peercaps;
|
||||
GstCaps *ourcaps;
|
||||
|
||||
space = GST_FFMPEG_CSP (gst_pad_get_parent (pad));
|
||||
space = GST_FFMPEGCSP (gst_pad_get_parent (pad));
|
||||
|
||||
/* we can do everything our peer can... */
|
||||
peercaps = gst_caps_copy (gst_pad_get_allowed_caps (space->srcpad));
|
||||
|
||||
/* and our own template of course */
|
||||
ourcaps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
|
||||
/* merge them together, we prefer the peercaps first */
|
||||
gst_caps_append (peercaps, ourcaps);
|
||||
|
||||
return peercaps;
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_srcconnect_func (GstPad *pad,
|
||||
const GstCaps *caps,
|
||||
gboolean newcaps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
guint n;
|
||||
AVCodecContext *ctx;
|
||||
GstFFMpegCsp *space;
|
||||
GstCaps *peercaps, *ourcaps, *one;
|
||||
|
||||
space = GST_FFMPEGCSP (gst_pad_get_parent (pad));
|
||||
|
||||
/* we cannot operate if we didn't get src caps */
|
||||
if (!(ourcaps = space->sinkcaps)) {
|
||||
#if 0
|
||||
if (!newcaps) {
|
||||
gst_pad_recalc_allowed_caps (pad);
|
||||
}
|
||||
#endif
|
||||
return GST_PAD_LINK_DELAYED;
|
||||
}
|
||||
|
||||
/* then see what the peer has that matches the size */
|
||||
caps = gst_caps_intersect (caps,
|
||||
gst_caps_new_full (
|
||||
gst_structure_new (
|
||||
"video/x-raw-yuv",
|
||||
"width", G_TYPE_INT, space->width,
|
||||
"height", G_TYPE_INT, space->height,
|
||||
"framerate", G_TYPE_DOUBLE, space->fps, NULL
|
||||
), gst_structure_new (
|
||||
"video/x-raw-rgb",
|
||||
"width", G_TYPE_INT, space->width,
|
||||
"height", G_TYPE_INT, space->height,
|
||||
"framerate", G_TYPE_DOUBLE, space->fps, NULL
|
||||
), NULL));
|
||||
|
||||
/* first see if we can do the format natively by filtering the peer caps
|
||||
* with our incomming caps */
|
||||
if ((peercaps = gst_caps_intersect (caps, ourcaps)) != NULL) {
|
||||
for (n = 0; n < gst_caps_get_size (peercaps); n++) {
|
||||
structure = gst_caps_get_structure (peercaps, n);
|
||||
one = gst_caps_new_full (gst_structure_copy (structure), NULL);
|
||||
|
||||
/* see if the peer likes it too, it should as the caps say so.. */
|
||||
if (gst_pad_try_set_caps (space->srcpad, one) > 0) {
|
||||
space->from_pixfmt = space->to_pixfmt = -1;
|
||||
return GST_PAD_LINK_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* loop over all possibilities and select the first one we can convert and
|
||||
* is accepted by the peer */
|
||||
caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, ctx);
|
||||
for (i = 0; i < gst_caps_get_size (caps); i++) {
|
||||
GstStructure *structure = gst_caps_get_structure (caps, i);
|
||||
GstCaps *setcaps;
|
||||
|
||||
if (fps > 0)
|
||||
gst_structure_set (structure, "framerate", G_TYPE_DOUBLE, fps, NULL);
|
||||
|
||||
setcaps = gst_caps_new_full (gst_structure_copy (structure), NULL);
|
||||
|
||||
ret = gst_pad_try_set_caps (pad, setcaps);
|
||||
gst_caps_free (setcaps);
|
||||
if (ret >= 0) {
|
||||
if (ctx->pix_fmt == PIX_FMT_NB)
|
||||
gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, caps, ctx);
|
||||
gst_caps_free (caps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (try_all) {
|
||||
ctx = avcodec_alloc_context ();
|
||||
for (n = 0; n < gst_caps_get_size (caps); n++) {
|
||||
structure = gst_caps_get_structure (caps, n);
|
||||
one = gst_caps_new_full (gst_structure_copy (structure), NULL);
|
||||
ctx->width = space->width;
|
||||
ctx->height = space->height;
|
||||
ctx->pix_fmt = PIX_FMT_NB;
|
||||
return gst_ffmpegcsp_try_connect (pad, ctx, fps);
|
||||
} else {
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, one, ctx);
|
||||
if (ctx->pix_fmt != PIX_FMT_NB) {
|
||||
if (gst_pad_try_set_caps (space->srcpad, one) > 0) {
|
||||
space->to_pixfmt = ctx->pix_fmt;
|
||||
av_free (ctx);
|
||||
if (space->from_frame)
|
||||
av_free (space->from_frame);
|
||||
if (space->to_frame)
|
||||
av_free (space->to_frame);
|
||||
space->from_frame = avcodec_alloc_frame ();
|
||||
space->to_frame = avcodec_alloc_frame ();
|
||||
return GST_PAD_LINK_DONE;
|
||||
}
|
||||
gst_caps_free (one);
|
||||
}
|
||||
}
|
||||
av_free (ctx);
|
||||
|
||||
/* we disable ourself here */
|
||||
space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
|
||||
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_connect (GstPad *pad, const GstCaps *caps)
|
||||
gst_ffmpegcsp_sinkconnect (GstPad *pad,
|
||||
const GstCaps *caps)
|
||||
{
|
||||
AVCodecContext *ctx;
|
||||
GstFFMpegCsp *space;
|
||||
gdouble fps;
|
||||
enum PixelFormat pixfmt;
|
||||
GstPad *other;
|
||||
enum PixelFormat *format, *other_format;
|
||||
GstPad *peer;
|
||||
|
||||
space = GST_FFMPEG_CSP (gst_pad_get_parent (pad));
|
||||
space = GST_FFMPEGCSP (gst_pad_get_parent (pad));
|
||||
|
||||
if (space->sinkpad == pad) {
|
||||
other = space->srcpad;
|
||||
format = &space->from_pixfmt;
|
||||
other_format = &space->to_pixfmt;
|
||||
} else if (space->srcpad == pad) {
|
||||
other = space->sinkpad;
|
||||
format = &space->to_pixfmt;
|
||||
other_format = &space->from_pixfmt;
|
||||
} else {
|
||||
g_assert_not_reached ();
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
if (!gst_caps_is_fixed (caps)) {
|
||||
return GST_PAD_LINK_DELAYED;
|
||||
}
|
||||
|
||||
ctx = avcodec_alloc_context ();
|
||||
ctx->width = 0;
|
||||
ctx->height = 0;
|
||||
|
@ -184,39 +247,42 @@ gst_ffmpegcsp_connect (GstPad *pad, const GstCaps *caps)
|
|||
|
||||
gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, caps, ctx);
|
||||
if (!ctx->width || !ctx->height || ctx->pix_fmt == PIX_FMT_NB) {
|
||||
av_free (ctx);
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
}
|
||||
|
||||
if (!gst_structure_get_double (gst_caps_get_structure (caps, 0),
|
||||
"framerate", &fps))
|
||||
fps = 0;
|
||||
|
||||
pixfmt = ctx->pix_fmt;
|
||||
if (*other_format == PIX_FMT_NB ||
|
||||
space->width != ctx->width ||
|
||||
space->height != ctx->height ||
|
||||
space->fps != fps) {
|
||||
GST_DEBUG_OBJECT (space, "Need caps nego on pad %s for size %dx%d",
|
||||
GST_PAD_NAME (other), ctx->width, ctx->height);
|
||||
/* ctx->pix_fmt is set to preferred format */
|
||||
if (gst_ffmpegcsp_try_connect (space->sinkpad, ctx, fps) <= 0) {
|
||||
av_free (ctx);
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
}
|
||||
*other_format = ctx->pix_fmt;
|
||||
}
|
||||
space->fps = 1. * ctx->frame_rate / ctx->frame_rate_base;
|
||||
space->width = ctx->width;
|
||||
space->height = ctx->height;
|
||||
space->fps = fps;
|
||||
*format = pixfmt;
|
||||
space->from_pixfmt = ctx->pix_fmt;
|
||||
av_free (ctx);
|
||||
|
||||
GST_INFO ( "size: %dx%d", space->width, space->height);
|
||||
|
||||
space->sinkcaps = (GstCaps *) caps;
|
||||
|
||||
if ((peer = gst_pad_get_peer (pad)) != NULL) {
|
||||
GstPadLinkReturn ret;
|
||||
ret = gst_ffmpegcsp_srcconnect_func (pad,
|
||||
gst_pad_get_caps (GST_PAD_PEER (space->srcpad)),
|
||||
FALSE);
|
||||
if (ret <= 0) {
|
||||
space->sinkcaps = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return GST_PAD_LINK_DONE;
|
||||
}
|
||||
|
||||
return GST_PAD_LINK_OK;
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_ffmpegcsp_srcconnect (GstPad *pad,
|
||||
const GstCaps *caps)
|
||||
{
|
||||
return gst_ffmpegcsp_srcconnect_func (pad, caps, TRUE);
|
||||
}
|
||||
|
||||
static GType
|
||||
gst_ffmpegcsp_get_type (void)
|
||||
{
|
||||
|
@ -225,78 +291,63 @@ gst_ffmpegcsp_get_type (void)
|
|||
if (!ffmpegcsp_type) {
|
||||
static const GTypeInfo ffmpegcsp_info = {
|
||||
sizeof (GstFFMpegCspClass),
|
||||
gst_ffmpegcsp_base_init,
|
||||
(GBaseInitFunc) gst_ffmpegcsp_base_init,
|
||||
NULL,
|
||||
gst_ffmpegcsp_class_init,
|
||||
(GClassInitFunc) gst_ffmpegcsp_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstFFMpegCsp),
|
||||
0,
|
||||
gst_ffmpegcsp_init,
|
||||
(GInstanceInitFunc) gst_ffmpegcsp_init,
|
||||
};
|
||||
|
||||
ffmpegcsp_type = g_type_register_static (GST_TYPE_ELEMENT,
|
||||
"GstFFMpegColorspace",
|
||||
&ffmpegcsp_info, 0);
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (debug_ffmpeg_csp, "ffcolorspace", 0, "FFMpeg colorspace converter");
|
||||
}
|
||||
|
||||
return ffmpegcsp_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ffmpegcsp_base_init (gpointer g_class)
|
||||
gst_ffmpegcsp_base_init (GstFFMpegCspClass *klass)
|
||||
{
|
||||
GstCaps *caps, *capscopy;
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
/* template caps */
|
||||
caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, NULL);
|
||||
capscopy = gst_caps_copy (caps);
|
||||
|
||||
/* build templates */
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
caps));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
capscopy));
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class, srctempl);
|
||||
gst_element_class_add_pad_template (element_class, sinktempl);
|
||||
gst_element_class_set_details (element_class, &ffmpegcsp_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ffmpegcsp_class_init (gpointer g_class, gpointer class_data)
|
||||
gst_ffmpegcsp_class_init (GstFFMpegCspClass *klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (g_class);
|
||||
gobject_class = (GObjectClass*) klass;
|
||||
gstelement_class = (GstElementClass*) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_ffmpegcsp_set_property;
|
||||
gobject_class->get_property = gst_ffmpegcsp_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_ffmpegcsp_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ffmpegcsp_init (GTypeInstance *instance, gpointer g_class)
|
||||
gst_ffmpegcsp_init (GstFFMpegCsp *space)
|
||||
{
|
||||
GstFFMpegCsp *space = GST_FFMPEG_CSP (instance);
|
||||
|
||||
space->sinkpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (space), "sink"),
|
||||
"sink");
|
||||
gst_pad_set_link_function (space->sinkpad, gst_ffmpegcsp_connect);
|
||||
space->sinkpad = gst_pad_new_from_template (sinktempl, "sink");
|
||||
gst_pad_set_link_function (space->sinkpad, gst_ffmpegcsp_sinkconnect);
|
||||
gst_pad_set_getcaps_function (space->sinkpad, gst_ffmpegcsp_getcaps);
|
||||
gst_pad_set_chain_function (space->sinkpad,gst_ffmpegcsp_chain);
|
||||
gst_element_add_pad (GST_ELEMENT(space), space->sinkpad);
|
||||
|
||||
space->srcpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (space), "src"),
|
||||
"src");
|
||||
space->srcpad = gst_pad_new_from_template (srctempl, "src");
|
||||
gst_element_add_pad (GST_ELEMENT (space), space->srcpad);
|
||||
gst_pad_set_link_function (space->srcpad, gst_ffmpegcsp_connect);
|
||||
gst_pad_set_link_function (space->srcpad, gst_ffmpegcsp_srcconnect);
|
||||
|
||||
space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
|
||||
space->from_frame = space->to_frame = NULL;
|
||||
|
@ -306,18 +357,18 @@ static void
|
|||
gst_ffmpegcsp_chain (GstPad *pad,
|
||||
GstData *data)
|
||||
{
|
||||
GstFFMpegCsp *space;
|
||||
GstBuffer *inbuf = GST_BUFFER (data);
|
||||
GstFFMpegCsp *space;
|
||||
GstBuffer *outbuf = NULL;
|
||||
|
||||
g_return_if_fail (pad != NULL);
|
||||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
g_return_if_fail (inbuf != NULL);
|
||||
|
||||
space = GST_FFMPEG_CSP (gst_pad_get_parent (pad));
|
||||
space = GST_FFMPEGCSP (gst_pad_get_parent (pad));
|
||||
|
||||
g_return_if_fail (space != NULL);
|
||||
g_return_if_fail (GST_IS_FFMPEG_CSP (space));
|
||||
g_return_if_fail (GST_IS_FFMPEGCSP (space));
|
||||
|
||||
if (space->from_pixfmt == PIX_FMT_NB ||
|
||||
space->to_pixfmt == PIX_FMT_NB) {
|
||||
|
@ -328,10 +379,10 @@ gst_ffmpegcsp_chain (GstPad *pad,
|
|||
if (space->from_pixfmt == space->to_pixfmt) {
|
||||
outbuf = inbuf;
|
||||
} else {
|
||||
/* use bufferpool here */
|
||||
guint size = avpicture_get_size (space->to_pixfmt,
|
||||
space->width,
|
||||
space->height);
|
||||
/* use bufferpools here */
|
||||
outbuf = gst_buffer_new_and_alloc (size);
|
||||
|
||||
/* convert */
|
||||
|
@ -343,7 +394,8 @@ gst_ffmpegcsp_chain (GstPad *pad,
|
|||
(AVPicture *) space->from_frame, space->from_pixfmt,
|
||||
space->width, space->height);
|
||||
|
||||
gst_buffer_stamp (outbuf, inbuf);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
|
||||
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
|
||||
|
||||
gst_buffer_unref (inbuf);
|
||||
}
|
||||
|
@ -356,12 +408,9 @@ gst_ffmpegcsp_change_state (GstElement *element)
|
|||
{
|
||||
GstFFMpegCsp *space;
|
||||
|
||||
space = GST_FFMPEG_CSP (element);
|
||||
space = GST_FFMPEGCSP (element);
|
||||
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_READY_TO_PAUSED:
|
||||
space->need_caps_nego = TRUE;
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
if (space->from_frame)
|
||||
av_free (space->from_frame);
|
||||
|
@ -378,9 +427,61 @@ gst_ffmpegcsp_change_state (GstElement *element)
|
|||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ffmpegcsp_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GstFFMpegCsp *space;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_FFMPEGCSP (object));
|
||||
space = GST_FFMPEGCSP (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_ffmpegcsp_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GstFFMpegCsp *space;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_FFMPEGCSP (object));
|
||||
space = GST_FFMPEGCSP (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_ffmpegcsp_register (GstPlugin *plugin)
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
/* template caps */
|
||||
caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, NULL);
|
||||
|
||||
/* build templates */
|
||||
srctempl = gst_pad_template_new ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
gst_caps_copy (caps));
|
||||
sinktempl = gst_pad_template_new ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
caps);
|
||||
|
||||
return gst_element_register (plugin, "ffcolorspace",
|
||||
GST_RANK_NONE, GST_TYPE_FFMPEG_CSP);
|
||||
GST_RANK_NONE, GST_TYPE_FFMPEGCSP);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue