diff options
Diffstat (limited to 'ext/divx')
-rw-r--r-- | ext/divx/gstdivxdec.c | 135 | ||||
-rw-r--r-- | ext/divx/gstdivxdec.h | 1 | ||||
-rw-r--r-- | ext/divx/gstdivxenc.c | 97 | ||||
-rw-r--r-- | ext/divx/gstdivxenc.h | 1 |
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 { |