summaryrefslogtreecommitdiff
path: root/ext/divx
diff options
context:
space:
mode:
Diffstat (limited to 'ext/divx')
-rw-r--r--ext/divx/gstdivxdec.c135
-rw-r--r--ext/divx/gstdivxdec.h1
-rw-r--r--ext/divx/gstdivxenc.c97
-rw-r--r--ext/divx/gstdivxenc.h1
4 files changed, 143 insertions, 91 deletions
diff --git a/ext/divx/gstdivxdec.c b/ext/divx/gstdivxdec.c
index 0ee308b81..011836f9b 100644
--- a/ext/divx/gstdivxdec.c
+++ b/ext/divx/gstdivxdec.c
@@ -43,28 +43,42 @@ GST_PAD_TEMPLATE_FACTORY(sink_template,
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_CAPS_NEW("divxdec_sink",
- "video/divx",
- NULL)
+ GST_CAPS_NEW(
+ "divxdec_sink",
+ "video/x-divx",
+ "divxversion", GST_PROPS_INT_RANGE(3, 5),
+ "width", GST_PROPS_INT_RANGE(0, G_MAXINT),
+ "height", GST_PROPS_INT_RANGE(0, G_MAXINT),
+ "framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT)
+ )
)
GST_PAD_TEMPLATE_FACTORY(src_template,
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_CAPS_NEW("divxdec_src",
- "video/raw",
- "format", GST_PROPS_LIST(
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','Y','U','V')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y'))
- ),
- "width", GST_PROPS_INT_RANGE(0, G_MAXINT),
- "height", GST_PROPS_INT_RANGE(0, G_MAXINT),
- NULL)
+ gst_caps_new(
+ "divxdec_src",
+ "video/x-raw-yuv",
+ GST_VIDEO_YUV_PAD_TEMPLATE_PROPS(
+ GST_PROPS_LIST(
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y'))
+ )
+ )
+ ),
+ gst_caps_new(
+ "divxdec_src_rgb1",
+ "video/x-raw-rgb",
+ GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32
+ ),
+ gst_caps_new(
+ "divxdec_src_rgb2",
+ "video/x-raw-rgb",
+ GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16
+ )
)
@@ -87,6 +101,7 @@ static void gst_divxdec_chain (GstPad *pad,
GstBuffer *buf);
static GstPadLinkReturn gst_divxdec_connect (GstPad *pad,
GstCaps *vscapslist);
+static GstPadLinkReturn gst_divxdec_negotiate (GstDivxDec *divxdec);
static GstElementClass *parent_class = NULL;
/* static guint gst_divxdec_signals[LAST_SIGNAL] = { 0 }; */
@@ -261,10 +276,12 @@ gst_divxdec_chain (GstPad *pad,
divxdec = GST_DIVXDEC(GST_OBJECT_PARENT(pad));
if (!divxdec->handle) {
- gst_element_error(GST_ELEMENT(divxdec),
- "No format set - aborting");
- gst_buffer_unref(buf);
- return;
+ if (gst_divxdec_negotiate(divxdec) <= 0) {
+ gst_element_error(GST_ELEMENT(divxdec),
+ "No format set - aborting");
+ gst_buffer_unref(buf);
+ return;
+ }
}
outbuf = gst_buffer_new_and_alloc(divxdec->width *
@@ -297,10 +314,9 @@ gst_divxdec_chain (GstPad *pad,
static GstPadLinkReturn
-gst_divxdec_connect (GstPad *pad,
- GstCaps *vscaps)
+gst_divxdec_negotiate (GstDivxDec *divxdec)
{
- GstDivxDec *divxdec;
+ GstPadLinkReturn ret;
GstCaps *caps;
struct {
guint32 fourcc;
@@ -314,8 +330,6 @@ gst_divxdec_connect (GstPad *pad,
GST_MAKE_FOURCC('U','Y','V','Y'), 0 },
{ GST_MAKE_FOURCC('I','4','2','0'), 12, 12,
GST_MAKE_FOURCC('I','4','2','0'), 0 },
- { GST_MAKE_FOURCC('I','Y','U','V'), 12, 12,
- GST_MAKE_FOURCC('I','4','2','0'), 0 },
{ GST_MAKE_FOURCC('Y','V','1','2'), 12, 12,
GST_MAKE_FOURCC('Y','V','1','2'), 0 },
{ GST_MAKE_FOURCC('R','G','B',' '), 32, 32,
@@ -338,69 +352,59 @@ gst_divxdec_connect (GstPad *pad,
};
gint i;
- divxdec = GST_DIVXDEC(gst_pad_get_parent (pad));
-
- /* if there's something old around, remove it */
- if (divxdec->handle) {
- gst_divxdec_unset(divxdec);
- }
-
- /* we are not going to act on variable caps */
- if (!GST_CAPS_IS_FIXED(vscaps))
- return GST_PAD_LINK_DELAYED;
-
- /* if we get here, we know the input is divx. we
- * only need to bother with the output colorspace */
- gst_caps_get_int(vscaps, "width", &divxdec->width);
- gst_caps_get_int(vscaps, "height", &divxdec->height);
-
for (i = 0; fmt_list[i].fourcc != 0; i++) {
divxdec->csp = fmt_list[i].csp;
/* try making a caps to set on the other side */
if (fmt_list[i].fourcc == GST_MAKE_FOURCC('R','G','B',' ')) {
guint32 r_mask = 0, b_mask = 0, g_mask = 0;
+ gint endianness = 0;
switch (fmt_list[i].depth) {
case 15:
+ endianness = G_BYTE_ORDER;
r_mask = 0xf800; g_mask = 0x07c0; b_mask = 0x003e;
break;
case 16:
+ endianness = G_BYTE_ORDER;
r_mask = 0xf800; g_mask = 0x07e0; b_mask = 0x001f;
break;
case 24:
- r_mask = 0xff0000; g_mask = 0x00ff00; b_mask = 0x0000ff;
+ endianness = G_BIG_ENDIAN;
+ r_mask = R_MASK_24; g_mask = G_MASK_24; b_mask = B_MASK_24;
break;
case 32:
- r_mask = 0xff000000; g_mask = 0x00ff0000; b_mask = 0x0000ff00;
+ endianness = G_BIG_ENDIAN;
+ r_mask = R_MASK_32; g_mask = G_MASK_32; b_mask = B_MASK_32;
break;
}
caps = GST_CAPS_NEW("divxdec_src_pad_rgb",
- "video/raw",
+ "video/x-raw-rgb",
"width", GST_PROPS_INT(divxdec->width),
"height", GST_PROPS_INT(divxdec->height),
- "format", GST_PROPS_FOURCC(fmt_list[i].fourcc),
+ "framerate", GST_PROPS_FLOAT(divxdec->fps),
"depth", GST_PROPS_INT(fmt_list[i].depth),
"bpp", GST_PROPS_INT(fmt_list[i].bpp),
- "endianness", GST_PROPS_INT(G_BYTE_ORDER),
+ "endianness", GST_PROPS_INT(endianness),
"red_mask", GST_PROPS_INT(r_mask),
"green_mask", GST_PROPS_INT(g_mask),
- "blue_mask", GST_PROPS_INT(b_mask),
- NULL);
+ "blue_mask", GST_PROPS_INT(b_mask));
} else {
caps = GST_CAPS_NEW("divxdec_src_pad_yuv",
- "video/raw",
+ "video/x-raw-yuv",
"width", GST_PROPS_INT(divxdec->width),
"height", GST_PROPS_INT(divxdec->height),
- "format", GST_PROPS_FOURCC(fmt_list[i].fourcc),
- NULL);
+ "framerate", GST_PROPS_FLOAT(divxdec->fps),
+ "format", GST_PROPS_FOURCC(fmt_list[i].fourcc));
}
- if (gst_pad_try_set_caps(divxdec->srcpad, caps) > 0) {
+ if ((ret = gst_pad_try_set_caps(divxdec->srcpad, caps)) > 0) {
divxdec->csp = fmt_list[i].csp;
divxdec->bpp = fmt_list[i].bpp;
divxdec->bitcnt = fmt_list[i].bitcnt;
if (gst_divxdec_setup(divxdec))
return GST_PAD_LINK_OK;
+ } else if (ret == GST_PAD_LINK_DELAYED) {
+ return ret; /* trying more is useless */
}
}
@@ -409,6 +413,33 @@ gst_divxdec_connect (GstPad *pad,
}
+static GstPadLinkReturn
+gst_divxdec_connect (GstPad *pad,
+ GstCaps *vscaps)
+{
+ GstDivxDec *divxdec;
+
+ divxdec = GST_DIVXDEC(gst_pad_get_parent (pad));
+
+ /* if there's something old around, remove it */
+ if (divxdec->handle) {
+ gst_divxdec_unset(divxdec);
+ }
+
+ /* we are not going to act on variable caps */
+ if (!GST_CAPS_IS_FIXED(vscaps))
+ return GST_PAD_LINK_DELAYED;
+
+ /* if we get here, we know the input is divx. we
+ * only need to bother with the output colorspace */
+ gst_caps_get_int(vscaps, "width", &divxdec->width);
+ gst_caps_get_int(vscaps, "height", &divxdec->height);
+ gst_caps_get_float(vscaps, "framerate", &divxdec->fps);
+
+ return gst_divxdec_negotiate(divxdec);
+}
+
+
static gboolean
plugin_init (GModule *module,
GstPlugin *plugin)
diff --git a/ext/divx/gstdivxdec.h b/ext/divx/gstdivxdec.h
index 35876bdb8..9f1da3ffe 100644
--- a/ext/divx/gstdivxdec.h
+++ b/ext/divx/gstdivxdec.h
@@ -55,6 +55,7 @@ struct _GstDivxDec {
guint32 csp;
int bitcnt, bpp;
int width, height;
+ float fps;
};
struct _GstDivxDecClass {
diff --git a/ext/divx/gstdivxenc.c b/ext/divx/gstdivxenc.c
index 24a266846..bd7547a14 100644
--- a/ext/divx/gstdivxenc.c
+++ b/ext/divx/gstdivxenc.c
@@ -44,28 +44,43 @@ GST_PAD_TEMPLATE_FACTORY(sink_template,
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_CAPS_NEW("divxenc_sink",
- "video/raw",
- "format", GST_PROPS_LIST(
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','Y','U','V')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')),
- GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y'))
- ),
- "width", GST_PROPS_INT_RANGE(0, G_MAXINT),
- "height", GST_PROPS_INT_RANGE(0, G_MAXINT),
- NULL)
+ gst_caps_new(
+ "divxdec_src",
+ "video/x-raw-yuv",
+ GST_VIDEO_YUV_PAD_TEMPLATE_PROPS(
+ GST_PROPS_LIST(
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')),
+ GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y'))
+ )
+ )
+ ),
+ gst_caps_new(
+ "divxdec_src_rgb1",
+ "video/x-raw-rgb",
+ GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32
+ ),
+ gst_caps_new(
+ "divxdec_src_rgb2",
+ "video/x-raw-rgb",
+ GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16
+ )
)
GST_PAD_TEMPLATE_FACTORY(src_template,
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_CAPS_NEW("divxenc_src",
- "video/divx",
- NULL)
+ GST_CAPS_NEW(
+ "divxenc_sink",
+ "video/x-divx",
+ "divxversion", GST_PROPS_INT(5),
+ "width", GST_PROPS_INT_RANGE(0, G_MAXINT),
+ "height", GST_PROPS_INT_RANGE(0, G_MAXINT),
+ "framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT)
+ )
)
@@ -246,11 +261,8 @@ gst_divxenc_setup (GstDivxEnc *divxenc)
void *handle = NULL;
SETTINGS output;
DivXBitmapInfoHeader input;
- gdouble fps;
int ret;
- fps = gst_video_frame_rate(GST_PAD_PEER(divxenc->sinkpad));
-
/* set it up */
memset(&input, 0, sizeof(DivXBitmapInfoHeader));
input.biSize = sizeof(DivXBitmapInfoHeader);
@@ -266,9 +278,9 @@ gst_divxenc_setup (GstDivxEnc *divxenc)
output.use_bidirect = 0;
output.input_clock = 0;
output.input_frame_period = 1000000;
- output.internal_timescale = fps * 1000000;
+ output.internal_timescale = divxenc->fps * 1000000;
output.max_key_interval = (divxenc->max_key_interval == -1) ?
- (2 * fps) :
+ (2 * divxenc->fps) :
divxenc->max_key_interval;
output.key_frame_threshold = 0;
output.vbv_bitrate = 0;
@@ -340,13 +352,6 @@ gst_divxenc_chain (GstPad *pad,
divxenc = GST_DIVXENC(GST_OBJECT_PARENT(pad));
- if (!divxenc->handle) {
- if (!gst_divxenc_setup(divxenc)) {
- gst_buffer_unref(buf);
- return;
- }
- }
-
outbuf = gst_buffer_new_and_alloc(divxenc->buffer_size);
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf);
@@ -397,21 +402,21 @@ gst_divxenc_connect (GstPad *pad,
return GST_PAD_LINK_DELAYED;
for (caps = vscaps; caps != NULL; caps = caps->next) {
- int w,h,d;
+ gint w,h,d;
+ gfloat fps;
guint32 fourcc;
guint32 divx_cs;
gint bitcnt = 0;
gst_caps_get_int(caps, "width", &w);
gst_caps_get_int(caps, "height", &h);
+ gst_caps_get_float(caps, "framerate", &fps);
gst_caps_get_fourcc_int(caps, "format", &fourcc);
switch (fourcc) {
case GST_MAKE_FOURCC('I','4','2','0'):
- case GST_MAKE_FOURCC('I','Y','U','V'):
divx_cs = GST_MAKE_FOURCC('I','4','2','0');
break;
case GST_MAKE_FOURCC('Y','U','Y','2'):
- case GST_MAKE_FOURCC('Y','U','Y','V'):
divx_cs = GST_MAKE_FOURCC('Y','U','Y','2');
break;
case GST_MAKE_FOURCC('Y','V','1','2'):
@@ -442,18 +447,32 @@ gst_divxenc_connect (GstPad *pad,
goto trynext;
}
- /* grmbl, we only know the peer pad *after*
- * linking, so we accept here, get the fps on
- * the first cycle and set it all up then */
divxenc->csp = divx_cs;
divxenc->bitcnt = bitcnt;
divxenc->width = w;
divxenc->height = h;
- return gst_pad_try_set_caps(divxenc->srcpad,
- GST_CAPS_NEW("divxenc_src_caps",
- "video/divx",
- "width", GST_PROPS_INT(w),
- "height", GST_PROPS_INT(h)));
+ divxenc->fps = fps;
+
+ /* try it */
+ if (gst_divxenc_setup(divxenc)) {
+ GstPadLinkReturn ret;
+ GstCaps *new_caps;
+
+ new_caps = GST_CAPS_NEW("divxenc_src_caps",
+ "video/x-divx",
+ "divxversion", GST_PROPS_INT(5),
+ "width", GST_PROPS_INT(w),
+ "height", GST_PROPS_INT(h),
+ "framerate", GST_PROPS_FLOAT(fps));
+
+ ret = gst_pad_try_set_caps(divxenc->srcpad, new_caps);
+
+ if (ret <= 0) {
+ gst_divxenc_unset(divxenc);
+ }
+
+ return ret;
+ }
trynext:
continue;
diff --git a/ext/divx/gstdivxenc.h b/ext/divx/gstdivxenc.h
index be1ddae5f..206659d32 100644
--- a/ext/divx/gstdivxenc.h
+++ b/ext/divx/gstdivxenc.h
@@ -64,6 +64,7 @@ struct _GstDivxEnc {
guint32 csp;
gint bitcnt;
gint width, height;
+ gfloat fps;
};
struct _GstDivxEncClass {