diff options
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-docs.sgml | 1 | ||||
-rw-r--r-- | docs/plugins/inspect/plugin-mpegvideoparse.xml | 34 | ||||
-rw-r--r-- | gst-plugins-bad.spec.in | 3 | ||||
-rw-r--r-- | gst/mpegvideoparse/Makefile.am | 24 | ||||
-rw-r--r-- | gst/mpegvideoparse/mpegpacketiser.c | 641 | ||||
-rw-r--r-- | gst/mpegvideoparse/mpegpacketiser.h | 153 | ||||
-rw-r--r-- | gst/mpegvideoparse/mpegvideoparse.c | 1037 | ||||
-rw-r--r-- | gst/mpegvideoparse/mpegvideoparse.h | 72 | ||||
-rw-r--r-- | gst/mpegvideoparse/mpegvideoparse.vcproj | 148 |
10 files changed, 1 insertions, 2116 deletions
diff --git a/configure.ac b/configure.ac index 299a53d12..a88a17018 100644 --- a/configure.ac +++ b/configure.ac @@ -315,7 +315,7 @@ GST_PLUGINS_NONPORTED=" adpcmdec adpcmenc aiff asfmux \ fieldanalysis freeverb freeze frei0r gaudieffects geometrictransform h264parse \ hdvparse hls id3tag inter interlace ivfparse jpegformat jp2kdecimator \ kate liveadder legacyresample librfb mpegdemux mpegtsmux \ - mpegpsmux mpegvideoparse mve mxf mythtv nsf nuvdemux \ + mpegpsmux mve mxf mythtv nsf nuvdemux \ patchdetect pnm rawparse real removesilence rtpmux rtpvp8 scaletempo \ sdi segmentclip siren speed subenc stereo tta videofilters \ videomaxrate videomeasure videosignal vmnc \ @@ -368,7 +368,6 @@ AG_GST_CHECK_PLUGIN(mpegdemux) AG_GST_CHECK_PLUGIN(mpegtsdemux) AG_GST_CHECK_PLUGIN(mpegtsmux) AG_GST_CHECK_PLUGIN(mpegpsmux) -AG_GST_CHECK_PLUGIN(mpegvideoparse) AG_GST_CHECK_PLUGIN(multifdsink) AG_GST_CHECK_PLUGIN(mve) AG_GST_CHECK_PLUGIN(mxf) @@ -1977,7 +1976,6 @@ gst/mpegtsdemux/Makefile gst/mpegtsmux/Makefile gst/mpegtsmux/tsmux/Makefile gst/mpegpsmux/Makefile -gst/mpegvideoparse/Makefile gst/multifdsink/Makefile gst/mve/Makefile gst/mxf/Makefile diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index 07fcdaa26..abf1ba357 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -184,7 +184,6 @@ <xi:include href="xml/plugin-mpegdemux2.xml" /> <xi:include href="xml/plugin-mpegpsmux.xml" /> <xi:include href="xml/plugin-mpegtsmux.xml" /> - <xi:include href="xml/plugin-mpegvideoparse.xml" /> <xi:include href="xml/plugin-mplex.xml" /> <xi:include href="xml/plugin-musepack.xml" /> <xi:include href="xml/plugin-musicbrainz.xml" /> diff --git a/docs/plugins/inspect/plugin-mpegvideoparse.xml b/docs/plugins/inspect/plugin-mpegvideoparse.xml deleted file mode 100644 index 7166f3c0d..000000000 --- a/docs/plugins/inspect/plugin-mpegvideoparse.xml +++ /dev/null @@ -1,34 +0,0 @@ -<plugin> - <name>mpegvideoparse</name> - <description>MPEG-1 and MPEG-2 video parser</description> - <filename>../../gst/mpegvideoparse/.libs/libgstmpegvideoparse.so</filename> - <basename>libgstmpegvideoparse.so</basename> - <version>0.10.22.1</version> - <license>LGPL</license> - <source>gst-plugins-bad</source> - <package>GStreamer Bad Plug-ins git</package> - <origin>Unknown package origin</origin> - <elements> - <element> - <name>legacympegvideoparse</name> - <longname>MPEG video elementary stream parser</longname> - <class>Codec/Parser/Video</class> - <description>Parses and frames MPEG-1 and MPEG-2 elementary video streams</description> - <author>Wim Taymans <wim.taymans@chello.be>, Jan Schmidt <thaytan@mad.scientist.com></author> - <pads> - <caps> - <name>sink</name> - <direction>sink</direction> - <presence>always</presence> - <details>video/mpeg, mpegversion=(int)[ 1, 2 ], parsed=(boolean)false, systemstream=(boolean)false</details> - </caps> - <caps> - <name>src</name> - <direction>source</direction> - <presence>always</presence> - <details>video/mpeg, mpegversion=(int)[ 1, 2 ], parsed=(boolean)true, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], pixel-aspect-ratio=(fraction)[ 0/1, 2147483647/1 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details> - </caps> - </pads> - </element> - </elements> -</plugin>
\ No newline at end of file diff --git a/gst-plugins-bad.spec.in b/gst-plugins-bad.spec.in index b69d7e416..10d786a00 100644 --- a/gst-plugins-bad.spec.in +++ b/gst-plugins-bad.spec.in @@ -223,16 +223,13 @@ make ERROR_CFLAGS='' ERROR_CXXFLAGS='' # %{_libdir}/gstreamer-%{majorminor}/libgstgaudieffects.so # %{_libdir}/gstreamer-%{majorminor}/libgstgeometrictransform.so # %{_libdir}/gstreamer-%{majorminor}/libgstgsettingselements.so -# %{_libdir}/gstreamer-%{majorminor}/libgsth264parse.so # %{_libdir}/gstreamer-%{majorminor}/libgsthdvparse.so # %{_libdir}/gstreamer-%{majorminor}/libgstid3tag.so # %{_libdir}/gstreamer-%{majorminor}/libgstivfparse.so # %{_libdir}/gstreamer-%{majorminor}/libgstjpegformat.so # %{_libdir}/gstreamer-%{majorminor}/libgstlegacyresample.so # %{_libdir}/gstreamer-%{majorminor}/libgstliveadder.so -#%{_libdir}/gstreamer-%{majorminor}/libgstmpeg4videoparse.so # %{_libdir}/gstreamer-%{majorminor}/libgstmpegdemux.so -# %{_libdir}/gstreamer-%{majorminor}/libgstmpegvideoparse.so # %{_libdir}/gstreamer-%{majorminor}/libgstmve.so # %{_libdir}/gstreamer-%{majorminor}/libgstmxf.so # %{_libdir}/gstreamer-%{majorminor}/libgstnsf.so diff --git a/gst/mpegvideoparse/Makefile.am b/gst/mpegvideoparse/Makefile.am deleted file mode 100644 index 4a52e27b5..000000000 --- a/gst/mpegvideoparse/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ - -plugin_LTLIBRARIES = libgstmpegvideoparse.la - -libgstmpegvideoparse_la_SOURCES = mpegvideoparse.c mpegpacketiser.c -libgstmpegvideoparse_la_CFLAGS = $(GST_CFLAGS) -libgstmpegvideoparse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) -libgstmpegvideoparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstmpegvideoparse_la_LIBTOOLFLAGS = --tag=disable-static - -noinst_HEADERS = mpegvideoparse.h mpegpacketiser.h - -Android.mk: Makefile.am $(BUILT_SOURCES) - androgenizer \ - -:PROJECT libgstmpegvideoparse -:SHARED libgstmpegvideoparse \ - -:TAGS eng debug \ - -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ - -:SOURCES $(libgstmpegvideoparse_la_SOURCES) \ - -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegvideoparse_la_CFLAGS) \ - -:LDFLAGS $(libgstmpegvideoparse_la_LDFLAGS) \ - $(libgstmpegvideoparse_la_LIBADD) \ - -ldl \ - -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ - LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \ - > $@ diff --git a/gst/mpegvideoparse/mpegpacketiser.c b/gst/mpegvideoparse/mpegpacketiser.c deleted file mode 100644 index 78721daea..000000000 --- a/gst/mpegvideoparse/mpegpacketiser.c +++ /dev/null @@ -1,641 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -/* The purpose of the packetiser is to parse the incoming buffers into 'blocks' - * that consist of the stream split at certain packet boundaries. It splits into - * a new block at the start of a GOP, Picture or Sequence packet. - * A GOP or sequence header always starts a new block. A Picture - * header starts a new block only if the previous packet was not a GOP - - * otherwise it is accumulated with the GOP */ -#include "mpegpacketiser.h" - -GST_DEBUG_CATEGORY_EXTERN (mpv_parse_debug); -#define GST_CAT_DEFAULT mpv_parse_debug - -static void collect_packets (MPEGPacketiser * p, GstBuffer * buf); - -void -mpeg_packetiser_init (MPEGPacketiser * p) -{ - p->adapter = gst_adapter_new (); - p->n_blocks = 0; - p->blocks = NULL; - mpeg_packetiser_flush (p); -} - -void -mpeg_packetiser_free (MPEGPacketiser * p) -{ - g_object_unref (p->adapter); - g_free (p->blocks); -} - -void -mpeg_packetiser_add_buf (MPEGPacketiser * p, GstBuffer * buf) -{ - /* Add the buffer to our pool */ - gst_adapter_push (p->adapter, buf); - - /* Store the timestamp to apply to the next picture that gets collected */ - if (p->cur_buf_ts != GST_CLOCK_TIME_NONE) { - p->prev_buf_ts = p->cur_buf_ts; - } - p->cur_buf_ts = GST_BUFFER_TIMESTAMP (buf); - - /* read what new packets we have in this buffer */ - collect_packets (p, buf); - - p->tracked_offset += GST_BUFFER_SIZE (buf); -} - -void -mpeg_packetiser_flush (MPEGPacketiser * p) -{ - gst_adapter_clear (p->adapter); - p->adapter_offset = 0; - - p->sync_word = 0xffffffff; - p->tracked_offset = 0; - p->prev_sync_packet = MPEG_PACKET_NONE; - - /* Reset our block info */ - p->cur_block_idx = -1; - p->first_block_idx = -1; - - /* Clear any pending timestamps */ - p->prev_buf_ts = GST_CLOCK_TIME_NONE; - p->cur_buf_ts = GST_CLOCK_TIME_NONE; -} - -guint8 * -mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end) -{ - guint32 code; - - if (G_UNLIKELY (cur == NULL)) - return NULL; - - code = *sync_word; - - while (cur < end) { - code <<= 8; - - if (code == 0x00000100) { - /* Reset the sync word accumulator */ - *sync_word = 0xffffffff; - return cur; - } - - /* accelerate search for start code */ - if (*cur > 1) { - while (cur < (end - 4) && *cur > 1) - if (cur[3] > 1) - cur += 4; - else - cur++; - code = 0xffffff00; - } - - /* Add the next available byte to the collected sync word */ - code |= *cur++; - } - - *sync_word = code; - return NULL; -} - -/* When we need to reallocate the blocks array, grow it by this much */ -#define BLOCKS_INCREMENT 5 - -/* Get the index of the next unfilled block in the buffer. May need to grow - * the array first */ -static gint -get_next_free_block (MPEGPacketiser * p) -{ - gint next; - gboolean grow_array = FALSE; - - /* Get a free block from the blocks array. May need to grow - * the array first */ - if (p->n_blocks == 0) { - grow_array = TRUE; - next = 0; - } else { - if (G_UNLIKELY (p->cur_block_idx == -1)) { - next = 0; - } else { - next = p->cur_block_idx; - if (((next + 1) % p->n_blocks) == p->first_block_idx) - grow_array = TRUE; - } - } - - if (grow_array) { - gint old_n_blocks = p->n_blocks; - - p->n_blocks += BLOCKS_INCREMENT; - - p->blocks = g_realloc (p->blocks, sizeof (MPEGBlockInfo) * p->n_blocks); - - /* Now we may need to move some data up to the end of the array, if the - * cur_block_idx is before the first_block_idx in the array. */ - if (p->cur_block_idx < p->first_block_idx) { - - GST_LOG ("Moving %d blocks from idx %d to idx %d of %d", - old_n_blocks - p->first_block_idx, - p->first_block_idx, p->first_block_idx + BLOCKS_INCREMENT, - p->n_blocks); - - memmove (p->blocks + p->first_block_idx + BLOCKS_INCREMENT, - p->blocks + p->first_block_idx, - sizeof (MPEGBlockInfo) * (old_n_blocks - p->first_block_idx)); - p->first_block_idx += BLOCKS_INCREMENT; - } - } - - return next; -} - -/* Mark the current block as complete */ -static void -complete_current_block (MPEGPacketiser * p, guint64 offset) -{ - MPEGBlockInfo *block; - - if (G_UNLIKELY (p->cur_block_idx == -1)) - return; /* No block is in progress */ - - /* If we're pointing at the first_block_idx, then we're about to re-complete - * a previously completed buffer. Not allowed, because the array should have - * been previously expanded to cope via a get_next_free_block call. */ - g_assert (p->cur_block_idx != p->first_block_idx); - - /* Get the appropriate entry from the blocks array */ - g_assert (p->blocks != NULL && p->cur_block_idx < p->n_blocks); - block = p->blocks + p->cur_block_idx; - - /* Extend the block length to the current offset */ - g_assert (block->offset < offset); - block->length = offset - block->offset; - - GST_LOG ("Completed block of type 0x%02x @ offset %" G_GUINT64_FORMAT - " with size %u", block->first_pack_type, block->offset, block->length); - - /* If this is the first complete block, set first_block_idx to be this block */ - if (p->first_block_idx == -1) - p->first_block_idx = p->cur_block_idx; - - /* Update the statistics regarding the packet we're handling */ - if (block->flags & MPEG_BLOCK_FLAG_PICTURE) - p->n_pictures++; - - /* And advance the cur_block_idx ptr to the next slot */ - p->cur_block_idx = (p->cur_block_idx + 1) % p->n_blocks; -} - -/* Accumulate the packet up to 'offset' into the current block - * (discard if no block is in progress). Update the block info - * to indicate what is in it. */ -static void -append_to_current_block (MPEGPacketiser * p, guint64 offset, guint8 pack_type) -{ - MPEGBlockInfo *block; - - if (G_UNLIKELY (p->cur_block_idx == -1)) - return; /* No block in progress, drop this packet */ - - /* Get the appropriate entry from the blocks array */ - g_assert (p->blocks != NULL && p->cur_block_idx < p->n_blocks); - block = p->blocks + p->cur_block_idx; - - /* Extend the block length to the current offset */ - g_assert (block->offset < offset); - block->length = offset - block->offset; - - /* Update flags */ - switch (pack_type) { - case MPEG_PACKET_SEQUENCE: - g_assert (!(block->flags & - (MPEG_BLOCK_FLAG_GOP | MPEG_BLOCK_FLAG_PICTURE))); - block->flags |= MPEG_BLOCK_FLAG_SEQUENCE; - break; - case MPEG_PACKET_GOP: - block->flags |= MPEG_BLOCK_FLAG_GOP; - break; - case MPEG_PACKET_PICTURE: - block->flags |= MPEG_BLOCK_FLAG_PICTURE; - break; - default: - break; - } -} - -static void -start_new_block (MPEGPacketiser * p, guint64 offset, guint8 pack_type) -{ - gint block_idx; - MPEGBlockInfo *block; - - /* First, append data up to the start of this block to the current one, but - * not including this packet info */ - complete_current_block (p, offset); - - block_idx = get_next_free_block (p); - /* FIXME: Retrieve the appropriate entry from the blocks array */ - /* Get the appropriate entry from the blocks array */ - g_assert (p->blocks != NULL && block_idx < p->n_blocks); - block = p->blocks + block_idx; - - /* Init the block */ - block->first_pack_type = pack_type; - block->offset = offset; - block->ts = GST_CLOCK_TIME_NONE; - - /* Initially, the length is 0. It grows as we encounter new sync headers */ - block->length = 0; - switch (pack_type) { - case MPEG_PACKET_SEQUENCE: - block->flags = MPEG_BLOCK_FLAG_SEQUENCE; - break; - case MPEG_PACKET_GOP: - block->flags = MPEG_BLOCK_FLAG_GOP; - break; - case MPEG_PACKET_PICTURE: - block->flags = MPEG_BLOCK_FLAG_PICTURE; - break; - default: - /* We don't start blocks with other packet types */ - g_assert_not_reached (); - } - - /* Make this our current block */ - p->cur_block_idx = block_idx; - - GST_LOG ("Started new block in slot %d with first pack 0x%02x @ offset %" - G_GUINT64_FORMAT, block_idx, block->first_pack_type, block->offset); - -} - -static void -handle_packet (MPEGPacketiser * p, guint64 offset, guint8 pack_type) -{ - GST_LOG ("offset %" G_GUINT64_FORMAT ", pack_type %2x", offset, pack_type); - switch (pack_type) { - case MPEG_PACKET_SEQUENCE: - case MPEG_PACKET_GOP: - /* Start a new block */ - start_new_block (p, offset, pack_type); - p->prev_sync_packet = pack_type; - break; - case MPEG_PACKET_PICTURE:{ - MPEGBlockInfo *block; - GstClockTime ts; - - /* Start a new block unless the previous sync packet was a GOP */ - if (p->prev_sync_packet != MPEG_PACKET_GOP) { - start_new_block (p, offset, pack_type); - } else { - append_to_current_block (p, offset, pack_type); - } - p->prev_sync_packet = pack_type; - - /* We have a picture packet, apply any pending timestamp. The logic here - * is that the timestamp on any incoming buffer needs to apply to the next - * picture packet where the _first_byte_ of the sync word starts after the - * packet boundary. We track the ts from the current buffer and a - * previous buffer in order to handle this correctly. It would still be - * possible to get it wrong if there was a PES packet smaller than 3 bytes - * but anyone that does that can suck it. */ - if ((offset >= p->tracked_offset) - && (p->cur_buf_ts != GST_CLOCK_TIME_NONE)) { - /* sync word started within this buffer - take the cur ts */ - ts = p->cur_buf_ts; - p->cur_buf_ts = GST_CLOCK_TIME_NONE; - p->prev_buf_ts = GST_CLOCK_TIME_NONE; - } else { - /* sync word started in a previous buffer - take the old ts */ - ts = p->prev_buf_ts; - p->prev_buf_ts = GST_CLOCK_TIME_NONE; - } - - /* If we didn't drop the packet, set the timestamp on it */ - if (G_LIKELY (p->cur_block_idx != -1)) { - block = p->blocks + p->cur_block_idx; - block->ts = ts; - GST_LOG ("Picture @ offset %" G_GINT64_FORMAT " has ts %" - GST_TIME_FORMAT, block->offset, GST_TIME_ARGS (block->ts)); - } - break; - } - default: - append_to_current_block (p, offset, pack_type); - break; - } -} - -static void -collect_packets (MPEGPacketiser * p, GstBuffer * buf) -{ - guint8 *cur; - guint8 *end = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf); - - cur = mpeg_util_find_start_code (&(p->sync_word), GST_BUFFER_DATA (buf), end); - while (cur != NULL) { - /* Calculate the offset as tracked since the last flush. Note that cur - * points to the last byte of the sync word, so we adjust by -3 to get the - * first byte */ - guint64 offset = p->tracked_offset + (cur - GST_BUFFER_DATA (buf) - 3); - - handle_packet (p, offset, *cur); - cur = mpeg_util_find_start_code (&(p->sync_word), cur, end); - } -} - -void -mpeg_packetiser_handle_eos (MPEGPacketiser * p) -{ - /* Append any remaining data to the current block */ - if (p->tracked_offset > 0) { - complete_current_block (p, p->tracked_offset); - } -} - -/* Returns a pointer to the block info for the completed block at the - * head of the queue, and extracts the bytes from the adapter if requested. - * Caller should move to the next block by calling mpeg_packetiser_next_block - * afterward. - */ -MPEGBlockInfo * -mpeg_packetiser_get_block (MPEGPacketiser * p, GstBuffer ** buf) -{ - MPEGBlockInfo *block; - - if (buf) - *buf = NULL; - - if (G_UNLIKELY (p->first_block_idx == -1)) { - return NULL; /* No complete blocks to discard */ - } - - /* p->first_block_idx can't get set != -1 unless some block storage got - * allocated */ - g_assert (p->blocks != NULL && p->n_blocks != 0); - block = p->blocks + p->first_block_idx; - - /* Can only get the buffer out once, so we'll return NULL on later attempts */ - if (buf != NULL && block->length > 0 && p->adapter_offset <= block->offset) { - /* Kick excess data out of the adapter */ - if (p->adapter_offset < block->offset) { - guint64 to_flush = block->offset - p->adapter_offset; - - g_assert (gst_adapter_available (p->adapter) >= to_flush); - gst_adapter_flush (p->adapter, to_flush); - p->adapter_offset += to_flush; - } - - g_assert (gst_adapter_available (p->adapter) >= block->length); - *buf = gst_adapter_take_buffer (p->adapter, block->length); - p->adapter_offset += block->length; - - GST_BUFFER_TIMESTAMP (*buf) = block->ts; - } else { - GST_DEBUG ("we have a block but do not meet all conditions buf: %p " - "block length: %d adapter offset %" G_GUINT64_FORMAT " block offset " - "%" G_GUINT64_FORMAT, buf, block->length, p->adapter_offset, - block->offset); - } - return block; -} - -/* Advance the first_block pointer to discard a completed block - * from the queue */ -void -mpeg_packetiser_next_block (MPEGPacketiser * p) -{ - gint next; - MPEGBlockInfo *block; - - block = mpeg_packetiser_get_block (p, NULL); - if (G_UNLIKELY (block == NULL)) - return; /* No complete blocks to discard */ - - /* Update the statistics regarding the block we're discarding */ - if (block->flags & MPEG_BLOCK_FLAG_PICTURE) - p->n_pictures--; - - next = (p->first_block_idx + 1) % p->n_blocks; - if (next == p->cur_block_idx) - p->first_block_idx = -1; /* Discarding the last block */ - else - p->first_block_idx = next; -} - -/* Set the Pixel Aspect Ratio in our hdr from a DAR code in the data */ -static void -set_par_from_dar (MPEGSeqHdr * hdr, guint8 asr_code) -{ - /* Pixel_width = DAR_width * display_vertical_size */ - /* Pixel_height = DAR_height * display_horizontal_size */ - switch (asr_code) { - case 0x02: /* 3:4 DAR = 4:3 pixels */ - hdr->par_w = 4 * hdr->height; - hdr->par_h = 3 * hdr->width; - break; - case 0x03: /* 9:16 DAR */ - hdr->par_w = 16 * hdr->height; - hdr->par_h = 9 * hdr->width; - break; - case 0x04: /* 1:2.21 DAR */ - hdr->par_w = 221 * hdr->height; - hdr->par_h = 100 * hdr->width; - break; - case 0x01: /* Square pixels */ - default: - hdr->par_w = hdr->par_h = 1; - break; - } -} - -static void -set_fps_from_code (MPEGSeqHdr * hdr, guint8 fps_code) -{ - const gint framerates[][2] = { - {30, 1}, {24000, 1001}, {24, 1}, {25, 1}, - {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001}, - {60, 1}, {30, 1} - }; - - if (fps_code < 10) { - hdr->fps_n = framerates[fps_code][0]; - hdr->fps_d = framerates[fps_code][1]; - } else { - /* Force a valid framerate */ - hdr->fps_n = 30000; - hdr->fps_d = 1001; - } -} - -static gboolean -mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) -{ - guint8 ext_code; - - if (G_UNLIKELY (data >= end)) - return FALSE; /* short extension packet */ - - ext_code = data[0] >> 4; - - switch (ext_code) { - case MPEG_PACKET_EXT_SEQUENCE: - { - /* Parse a Sequence Extension */ - guint8 horiz_size_ext, vert_size_ext; - guint8 fps_n_ext, fps_d_ext; - - if (G_UNLIKELY ((end - data) < 6)) - /* need at least 10 bytes, minus 4 for the start code 000001b5 */ - return FALSE; - - hdr->profile = data[0] & 0x0f; /* profile (0:2) + escape bit (3) */ - hdr->level = (data[1] >> 4) & 0x0f; - hdr->progressive = data[1] & 0x08; - /* chroma_format = (data[1] >> 2) & 0x03; */ - horiz_size_ext = ((data[1] << 1) & 0x02) | ((data[2] >> 7) & 0x01); - vert_size_ext = (data[2] >> 5) & 0x03; - /* low_delay = data[5] >> 7; */ - fps_n_ext = (data[5] >> 5) & 0x03; - fps_d_ext = data[5] & 0x1f; - - hdr->fps_n *= (fps_n_ext + 1); - hdr->fps_d *= (fps_d_ext + 1); - hdr->width += (horiz_size_ext << 12); - hdr->height += (vert_size_ext << 12); - break; - } - default: - break; - } - - return TRUE; -} - -gboolean -mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) -{ - guint32 code; - guint8 dar_idx, fps_idx; - guint32 sync_word = 0xffffffff; - gboolean load_intra_flag; - gboolean load_non_intra_flag; - - if (G_UNLIKELY ((end - data) < 12)) - return FALSE; /* Too small to be a sequence header */ - - code = GST_READ_UINT32_BE (data); - if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_SEQUENCE))) - return FALSE; - - /* Skip the sync word */ - data += 4; - - /* Parse the MPEG 1 bits */ - hdr->mpeg_version = 1; - - code = GST_READ_UINT32_BE (data); - hdr->width = (code >> 20) & 0xfff; - hdr->height = (code >> 8) & 0xfff; - - dar_idx = (code >> 4) & 0xf; - set_par_from_dar (hdr, dar_idx); - fps_idx = code & 0xf; - set_fps_from_code (hdr, fps_idx); - - hdr->bitrate = ((data[6] >> 6) | (data[5] << 2) | (data[4] << 10)); - if (hdr->bitrate == 0x3ffff) { - /* VBR stream */ - hdr->bitrate = 0; - } else { - /* Value in header is in units of 400 bps */ - hdr->bitrate *= 400; - } - - /* constrained_flag = (data[7] >> 2) & 0x01; */ - load_intra_flag = (data[7] >> 1) & 0x01; - if (load_intra_flag) { - if (G_UNLIKELY ((end - data) < 64)) - return FALSE; - data += 64; - } - - load_non_intra_flag = data[7] & 0x01; - if (load_non_intra_flag) { - if (G_UNLIKELY ((end - data) < 64)) - return FALSE; - data += 64; - } - - /* Advance past the rest of the MPEG-1 header */ - data += 8; - - /* Read MPEG-2 sequence extensions */ - data = mpeg_util_find_start_code (&sync_word, data, end); - while (data != NULL) { - if (G_UNLIKELY (data >= end)) - return FALSE; - - /* data points at the last byte of the start code */ - if (data[0] == MPEG_PACKET_EXTENSION) { - if (!mpeg_util_parse_extension_packet (hdr, data + 1, end)) - return FALSE; - - hdr->mpeg_version = 2; - } - data = mpeg_util_find_start_code (&sync_word, data, end); - } - - return TRUE; -} - -gboolean -mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) -{ - guint32 code; - - if (G_UNLIKELY ((end - data) < 6)) - return FALSE; /* Packet too small */ - - code = GST_READ_UINT32_BE (data); - if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_PICTURE))) - return FALSE; - - /* Skip the start code */ - data += 4; - - hdr->pic_type = (data[1] >> 3) & 0x07; - if (hdr->pic_type == 0 || hdr->pic_type > 4) - return FALSE; /* Corrupted picture packet */ - - return TRUE; -} diff --git a/gst/mpegvideoparse/mpegpacketiser.h b/gst/mpegvideoparse/mpegpacketiser.h deleted file mode 100644 index 88b1ca58a..000000000 --- a/gst/mpegvideoparse/mpegpacketiser.h +++ /dev/null @@ -1,153 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __MPEGPACKETISER_H__ -#define __MPEGPACKETISER_H__ - -#include <gst/gst.h> -#include <gst/base/gstadapter.h> - -typedef struct MPEGPacketiser MPEGPacketiser; -typedef struct MPEGBlockInfo MPEGBlockInfo; -typedef struct MPEGSeqHdr MPEGSeqHdr; -typedef struct MPEGPictureHdr MPEGPictureHdr; - -/* Packet ID codes for different packet types we - * care about */ -#define MPEG_PACKET_PICTURE 0x00 -#define MPEG_PACKET_SLICE_MIN 0x01 -#define MPEG_PACKET_SLICE_MAX 0xaf -#define MPEG_PACKET_SEQUENCE 0xb3 -#define MPEG_PACKET_EXTENSION 0xb5 -#define MPEG_PACKET_SEQUENCE_END 0xb7 -#define MPEG_PACKET_GOP 0xb8 -#define MPEG_PACKET_NONE 0xff - -/* Extension codes we care about */ -#define MPEG_PACKET_EXT_SEQUENCE 0x01 -#define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02 -#define MPEG_PACKET_EXT_QUANT_MATRIX 0x03 - -/* Flags indicating what type of packets are in this block, some are mutually - * exclusive though - ie, sequence packs are accumulated separately. GOP & - * Picture may occur together or separately */ -#define MPEG_BLOCK_FLAG_SEQUENCE 0x01 -#define MPEG_BLOCK_FLAG_PICTURE 0x02 -#define MPEG_BLOCK_FLAG_GOP 0x04 - -#define MPEG_PICTURE_TYPE_I 0x01 -#define MPEG_PICTURE_TYPE_P 0x02 -#define MPEG_PICTURE_TYPE_B 0x03 -#define MPEG_PICTURE_TYPE_D 0x04 - -struct MPEGBlockInfo { - guint8 first_pack_type; - guint8 flags; - - guint64 offset; - guint32 length; - - GstClockTime ts; -}; - -struct MPEGSeqHdr -{ - /* 0 for unknown, else 1 or 2 */ - guint8 mpeg_version; - - /* Pixel-Aspect Ratio from DAR code via set_par_from_dar */ - gint par_w, par_h; - /* Width and Height of the video */ - gint width, height; - /* Framerate */ - gint fps_n, fps_d; - /* Bitrate */ - guint bitrate; - /* Profile and level */ - guint profile, level; - - gboolean progressive; -}; - -struct MPEGPictureHdr -{ - guint8 pic_type; -}; - -struct MPEGPacketiser { - GstAdapter *adapter; - /* position in the adapter */ - guint64 adapter_offset; - - /* Sync word accumulator */ - guint32 sync_word; - - /* Offset since the last flush (unrelated to incoming buffer offsets) */ - guint64 tracked_offset; - - /* Number of picture packets currently collected */ - guint n_pictures; - - /* 2 sets of timestamps + offsets used to mark picture blocks - * The first is used when a sync word overlaps packet boundaries - * and comes from some buffer in the past. The next one comes from current - * buffer. These are only ever valid when handling streams from a demuxer, - * of course. */ - GstClockTime prev_buf_ts; - GstClockTime cur_buf_ts; - - /* MPEG id of the previous SEQUENCE, PICTURE or GOP packet. - MPEG_PACKET_NONE after a flush */ - guint8 prev_sync_packet; - - /* Indices into the blocks array. cur_block_idx is where we're writing and - indicates the end of the populated block entries. - first_block_idx is the read ptr. It may be -1 to indicate there are no - complete blocks available */ - gint cur_block_idx; - gint first_block_idx; - - /* An array of MPEGBlockInfo entries, used as a growable circular buffer - * indexed by cur_block_idx and bounded by last_block_idx */ - gint n_blocks; - MPEGBlockInfo *blocks; -}; - -void mpeg_packetiser_init (MPEGPacketiser *p); -void mpeg_packetiser_free (MPEGPacketiser *p); - -void mpeg_packetiser_add_buf (MPEGPacketiser *p, GstBuffer *buf); -void mpeg_packetiser_handle_eos (MPEGPacketiser *p); - -void mpeg_packetiser_flush (MPEGPacketiser *p); - -/* Get the blockinfo and buffer for the block at the head of the queue */ -MPEGBlockInfo *mpeg_packetiser_get_block (MPEGPacketiser *p, GstBuffer **buf); - -/* Advance to the next data block */ -void mpeg_packetiser_next_block (MPEGPacketiser *p); - -/* Utility functions for parsing MPEG packets */ -guint8 *mpeg_util_find_start_code (guint32 *sync_word, - guint8 *cur, guint8 *end); -gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, - guint8 *data, guint8 *end); -gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr *hdr, - guint8 *data, guint8 *end); - -#endif diff --git a/gst/mpegvideoparse/mpegvideoparse.c b/gst/mpegvideoparse/mpegvideoparse.c deleted file mode 100644 index 52a34c10f..000000000 --- a/gst/mpegvideoparse/mpegvideoparse.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include "mpegvideoparse.h" - -/* FIXME: there are still some things to do in this element. - * + Handle Sequence Display Extension to output the display size - * rather than the encoded size. - * + Do all the other stuff (documentation, tests) to get it into - * ugly or good. - * + low priority: - * - handle seeking in raw elementary streams - * - calculate timestamps for all un-timestamped frames, taking into - * account frame re-ordering. Doing this probably requires introducing - * an extra end-to-end delay however, so might not be really desirable. - * - Collect a list of regions and the sequence headers that apply - * to each region so that we properly handle SEQUENCE_END followed - * by a new sequence. At the moment, the caps will change if the - * sequence changes, but if we then seek to a different spot it might - * be wrong. Fortunately almost every stream only has 1 sequence. - */ -GST_DEBUG_CATEGORY (mpv_parse_debug); -#define GST_CAT_DEFAULT mpv_parse_debug - -static GstStaticPadTemplate src_template = -GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) [ 1, 2 ], " - "parsed = (boolean) true, " - "systemstream = (boolean) false, " - "width = (int) [ 16, 4096 ], " - "height = (int) [ 16, 4096 ], " - "pixel-aspect-ratio = (fraction) [ 0/1, MAX ], " - "framerate = (fraction) [ 0/1, MAX ]") - ); - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) [ 1, 2 ], " - "parsed = (boolean) false, " "systemstream = (boolean) false") - ); - -/* MpegVideoParse signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0 - /* FILL ME */ -}; - -static void gst_mpegvideoparse_class_init (MpegVideoParseClass * klass); -static void gst_mpegvideoparse_base_init (MpegVideoParseClass * klass); -static void gst_mpegvideoparse_init (MpegVideoParse * mpegvideoparse); -static void gst_mpegvideoparse_dispose (GObject * object); - -static GstFlowReturn gst_mpegvideoparse_chain (GstPad * pad, GstBuffer * buf); -static gboolean mpv_parse_sink_event (GstPad * pad, GstEvent * event); -static void gst_mpegvideoparse_flush (MpegVideoParse * mpegvideoparse); -static GstStateChangeReturn -gst_mpegvideoparse_change_state (GstElement * element, - GstStateChange transition); - -static void mpv_send_pending_segs (MpegVideoParse * mpegvideoparse); -static void mpv_clear_pending_segs (MpegVideoParse * mpegvideoparse); - -static GstElementClass *parent_class = NULL; - -/*static guint gst_mpegvideoparse_signals[LAST_SIGNAL] = { 0 }; */ - -GType -mpegvideoparse_get_type (void) -{ - static GType mpegvideoparse_type = 0; - - if (!mpegvideoparse_type) { - static const GTypeInfo mpegvideoparse_info = { - sizeof (MpegVideoParseClass), - (GBaseInitFunc) gst_mpegvideoparse_base_init, - NULL, - (GClassInitFunc) gst_mpegvideoparse_class_init, - NULL, - NULL, - sizeof (MpegVideoParse), - 0, - (GInstanceInitFunc) gst_mpegvideoparse_init, - }; - - mpegvideoparse_type = - g_type_register_static (GST_TYPE_ELEMENT, "MpegVideoParse", - &mpegvideoparse_info, 0); - } - return mpegvideoparse_type; -} - -static void -gst_mpegvideoparse_base_init (MpegVideoParseClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - - gst_element_class_set_details_simple (element_class, - "MPEG video elementary stream parser", - "Codec/Parser/Video", - "Parses and frames MPEG-1 and MPEG-2 elementary video streams", - "Wim Taymans <wim.taymans@chello.be>, " - "Jan Schmidt <thaytan@mad.scientist.com>"); -} - -static void -gst_mpegvideoparse_class_init (MpegVideoParseClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gstelement_class = (GstElementClass *) klass; - gobject_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->dispose = (GObjectFinalizeFunc) (gst_mpegvideoparse_dispose); - gstelement_class->change_state = gst_mpegvideoparse_change_state; -} - -static void -mpv_parse_reset (MpegVideoParse * mpegvideoparse) -{ - mpegvideoparse->seq_hdr.mpeg_version = 0; - mpegvideoparse->seq_hdr.width = mpegvideoparse->seq_hdr.height = -1; - mpegvideoparse->seq_hdr.fps_n = mpegvideoparse->seq_hdr.par_w = 0; - mpegvideoparse->seq_hdr.fps_d = mpegvideoparse->seq_hdr.par_h = 1; - - mpv_clear_pending_segs (mpegvideoparse); -} - -static void -mpv_send_pending_segs (MpegVideoParse * mpegvideoparse) -{ - while (mpegvideoparse->pending_segs) { - GstEvent *ev = mpegvideoparse->pending_segs->data; - - gst_pad_push_event (mpegvideoparse->srcpad, ev); - - mpegvideoparse->pending_segs = - g_list_delete_link (mpegvideoparse->pending_segs, - mpegvideoparse->pending_segs); - } - mpegvideoparse->pending_segs = NULL; -} - -static void -mpv_clear_pending_segs (MpegVideoParse * mpegvideoparse) -{ - while (mpegvideoparse->pending_segs) { - GstEvent *ev = mpegvideoparse->pending_segs->data; - gst_event_unref (ev); - - mpegvideoparse->pending_segs = - g_list_delete_link (mpegvideoparse->pending_segs, - mpegvideoparse->pending_segs); - } -} - -static void -gst_mpegvideoparse_init (MpegVideoParse * mpegvideoparse) -{ - mpegvideoparse->sinkpad = - gst_pad_new_from_static_template (&sink_template, "sink"); - gst_pad_set_chain_function (mpegvideoparse->sinkpad, - gst_mpegvideoparse_chain); - gst_pad_set_event_function (mpegvideoparse->sinkpad, mpv_parse_sink_event); - gst_element_add_pad (GST_ELEMENT (mpegvideoparse), mpegvideoparse->sinkpad); - - mpegvideoparse->srcpad = - gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_use_fixed_caps (mpegvideoparse->srcpad); - gst_element_add_pad (GST_ELEMENT (mpegvideoparse), mpegvideoparse->srcpad); - - mpeg_packetiser_init (&mpegvideoparse->packer); - - mpv_parse_reset (mpegvideoparse); -} - -void -gst_mpegvideoparse_dispose (GObject * object) -{ - MpegVideoParse *mpegvideoparse = GST_MPEGVIDEOPARSE (object); - - mpeg_packetiser_free (&mpegvideoparse->packer); - gst_buffer_replace (&mpegvideoparse->seq_hdr_buf, NULL); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static gboolean -mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse, - GstBuffer * buf) -{ - MPEGSeqHdr new_hdr; - guint8 *cur, *end; - - cur = GST_BUFFER_DATA (buf); - end = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf); - - memset (&new_hdr, 0, sizeof (MPEGSeqHdr)); - - if (G_UNLIKELY (!mpeg_util_parse_sequence_hdr (&new_hdr, cur, end))) - return FALSE; - - if (new_hdr.width < 16 || new_hdr.width > 4096 || - new_hdr.height < 16 || new_hdr.height > 4096) { - GST_WARNING_OBJECT (mpegvideoparse, "Width/height out of valid range " - "[16, 4096]"); - return FALSE; - } - - if (memcmp (&mpegvideoparse->seq_hdr, &new_hdr, sizeof (MPEGSeqHdr)) != 0) { - GstCaps *caps; - GstBuffer *seq_buf; - /* - * Profile indication - 1 => High, 2 => Spatially Scalable, - * 3 => SNR Scalable, 4 => Main, 5 => Simple - * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1 - */ - const gchar *profiles[] = { "high", "spatial", "snr", "main", "simple" }; - /* - * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low, - * except in the case of profile = 0 - */ - const gchar *levels[] = { "high", "high-1440", "main", "low" }; - - /* Store the entire sequence header + sequence header extension - for output as codec_data */ - seq_buf = gst_buffer_copy (buf); - gst_buffer_replace (&mpegvideoparse->seq_hdr_buf, seq_buf); - gst_buffer_unref (seq_buf); - - caps = gst_caps_new_simple ("video/mpeg", - "systemstream", G_TYPE_BOOLEAN, FALSE, - "parsed", G_TYPE_BOOLEAN, TRUE, - "mpegversion", G_TYPE_INT, new_hdr.mpeg_version, - "width", G_TYPE_INT, new_hdr.width, - "height", G_TYPE_INT, new_hdr.height, - "framerate", GST_TYPE_FRACTION, new_hdr.fps_n, new_hdr.fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, new_hdr.par_w, new_hdr.par_h, - "interlaced", G_TYPE_BOOLEAN, !new_hdr.progressive, - "codec_data", GST_TYPE_BUFFER, seq_buf, NULL); - - if (new_hdr.mpeg_version == 2) { - const gchar *profile = NULL, *level = NULL; - - if (new_hdr.profile > 0 && new_hdr.profile < 6) - profile = profiles[new_hdr.profile - 1]; - - if ((new_hdr.level > 3) && (new_hdr.level < 11) && - (new_hdr.level % 2 == 0)) - level = levels[(new_hdr.level >> 1) - 1]; - - if (new_hdr.profile == 8) { - /* Non-hierarchical profile */ - switch (new_hdr.level) { - case 2: - level = levels[0]; - case 5: - level = levels[2]; - profile = "4:2:2"; - break; - case 10: - level = levels[0]; - case 11: - level = levels[1]; - case 13: - level = levels[2]; - case 14: - level = levels[3]; - profile = "multiview"; - break; - default: - break; - } - } - - if (profile) - gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL); - else - GST_DEBUG ("Invalid profile - %u", new_hdr.profile); - - if (level) - gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL); - else - GST_DEBUG ("Invalid level - %u", new_hdr.level); - } - - GST_DEBUG ("New mpegvideoparse caps: %" GST_PTR_FORMAT, caps); - if (!gst_pad_set_caps (mpegvideoparse->srcpad, caps)) { - gst_caps_unref (caps); - return FALSE; - } - gst_caps_unref (caps); - - if (new_hdr.bitrate > 0) { - GstTagList *taglist; - - taglist = gst_tag_list_new_full (GST_TAG_BITRATE, new_hdr.bitrate, NULL); - gst_element_found_tags_for_pad (GST_ELEMENT_CAST (mpegvideoparse), - mpegvideoparse->srcpad, taglist); - } - - /* And update the new_hdr into our stored version */ - mpegvideoparse->seq_hdr = new_hdr; - } - - return TRUE; -} - -#ifndef GST_DISABLE_GST_DEBUG -static const gchar * -picture_start_code_name (guint8 psc) -{ - guint i; - const struct - { - guint8 psc; - const gchar *name; - } psc_names[] = { - { - 0x00, "Picture Start"}, { - 0xb0, "Reserved"}, { - 0xb1, "Reserved"}, { - 0xb2, "User Data Start"}, { - 0xb3, "Sequence Header Start"}, { - 0xb4, "Sequence Error"}, { - 0xb5, "Extnsion Start"}, { - 0xb6, "Reserved"}, { - 0xb7, "Sequence End"}, { - 0xb8, "Group Start"}, { - 0xb9, "Program End"} - }; - if (psc < 0xB0 && psc > 0) - return "Slice Start"; - - for (i = 0; i < G_N_ELEMENTS (psc_names); i++) - if (psc_names[i].psc == psc) - return psc_names[i].name; - - return "UNKNOWN"; -}; - -static const gchar * -picture_type_name (guint8 pct) -{ - guint i; - const struct - { - guint8 pct; - const gchar *name; - } pct_names[] = { - { - 0, "Forbidden"}, { - 1, "I Frame"}, { - 2, "P Frame"}, { - 3, "B Frame"}, { - 4, "DC Intra Coded (Shall Not Be Used!)"} - }; - - for (i = 0; i < G_N_ELEMENTS (pct_names); i++) - if (pct_names[i].pct == pct) - return pct_names[i].name; - - return "Reserved/Unknown"; -} -#endif /* GST_DISABLE_GST_DEBUG */ - -static gboolean -mpegvideoparse_handle_picture (MpegVideoParse * mpegvideoparse, GstBuffer * buf) -{ - guint8 *cur, *end; - guint32 sync_word = 0xffffffff; - - cur = GST_BUFFER_DATA (buf); - end = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf); - - cur = mpeg_util_find_start_code (&sync_word, cur, end); - while (cur != NULL) { - if (cur[0] == 0 || cur[0] > 0xaf) - GST_LOG_OBJECT (mpegvideoparse, "Picture Start Code : %s", - picture_start_code_name (cur[0])); - /* Cur points at the last byte of the start code */ - if (cur[0] == MPEG_PACKET_PICTURE) { - guint8 *pic_data = cur - 3; - MPEGPictureHdr hdr; - - /* pic_data points to the first byte of the sync word now */ - if (!mpeg_util_parse_picture_hdr (&hdr, pic_data, end)) - return FALSE; - - if (hdr.pic_type != MPEG_PICTURE_TYPE_I) - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); - - GST_LOG_OBJECT (mpegvideoparse, "Picture type is %s", - picture_type_name (hdr.pic_type)); - /* FIXME: Can use the picture type and number of fields to track a - * timestamp */ - break; - } - cur = mpeg_util_find_start_code (&sync_word, cur, end); - } - - return TRUE; -} - -#if 0 -static guint64 -gst_mpegvideoparse_time_code (guchar * gop, MPEGSeqHdr * seq_hdr) -{ - guint32 data = GST_READ_UINT32_BE (gop); - guint64 seconds; - guint8 frames; - - seconds = ((data & 0xfc000000) >> 26) * 3600; /* hours */ - seconds += ((data & 0x03f00000) >> 20) * 60; /* minutes */ - seconds += (data & 0x0007e000) >> 13; /* seconds */ - - frames = (data & 0x00001f80) >> 7; - - return seconds * GST_SECOND + gst_util_uint64_scale_int (frames * GST_SECOND, - seq_hdr->fps_d, seq_hdr->fps_n); -} -#endif - -static void -gst_mpegvideoparse_flush (MpegVideoParse * mpegvideoparse) -{ - GST_DEBUG_OBJECT (mpegvideoparse, "mpegvideoparse: flushing"); - - mpegvideoparse->next_offset = GST_BUFFER_OFFSET_NONE; - - g_list_foreach (mpegvideoparse->gather, (GFunc) gst_mini_object_unref, NULL); - g_list_free (mpegvideoparse->gather); - mpegvideoparse->gather = NULL; - g_list_foreach (mpegvideoparse->decode, (GFunc) gst_mini_object_unref, NULL); - g_list_free (mpegvideoparse->decode); - mpegvideoparse->decode = NULL; - mpeg_packetiser_flush (&mpegvideoparse->packer); - - mpv_clear_pending_segs (mpegvideoparse); -} - -static GstFlowReturn -mpegvideoparse_drain_avail (MpegVideoParse * mpegvideoparse) -{ - MPEGBlockInfo *cur; - GstBuffer *buf = NULL; - GstFlowReturn res = GST_FLOW_OK; - - cur = mpeg_packetiser_get_block (&mpegvideoparse->packer, &buf); - while ((cur != NULL) && (res == GST_FLOW_OK)) { - /* Handle the block */ - GST_LOG_OBJECT (mpegvideoparse, - "Have block of size %u with pack_type %s and flags 0x%02x", - cur->length, picture_start_code_name (cur->first_pack_type), - cur->flags); - - if ((cur->flags & MPEG_BLOCK_FLAG_SEQUENCE) && buf != NULL) { - /* Found a sequence header */ - if (!mpegvideoparse_handle_sequence (mpegvideoparse, buf)) { - GST_DEBUG_OBJECT (mpegvideoparse, - "Invalid sequence header. Dropping buffer."); - gst_buffer_unref (buf); - buf = NULL; - } - } else if (mpegvideoparse->seq_hdr.mpeg_version == 0 && buf) { - /* Don't start pushing out buffers until we've seen a sequence header */ - GST_DEBUG_OBJECT (mpegvideoparse, - "No sequence header yet. Dropping buffer of %u bytes", - GST_BUFFER_SIZE (buf)); - gst_buffer_unref (buf); - buf = NULL; - } - - if (buf != NULL) { - /* If outputting a PICTURE packet, we can calculate the duration - and possibly the timestamp */ - if (cur->flags & MPEG_BLOCK_FLAG_PICTURE) { - if (!mpegvideoparse_handle_picture (mpegvideoparse, buf)) { - /* Corrupted picture. Drop it. */ - GST_DEBUG_OBJECT (mpegvideoparse, - "Corrupted picture header. Dropping buffer of %u bytes", - GST_BUFFER_SIZE (buf)); - mpegvideoparse->need_discont = TRUE; - gst_buffer_unref (buf); - buf = NULL; - } - } - } - - if (buf != NULL) { - GST_DEBUG_OBJECT (mpegvideoparse, - "mpegvideoparse: pushing buffer of %u bytes with ts %" - GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); - - gst_buffer_set_caps (buf, GST_PAD_CAPS (mpegvideoparse->srcpad)); - - if (mpegvideoparse->need_discont) { - GST_DEBUG_OBJECT (mpegvideoparse, - "setting discont flag on outgoing buffer"); - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - mpegvideoparse->need_discont = FALSE; - } - - mpv_send_pending_segs (mpegvideoparse); - - res = gst_pad_push (mpegvideoparse->srcpad, buf); - buf = NULL; - } - - /* Advance to the next data block */ - mpeg_packetiser_next_block (&mpegvideoparse->packer); - cur = mpeg_packetiser_get_block (&mpegvideoparse->packer, &buf); - } - if (buf != NULL) - gst_buffer_unref (buf); - - return res; -} - -static GstFlowReturn -gst_mpegvideoparse_chain_forward (MpegVideoParse * mpegvideoparse, - gboolean discont, GstBuffer * buf) -{ - GstFlowReturn res; - guint64 next_offset = GST_BUFFER_OFFSET_NONE; - - GST_DEBUG_OBJECT (mpegvideoparse, - "mpegvideoparse: received buffer of %u bytes with ts %" - GST_TIME_FORMAT " and offset %" G_GINT64_FORMAT, GST_BUFFER_SIZE (buf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_OFFSET (buf)); - - /* If we have an offset, and the incoming offset doesn't match, - or we have a discont, handle it first by flushing out data - we have collected. */ - if (mpegvideoparse->next_offset != GST_BUFFER_OFFSET_NONE) { - if (GST_BUFFER_OFFSET_IS_VALID (buf)) { - if (mpegvideoparse->next_offset != GST_BUFFER_OFFSET (buf)) - discont = TRUE; - next_offset = GST_BUFFER_OFFSET (buf) + GST_BUFFER_SIZE (buf); - } else { - next_offset = mpegvideoparse->next_offset + GST_BUFFER_SIZE (buf); - } - } - - /* Clear out any existing stuff if the new buffer is discontinuous */ - if (discont) { - GST_DEBUG_OBJECT (mpegvideoparse, "Have discont packet, draining data"); - mpegvideoparse->need_discont = TRUE; - - mpeg_packetiser_handle_eos (&mpegvideoparse->packer); - res = mpegvideoparse_drain_avail (mpegvideoparse); - mpeg_packetiser_flush (&mpegvideoparse->packer); - if (res != GST_FLOW_OK) { - gst_buffer_unref (buf); - goto done; - } - } - - /* Takes ownership of the data */ - mpeg_packetiser_add_buf (&mpegvideoparse->packer, buf); - - /* And push out what we can */ - res = mpegvideoparse_drain_avail (mpegvideoparse); - -done: - /* Update our offset */ - mpegvideoparse->next_offset = next_offset; - - return res; -} - -/* scan the decode queue for a picture header with an I frame and return the - * index in the first buffer. We only scan the first buffer and possibly a - * couple of bytes of the next buffers to find the I frame. Scanning is done - * backwards because the first buffer could contain many picture start codes - * with I frames. */ -static guint -scan_keyframe (MpegVideoParse * mpegvideoparse) -{ - guint64 scanword; - guint count; - GList *walk; - GstBuffer *head; - guint8 *data; - guint size; - - /* we use an 8 byte buffer, this is enough to hold the picture start code and - * the picture header bits we are interested in. We init to 0xff so that when - * we have a valid picture start without the header bits, we will be able to - * detect this because it will generate an invalid picture type. */ - scanword = ~G_GUINT64_CONSTANT (0); - - GST_LOG_OBJECT (mpegvideoparse, "scan keyframe"); - - /* move to the second buffer if we can, we should have at least one buffer */ - walk = mpegvideoparse->decode; - g_return_val_if_fail (walk != NULL, -1); - - head = GST_BUFFER_CAST (walk->data); - - count = 0; - walk = g_list_next (walk); - while (walk) { - GstBuffer *buf = GST_BUFFER_CAST (walk->data); - - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); - - GST_LOG_OBJECT (mpegvideoparse, "collect remaining %d bytes from %p", - 6 - count, buf); - - while (size > 0 && count < 6) { - scanword = (scanword << 8) | *data++; - size--; - count++; - } - if (count == 6) - break; - - walk = g_list_next (walk); - } - /* move bits to the beginning of the word now */ - if (count) - scanword = (scanword << (8 * (8 - count))); - - GST_LOG_OBJECT (mpegvideoparse, "scanword 0x%016" G_GINT64_MODIFIER "x", - scanword); - - data = GST_BUFFER_DATA (head); - size = GST_BUFFER_SIZE (head); - - while (size > 0) { - scanword = (((guint64) data[size - 1]) << 56) | (scanword >> 8); - - GST_LOG_OBJECT (mpegvideoparse, - "scanword at %d 0x%016" G_GINT64_MODIFIER "x", size - 1, scanword); - - /* check picture start and picture type */ - if ((scanword & G_GUINT64_CONSTANT (0xffffffff00380000)) == - G_GUINT64_CONSTANT (0x0000010000080000)) - break; - - size--; - } - return size - 1; -} - -/* For reverse playback we use a technique that can be used for - * any keyframe based video codec. - * - * Input: - * Buffer decoding order: 7 8 9 4 5 6 1 2 3 EOS - * Keyframe flag: K K - * Discont flag: D D D - * - * - Each Discont marks a discont in the decoding order. - * - The keyframes mark where we can start decoding. For mpeg they are either - * set by the demuxer or we have to scan the buffers for a syncword and - * picture header with an I frame. - * - * First we prepend incomming buffers to the gather queue, whenever we receive - * a discont, we flush out the gather queue. - * - * The above data will be accumulated in the gather queue like this: - * - * gather queue: 9 8 7 - * D - * - * Whe buffer 4 is received (with a DISCONT), we flush the gather queue like - * this: - * - * while (gather) - * take head of queue and prepend to decode queue. - * if we copied a keyframe, decode the decode queue. - * - * After we flushed the gather queue, we add 4 to the (now empty) gather queue. - * We get the following situation: - * - * gather queue: 4 - * decode queue: 7 8 9 - * - * After we received 5 (Keyframe) and 6: - * - * gather queue: 6 5 4 - * decode queue: 7 8 9 - * - * When we receive 1 (DISCONT) which triggers a flush of the gather queue: - * - * Copy head of the gather queue (6) to decode queue: - * - * gather queue: 5 4 - * decode queue: 6 7 8 9 - * - * Copy head of the gather queue (5) to decode queue. This is a keyframe so we - * can start decoding. - * - * gather queue: 4 - * decode queue: 5 6 7 8 9 - * - * Decode frames in decode queue, we don't actually do the decoding but we - * will send the decode queue to the downstream element. This will empty the - * decoding queue again. - * - * Copy head of the gather queue (4) to decode queue, we flushed the gather - * queue and can now store input buffer in the gather queue: - * - * gather queue: 1 - * decode queue: 4 - * - * When we receive EOS, the queue looks like: - * - * gather queue: 3 2 1 - * decode queue: 4 - * - * Fill decode queue, first keyframe we copy is 2: - * - * gather queue: 1 - * decode queue: 2 3 4 - * - * After pushing the decode queue: - * - * gather queue: 1 - * decode queue: - * - * Leftover buffer 1 cannot be decoded and must be discarded. - */ -static GstFlowReturn -gst_mpegvideoparse_flush_decode (MpegVideoParse * mpegvideoparse, guint idx) -{ - GstFlowReturn res = GST_FLOW_OK; - GstBuffer *head = NULL; - - while (mpegvideoparse->decode) { - GstBuffer *buf; - - buf = GST_BUFFER_CAST (mpegvideoparse->decode->data); - - if (idx != -1) { - GstBuffer *temp; - - if (idx > 0) { - /* first buffer, split at the point where the picture start was - * detected and store as the new head of the decoding list. */ - head = gst_buffer_create_sub (buf, 0, idx); - /* push the remainder after the picture sync point downstream, this is the - * first DISCONT buffer we push. */ - temp = gst_buffer_create_sub (buf, idx, GST_BUFFER_SIZE (buf) - idx); - /* don't need old buffer anymore and swap new buffer */ - gst_buffer_unref (buf); - buf = temp; - } - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - idx = -1; - } else { - /* next buffers are not discont */ - GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT); - } - - GST_DEBUG_OBJECT (mpegvideoparse, "pushing buffer %p, ts %" GST_TIME_FORMAT, - buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); - - res = gst_pad_push (mpegvideoparse->srcpad, buf); - - mpegvideoparse->decode = - g_list_delete_link (mpegvideoparse->decode, mpegvideoparse->decode); - } - if (head) { - /* store remainder of the buffer */ - mpegvideoparse->decode = g_list_prepend (mpegvideoparse->decode, head); - } - return res; -} - -static GstFlowReturn -gst_mpegvideoparse_chain_reverse (MpegVideoParse * mpegvideoparse, - gboolean discont, GstBuffer * buf) -{ - GstFlowReturn res = GST_FLOW_OK; - - /* if we have a discont, move buffers to the decode list */ - if (G_UNLIKELY (discont)) { - GST_DEBUG_OBJECT (mpegvideoparse, "received discont,gathering buffers"); - - while (mpegvideoparse->gather) { - GstBuffer *gbuf; - guint keyframeidx; - - gbuf = GST_BUFFER_CAST (mpegvideoparse->gather->data); - /* remove from the gather list */ - mpegvideoparse->gather = - g_list_delete_link (mpegvideoparse->gather, mpegvideoparse->gather); - /* copy to decode queue */ - mpegvideoparse->decode = g_list_prepend (mpegvideoparse->decode, gbuf); - - GST_DEBUG_OBJECT (mpegvideoparse, "copied decoding buffer %p, len %d", - gbuf, g_list_length (mpegvideoparse->decode)); - - /* check if we copied a keyframe, we scan the buffers on the decode queue. - * We only need to scan the first buffer and at most 3 bytes of the second - * buffer. We return the index of the keyframe (or -1 when nothing was - * found) */ - while ((keyframeidx = scan_keyframe (mpegvideoparse)) != -1) { - GST_DEBUG_OBJECT (mpegvideoparse, "copied keyframe at %u", keyframeidx); - res = gst_mpegvideoparse_flush_decode (mpegvideoparse, keyframeidx); - } - } - } - - if (buf) { - /* add buffer to gather queue */ - GST_DEBUG_OBJECT (mpegvideoparse, "gathering buffer %p, size %u", buf, - GST_BUFFER_SIZE (buf)); - mpegvideoparse->gather = g_list_prepend (mpegvideoparse->gather, buf); - } - - return res; -} - -static GstFlowReturn -gst_mpegvideoparse_chain (GstPad * pad, GstBuffer * buf) -{ - MpegVideoParse *mpegvideoparse; - GstFlowReturn res; - gboolean discont; - - mpegvideoparse = - GST_MPEGVIDEOPARSE (gst_object_get_parent (GST_OBJECT (pad))); - - discont = GST_BUFFER_IS_DISCONT (buf); - - if (mpegvideoparse->segment.rate > 0.0) - res = gst_mpegvideoparse_chain_forward (mpegvideoparse, discont, buf); - else - res = gst_mpegvideoparse_chain_reverse (mpegvideoparse, discont, buf); - - gst_object_unref (mpegvideoparse); - - return res; -} - -static gboolean -mpv_parse_sink_event (GstPad * pad, GstEvent * event) -{ - gboolean res = TRUE; - MpegVideoParse *mpegvideoparse = - GST_MPEGVIDEOPARSE (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - { - gdouble rate, applied_rate; - GstFormat format; - gint64 start, stop, pos; - gboolean update; - - gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate, - &format, &start, &stop, &pos); - - if (format == GST_FORMAT_BYTES) { - /* FIXME: Later, we might use a seek table to seek on elementary stream - files, and that would allow byte-to-time conversions. It's not a high - priority - most mpeg video is muxed and then the demuxer handles - seeking. In the meantime, here's some commented out logic copied - from mp3parse */ -#if 0 - GstClockTime seg_start, seg_stop, seg_pos; - - /* stop time is allowed to be open-ended, but not start & pos */ - if (!mp3parse_bytepos_to_time (mp3parse, stop, &seg_stop)) - seg_stop = GST_CLOCK_TIME_NONE; - if (mp3parse_bytepos_to_time (mp3parse, start, &seg_start) && - mp3parse_bytepos_to_time (mp3parse, pos, &seg_pos)) { - gst_event_unref (event); - event = gst_event_new_new_segment_full (update, rate, applied_rate, - GST_FORMAT_TIME, seg_start, seg_stop, seg_pos); - format = GST_FORMAT_TIME; - GST_DEBUG_OBJECT (mp3parse, "Converted incoming segment to TIME. " - "start = %" G_GINT64_FORMAT ", stop = %" G_GINT64_FORMAT - "pos = %" G_GINT64_FORMAT, seg_start, seg_stop, seg_pos); - } -#endif - } - - if (format != GST_FORMAT_TIME) { - /* Unknown incoming segment format. Output a default open-ended - * TIME segment */ - gst_event_unref (event); - - /* set new values */ - format = GST_FORMAT_TIME; - start = 0; - stop = GST_CLOCK_TIME_NONE; - pos = 0; - /* create a new segment with these values */ - event = gst_event_new_new_segment_full (update, rate, applied_rate, - format, start, stop, pos); - } - - gst_mpegvideoparse_flush (mpegvideoparse); - - /* now configure the values */ - gst_segment_set_newsegment_full (&mpegvideoparse->segment, update, - rate, applied_rate, format, start, stop, pos); - - GST_DEBUG_OBJECT (mpegvideoparse, - "Pushing newseg rate %g, applied rate %g, format %d, start %" - G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", pos %" G_GINT64_FORMAT, - rate, applied_rate, format, start, stop, pos); - - /* Forward the event if we've seen a sequence header - * and therefore set output caps, otherwise queue it for later */ - if (mpegvideoparse->seq_hdr.mpeg_version != 0) - res = gst_pad_push_event (mpegvideoparse->srcpad, event); - else { - res = TRUE; - mpegvideoparse->pending_segs = - g_list_append (mpegvideoparse->pending_segs, event); - } - break; - } - case GST_EVENT_FLUSH_STOP: - GST_DEBUG_OBJECT (mpegvideoparse, "flush stop"); - gst_mpegvideoparse_flush (mpegvideoparse); - res = gst_pad_push_event (mpegvideoparse->srcpad, event); - break; - case GST_EVENT_EOS: - /* Push any remaining buffers out, then flush. */ - GST_DEBUG_OBJECT (mpegvideoparse, "received EOS"); - if (mpegvideoparse->segment.rate >= 0.0) { - mpeg_packetiser_handle_eos (&mpegvideoparse->packer); - mpegvideoparse_drain_avail (mpegvideoparse); - gst_mpegvideoparse_flush (mpegvideoparse); - } else { - gst_mpegvideoparse_chain_reverse (mpegvideoparse, TRUE, NULL); - gst_mpegvideoparse_flush_decode (mpegvideoparse, 0); - } - res = gst_pad_push_event (mpegvideoparse->srcpad, event); - break; - default: - res = gst_pad_push_event (mpegvideoparse->srcpad, event); - break; - } - - gst_object_unref (mpegvideoparse); - return res; -} - -static GstStateChangeReturn -gst_mpegvideoparse_change_state (GstElement * element, - GstStateChange transition) -{ - MpegVideoParse *mpegvideoparse; - GstStateChangeReturn ret; - - g_return_val_if_fail (GST_IS_MPEGVIDEOPARSE (element), - GST_STATE_CHANGE_FAILURE); - - mpegvideoparse = GST_MPEGVIDEOPARSE (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_segment_init (&mpegvideoparse->segment, GST_FORMAT_UNDEFINED); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - mpv_parse_reset (mpegvideoparse); - gst_mpegvideoparse_flush (mpegvideoparse); - break; - default: - break; - } - - return ret; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (mpv_parse_debug, "legacympegvideoparse", 0, - "MPEG Video Parser"); - - return gst_element_register (plugin, "legacympegvideoparse", - GST_RANK_NONE, GST_TYPE_MPEGVIDEOPARSE); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "mpegvideoparse", - "MPEG-1 and MPEG-2 video parser", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/gst/mpegvideoparse/mpegvideoparse.h b/gst/mpegvideoparse/mpegvideoparse.h deleted file mode 100644 index b514863ff..000000000 --- a/gst/mpegvideoparse/mpegvideoparse.h +++ /dev/null @@ -1,72 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __MPEGVIDEOPARSE_H__ -#define __MPEGVIDEOPARSE_H__ - -#include <gst/gst.h> -#include "mpegpacketiser.h" - -G_BEGIN_DECLS - -#define GST_TYPE_MPEGVIDEOPARSE \ - (mpegvideoparse_get_type()) -#define GST_MPEGVIDEOPARSE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEGVIDEOPARSE,MpegVideoParse)) -#define GST_MPEGVIDEOPARSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEGVIDEOPARSE,MpegVideoParseClass)) -#define GST_IS_MPEGVIDEOPARSE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEGVIDEOPARSE)) -#define GST_IS_MPEGVIDEOPARSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEGVIDEOPARSE)) - -typedef struct _MpegVideoParse MpegVideoParse; -typedef struct _MpegVideoParseClass MpegVideoParseClass; - -struct _MpegVideoParse { - GstElement element; - - GstPad *sinkpad, *srcpad; - GstSegment segment; - GList *pending_segs; - - gint64 next_offset; - gboolean need_discont; - - /* Info from the Sequence Header */ - MPEGSeqHdr seq_hdr; - GstBuffer *seq_hdr_buf; - - /* Packetise helper */ - MPEGPacketiser packer; - - /* gather/decode queues for reverse playback */ - GList *gather; - GList *decode; -}; - -struct _MpegVideoParseClass { - GstElementClass parent_class; -}; - -GType mpegvideoparse_get_type(void); - -G_END_DECLS - -#endif /* __MPEGVIDEOPARSE_H__ */ diff --git a/gst/mpegvideoparse/mpegvideoparse.vcproj b/gst/mpegvideoparse/mpegvideoparse.vcproj deleted file mode 100644 index 7aed71ac3..000000000 --- a/gst/mpegvideoparse/mpegvideoparse.vcproj +++ /dev/null @@ -1,148 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="7.10" - Name="mpegvideoparse" - ProjectGUID="{979C216F-0ACF-4956-AE00-055A42D678E6}" - Keyword="Win32Proj"> - <Platforms> - <Platform - Name="Win32"/> - </Platforms> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="../../win32/Debug" - IntermediateDirectory="../../win32/Debug" - ConfigurationType="2" - CharacterSet="2"> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;"../../gst-libs";../../../popt/include;../../../libxml2/include/libxml2" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;mpegvideoparse_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES" - MinimalRebuild="TRUE" - BasicRuntimeChecks="3" - RuntimeLibrary="3" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="TRUE" - DebugInformationFormat="4"/> - <Tool - Name="VCCustomBuildTool"/> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib" - OutputFile="$(OutDir)/mpegvideoparse.dll" - LinkIncremental="2" - AdditionalLibraryDirectories="../../../gstreamer/win32/Debug;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib" - ModuleDefinitionFile="" - GenerateDebugInformation="TRUE" - ProgramDatabaseFile="$(OutDir)/mpegvideoparse.pdb" - SubSystem="2" - OptimizeReferences="2" - ImportLibrary="$(OutDir)/mpegvideoparse.lib" - TargetMachine="1"/> - <Tool - Name="VCMIDLTool"/> - <Tool - Name="VCPostBuildEventTool" - CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/> - <Tool - Name="VCPreBuildEventTool"/> - <Tool - Name="VCPreLinkEventTool"/> - <Tool - Name="VCResourceCompilerTool"/> - <Tool - Name="VCWebServiceProxyGeneratorTool"/> - <Tool - Name="VCXMLDataGeneratorTool"/> - <Tool - Name="VCWebDeploymentTool"/> - <Tool - Name="VCManagedWrapperGeneratorTool"/> - <Tool - Name="VCAuxiliaryManagedWrapperGeneratorTool"/> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="../../win32/Release" - IntermediateDirectory="../../win32/Release" - ConfigurationType="2" - CharacterSet="2"> - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;"../../gst-libs";../../../popt/include;../../../libxml2/include/libxml2" - PreprocessorDefinitions="WIN32;NDEBUG;GST_DISABLE_GST_DEBUG;_WINDOWS;_USRDLL;mpegvideoparse_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES" - RuntimeLibrary="2" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="TRUE" - DebugInformationFormat="3"/> - <Tool - Name="VCCustomBuildTool"/> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib" - OutputFile="$(OutDir)/mpegvideoparse.dll" - LinkIncremental="1" - AdditionalLibraryDirectories="../../../gstreamer/win32/Release;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib" - ModuleDefinitionFile="" - GenerateDebugInformation="TRUE" - SubSystem="2" - OptimizeReferences="2" - EnableCOMDATFolding="2" - ImportLibrary="$(OutDir)/mpegvideoparse.lib" - TargetMachine="1"/> - <Tool - Name="VCMIDLTool"/> - <Tool - Name="VCPostBuildEventTool" - CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/> - <Tool - Name="VCPreBuildEventTool"/> - <Tool - Name="VCPreLinkEventTool"/> - <Tool - Name="VCResourceCompilerTool"/> - <Tool - Name="VCWebServiceProxyGeneratorTool"/> - <Tool - Name="VCXMLDataGeneratorTool"/> - <Tool - Name="VCWebDeploymentTool"/> - <Tool - Name="VCManagedWrapperGeneratorTool"/> - <Tool - Name="VCAuxiliaryManagedWrapperGeneratorTool"/> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> - <File - RelativePath=".\mpegvideoparse.c"> - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> - <File - RelativePath=".\mpegvideoparse.h"> - </File> - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> |