summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-01-29 15:47:18 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-01-29 15:47:18 +0000
commitaa4bcc482ba6128369d3b5140f19ca97c46fdc37 (patch)
tree4e4a5b09161f21dd0d836b0a3e3b8a042ea46be8 /gst
parentad740f4293c61839a31e1c9f0e85f5d3de633ef0 (diff)
gst/avi/gstavidemux.*: Invert DIB images. Fixes #132341.
Original commit message from CVS: * gst/avi/gstavidemux.c: (gst_avi_demux_add_stream), (swap_line), (gst_avi_demux_invert), (gst_avi_demux_process_next_entry), (gst_avi_demux_stream_data): * gst/avi/gstavidemux.h: Invert DIB images. Fixes #132341.
Diffstat (limited to 'gst')
-rw-r--r--gst/avi/gstavidemux.c44
-rw-r--r--gst/avi/gstavidemux.h1
2 files changed, 44 insertions, 1 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index c3f7a618..2fdd16bd 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -884,7 +884,7 @@ gst_avi_demux_add_stream (GstAviDemux * avi)
GstPadTemplate *templ = NULL;
GstPad *pad;
avi_stream_context *stream;
- gint blockalign = 0, bitrate = 0;
+ gint blockalign = 0, bitrate = 0, width = 0, height = 0;
guint64 *locations = NULL;
GstTagList *list = gst_tag_list_new ();
gboolean have_tag = FALSE;
@@ -1003,6 +1003,8 @@ gst_avi_demux_add_stream (GstAviDemux * avi)
have_tag = TRUE;
g_free (codec_name);
}
+ width = strf.vids->width;
+ height = strf.vids->height;
g_free (strf.vids);
avi->num_v_streams++;
break;
@@ -1076,6 +1078,8 @@ gst_avi_demux_add_stream (GstAviDemux * avi)
stream->skip = 0;
stream->blockalign = blockalign;
stream->bitrate = bitrate;
+ stream->width = width;
+ stream->height = height;
stream->indexes = locations;
gst_pad_set_element_private (pad, stream);
avi->num_streams++;
@@ -1984,6 +1988,37 @@ gst_avi_demux_handle_seek (GstAviDemux * avi)
return TRUE;
}
+/*
+ * Invert DIB buffers... Takes existing buffer and
+ * returns either the buffer or a new one (with old
+ * one dereferenced).
+ */
+
+static inline void
+swap_line (guint8 * d1, guint8 * d2, guint8 * tmp, gint bytes)
+{
+ memcpy (tmp, d1, bytes);
+ memcpy (d1, d2, bytes);
+ memcpy (d2, tmp, bytes);
+}
+
+static GstBuffer *
+gst_avi_demux_invert (avi_stream_context * stream, GstBuffer * buf)
+{
+ buf = gst_buffer_copy_on_write (buf);
+ gint y, h = stream->height, w = stream->width;
+ guint8 *tmp = g_malloc (w);
+
+ for (y = 0; y < h / 2; y++) {
+ swap_line (GST_BUFFER_DATA (buf) + w * y,
+ GST_BUFFER_DATA (buf) + w * (h - 1 - y), tmp, w);
+ }
+
+ g_free (tmp);
+
+ return buf;
+}
+
static gboolean
gst_avi_demux_process_next_entry (GstAviDemux * avi)
{
@@ -2036,6 +2071,9 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
GST_ERROR ("Failed to read %d bytes of data", entry->size);
return FALSE;
}
+ if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
+ buf = gst_avi_demux_invert (stream, buf);
+ }
if (entry->flags & GST_RIFF_IF_KEYFRAME) {
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_KEY_UNIT);
}
@@ -2126,6 +2164,10 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
} else {
GstClockTime dur_ts;
+ if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
+ buf = gst_avi_demux_invert (stream, buf);
+ }
+
GST_BUFFER_TIMESTAMP (buf) = next_ts;
gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &dur_ts);
GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
diff --git a/gst/avi/gstavidemux.h b/gst/avi/gstavidemux.h
index b506802e..c5db2581 100644
--- a/gst/avi/gstavidemux.h
+++ b/gst/avi/gstavidemux.h
@@ -64,6 +64,7 @@ typedef struct {
GstCaps *caps;
gst_riff_strh *strh;
gint blockalign, bitrate;
+ gint width, height;
/* current position (byte, frame, time) */
guint current_frame;