summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-06-21 18:27:46 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-06-21 18:27:46 +0000
commitc2319d8fa1d1e0c16094bd1ee402e0639b3f2399 (patch)
treee5911bd9188d9fa149cb0a120d0cf9e72c25830a
parentad2e7cd89cd5f10d1de6ce06d45e3ce3193663d3 (diff)
Added YV12 output format
Original commit message from CVS: Added YV12 output format
-rw-r--r--ext/mpeg2dec/gstmpeg2deccvs.c80
-rw-r--r--ext/mpeg2dec/gstmpeg2deccvs.h40
2 files changed, 92 insertions, 28 deletions
diff --git a/ext/mpeg2dec/gstmpeg2deccvs.c b/ext/mpeg2dec/gstmpeg2deccvs.c
index 47947d29..82be51bd 100644
--- a/ext/mpeg2dec/gstmpeg2deccvs.c
+++ b/ext/mpeg2dec/gstmpeg2deccvs.c
@@ -23,7 +23,7 @@
#include <mpeg2dec/mm_accel.h>
#include <mpeg2dec/video_out.h>
-#include "gstmpeg2dec.h"
+#include "gstmpeg2deccvs.h"
/* elementfactory information */
static GstElementDetails gst_mpeg2dec_details = {
@@ -54,6 +54,13 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory,
GST_CAPS_NEW (
"mpeg2dec_src",
"video/raw",
+ "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','V','1','2')),
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096)
+ ),
+ GST_CAPS_NEW (
+ "mpeg2dec_src",
+ "video/raw",
"format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')),
"width", GST_PROPS_INT_RANGE (16, 4096),
"height", GST_PROPS_INT_RANGE (16, 4096)
@@ -196,8 +203,14 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec *mpeg2dec, mpeg2_info_t *info)
out = GST_BUFFER_DATA (outbuf);
buf[0] = out;
- buf[1] = buf[0] + size;
- buf[2] = buf[1] + size/4;
+ if (mpeg2dec->format == MPEG2DEC_FORMAT_I420) {
+ buf[1] = buf[0] + size;
+ buf[2] = buf[1] + size/4;
+ }
+ else {
+ buf[2] = buf[0] + size;
+ buf[1] = buf[2] + size/4;
+ }
gst_buffer_ref (outbuf);
mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf);
@@ -210,6 +223,53 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec *mpeg2dec, mpeg2_info_t *info)
return TRUE;
}
+static gboolean
+gst_mpeg2dec_negotiate_format (GstMpeg2dec *mpeg2dec)
+{
+ GstCaps *allowed;
+ GstCaps *trylist;
+
+ /* we what we are allowed to do */
+ allowed = gst_pad_get_allowed_caps (mpeg2dec->srcpad);
+
+ /* try to fix our height */
+ trylist = gst_caps_intersect (allowed,
+ GST_CAPS_NEW (
+ "mpeg2dec_negotiate",
+ "video/raw",
+ "width", GST_PROPS_INT (mpeg2dec->width),
+ "height", GST_PROPS_INT (mpeg2dec->height)
+ ));
+ /* prepare for looping */
+ trylist = gst_caps_normalize (trylist);
+
+ while (trylist) {
+ GstCaps *to_try = gst_caps_copy_1 (trylist);
+
+ /* try each format */
+ if (gst_pad_try_set_caps (mpeg2dec->srcpad, to_try)) {
+ guint32 fourcc;
+
+ /* it worked, try to find what it was again */
+ gst_caps_get_fourcc_int (to_try, "format", &fourcc);
+
+ if (fourcc == GST_STR_FOURCC ("I420")) {
+ mpeg2dec->format = MPEG2DEC_FORMAT_I420;
+ }
+ else {
+ mpeg2dec->format = MPEG2DEC_FORMAT_YV12;
+ }
+ break;
+ }
+ trylist = trylist->next;
+ }
+ /* oops list exhausted an nothing was found... */
+ if (!trylist) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
static void
gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
{
@@ -270,14 +330,10 @@ gst_mpeg2dec_chain (GstPad *pad, GstBuffer *buf)
mpeg2dec->height = info->sequence->height;
mpeg2dec->total_frames = 0;
- gst_pad_try_set_caps (mpeg2dec->srcpad,
- GST_CAPS_NEW (
- "mpeg2dec_caps",
- "video/raw",
- "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')),
- "width", GST_PROPS_INT (mpeg2dec->width),
- "height", GST_PROPS_INT (mpeg2dec->height)
- ));
+ if (!gst_mpeg2dec_negotiate_format (mpeg2dec)) {
+ gst_element_error (GST_ELEMENT (mpeg2dec), "could not negotiate format");
+ return;
+ }
gst_mpeg2dec_alloc_buffer (mpeg2dec, info);
break;
@@ -605,7 +661,7 @@ gst_mpeg2dec_change_state (GstElement *element)
mpeg2dec->closed = FALSE;
/* reset the initial video state */
- mpeg2dec->format = -1;
+ mpeg2dec->format = MPEG2DEC_FORMAT_NONE;
mpeg2dec->width = -1;
mpeg2dec->height = -1;
mpeg2dec->first = TRUE;
diff --git a/ext/mpeg2dec/gstmpeg2deccvs.h b/ext/mpeg2dec/gstmpeg2deccvs.h
index 609cc133..d93f9a7e 100644
--- a/ext/mpeg2dec/gstmpeg2deccvs.h
+++ b/ext/mpeg2dec/gstmpeg2deccvs.h
@@ -46,31 +46,39 @@ extern "C" {
typedef struct _GstMpeg2dec GstMpeg2dec;
typedef struct _GstMpeg2decClass GstMpeg2decClass;
+typedef enum
+{
+ MPEG2DEC_FORMAT_NONE,
+ MPEG2DEC_FORMAT_I420,
+ MPEG2DEC_FORMAT_YV12,
+} Mpeg2decFormat;
+
struct _GstMpeg2dec {
- GstElement element;
+ GstElement element;
/* pads */
- GstPad *sinkpad,*srcpad;
+ GstPad *sinkpad,
+ *srcpad;
GstBufferPool *peerpool;
- mpeg2dec_t *decoder;
- guint32 accel;
- gboolean closed;
+ mpeg2dec_t *decoder;
+ guint32 accel;
+ gboolean closed;
/* the timestamp of the next frame */
- gboolean first;
- gboolean discont_pending;
- gint64 next_time;
- gint64 last_PTS;
- gint frames_per_PTS;
- gint adjust;
+ gboolean first;
+ gboolean discont_pending;
+ gint64 next_time;
+ gint64 last_PTS;
+ gint frames_per_PTS;
+ gint adjust;
/* video state */
- gint format;
- gint width;
- gint height;
- gint frame_rate_code;
- gint64 total_frames;
+ Mpeg2decFormat format;
+ gint width;
+ gint height;
+ gint frame_rate_code;
+ gint64 total_frames;
};
struct _GstMpeg2decClass {