diff options
Diffstat (limited to 'gst-libs/gst')
-rw-r--r-- | gst-libs/gst/riff/Makefile.am | 13 | ||||
-rw-r--r-- | gst-libs/gst/riff/riff-ids.h | 319 | ||||
-rw-r--r-- | gst-libs/gst/riff/riff-media.c | 454 | ||||
-rw-r--r-- | gst-libs/gst/riff/riff-media.h | 55 | ||||
-rw-r--r-- | gst-libs/gst/riff/riff-read.c | 877 | ||||
-rw-r--r-- | gst-libs/gst/riff/riff.c | 16 | ||||
-rw-r--r-- | gst-libs/gst/riff/riff.h | 448 | ||||
-rw-r--r-- | gst-libs/gst/riff/riffencode.c | 181 | ||||
-rw-r--r-- | gst-libs/gst/riff/riffparse.c | 250 | ||||
-rw-r--r-- | gst-libs/gst/riff/riffutil.c | 47 |
10 files changed, 1724 insertions, 936 deletions
diff --git a/gst-libs/gst/riff/Makefile.am b/gst-libs/gst/riff/Makefile.am index 8795515f..26e3cc4f 100644 --- a/gst-libs/gst/riff/Makefile.am +++ b/gst-libs/gst/riff/Makefile.am @@ -1,10 +1,17 @@ - plugin_LTLIBRARIES = libgstriff.la -libgstriff_la_SOURCES = riffparse.c riffencode.c riffutil.c riff.c +libgstriff_la_SOURCES = \ + riff.c \ + riff-media.c \ + riff-read.c \ + riff-write.c libgstriffincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/riff -libgstriffinclude_HEADERS = riff.h +libgstriffinclude_HEADERS = \ + riff-ids.h \ + riff-media.h \ + riff-read.h \ + riff-write.h libgstriff_la_LIBADD = libgstriff_la_CFLAGS = $(GST_CFLAGS) diff --git a/gst-libs/gst/riff/riff-ids.h b/gst-libs/gst/riff/riff-ids.h new file mode 100644 index 00000000..da465c2d --- /dev/null +++ b/gst-libs/gst/riff/riff-ids.h @@ -0,0 +1,319 @@ +/* GStreamer RIFF I/O + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * riff-ids.h: RIFF IDs and structs + * + * 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 __GST_RIFF_IDS_H__ +#define __GST_RIFF_IDS_H__ + +#include <gst/gst.h> + +/* RIFF types */ +#define GST_RIFF_RIFF_WAVE GST_MAKE_FOURCC ('W','A','V','E') +#define GST_RIFF_RIFF_AVI GST_MAKE_FOURCC ('A','V','I',' ') + +/* tags */ +#define GST_RIFF_TAG_RIFF GST_MAKE_FOURCC ('R','I','F','F') +#define GST_RIFF_TAG_RIFX GST_MAKE_FOURCC ('R','I','F','X') +#define GST_RIFF_TAG_LIST GST_MAKE_FOURCC ('L','I','S','T') +#define GST_RIFF_TAG_avih GST_MAKE_FOURCC ('a','v','i','h') +#define GST_RIFF_TAG_strd GST_MAKE_FOURCC ('s','t','r','d') +#define GST_RIFF_TAG_strn GST_MAKE_FOURCC ('s','t','r','n') +#define GST_RIFF_TAG_strh GST_MAKE_FOURCC ('s','t','r','h') +#define GST_RIFF_TAG_strf GST_MAKE_FOURCC ('s','t','r','f') +#define GST_RIFF_TAG_vedt GST_MAKE_FOURCC ('v','e','d','t') +#define GST_RIFF_TAG_JUNK GST_MAKE_FOURCC ('J','U','N','K') +#define GST_RIFF_TAG_idx1 GST_MAKE_FOURCC ('i','d','x','1') +#define GST_RIFF_TAG_dmlh GST_MAKE_FOURCC ('d','m','l','h') +/* WAV stuff */ +#define GST_RIFF_TAG_fmt GST_MAKE_FOURCC ('f','m','t',' ') +#define GST_RIFF_TAG_data GST_MAKE_FOURCC ('d','a','t','a') + +/* LIST types */ +#define GST_RIFF_LIST_movi GST_MAKE_FOURCC ('m','o','v','i') +#define GST_RIFF_LIST_hdrl GST_MAKE_FOURCC ('h','d','r','l') +#define GST_RIFF_LIST_odml GST_MAKE_FOURCC ('o','d','m','l') +#define GST_RIFF_LIST_strl GST_MAKE_FOURCC ('s','t','r','l') +#define GST_RIFF_LIST_INFO GST_MAKE_FOURCC ('I','N','F','O') +#define GST_RIFF_LIST_AVIX GST_MAKE_FOURCC ('A','V','I','X') + +/* fcc types */ +#define GST_RIFF_FCC_vids GST_MAKE_FOURCC ('v','i','d','s') +#define GST_RIFF_FCC_auds GST_MAKE_FOURCC ('a','u','d','s') +#define GST_RIFF_FCC_pads GST_MAKE_FOURCC ('p','a','d','s') +#define GST_RIFF_FCC_txts GST_MAKE_FOURCC ('t','x','t','s') +#define GST_RIFF_FCC_vidc GST_MAKE_FOURCC ('v','i','d','c') +#define GST_RIFF_FCC_iavs GST_MAKE_FOURCC ('i','a','v','s') +/* fcc handlers */ +#define GST_RIFF_FCCH_RLE GST_MAKE_FOURCC ('R','L','E',' ') +#define GST_RIFF_FCCH_msvc GST_MAKE_FOURCC ('m','s','v','c') +#define GST_RIFF_FCCH_MSVC GST_MAKE_FOURCC ('M','S','V','C') + +/* INFO types - see http://www.saettler.com/RIFFMCI/riffmci.html */ +#define GST_RIFF_INFO_IARL GST_MAKE_FOURCC ('I','A','R','L') /* location */ +#define GST_RIFF_INFO_IART GST_MAKE_FOURCC ('I','A','R','T') /* artist */ +#define GST_RIFF_INFO_ICMS GST_MAKE_FOURCC ('I','C','M','S') /* commissioned */ +#define GST_RIFF_INFO_ICMT GST_MAKE_FOURCC ('I','C','M','T') /* comment */ +#define GST_RIFF_INFO_ICOP GST_MAKE_FOURCC ('I','C','O','P') /* copyright */ +#define GST_RIFF_INFO_ICRD GST_MAKE_FOURCC ('I','C','R','D') /* creation date */ +#define GST_RIFF_INFO_ICRP GST_MAKE_FOURCC ('I','C','R','P') /* cropped */ +#define GST_RIFF_INFO_IDIM GST_MAKE_FOURCC ('I','D','I','M') /* dimensions */ +#define GST_RIFF_INFO_IDPI GST_MAKE_FOURCC ('I','D','P','I') /* dots-per-inch */ +#define GST_RIFF_INFO_IENG GST_MAKE_FOURCC ('I','E','N','G') /* engineer(s) */ +#define GST_RIFF_INFO_IGNR GST_MAKE_FOURCC ('I','G','N','R') /* genre */ +#define GST_RIFF_INFO_IKEY GST_MAKE_FOURCC ('I','K','E','Y') /* keywords */ +#define GST_RIFF_INFO_ILGT GST_MAKE_FOURCC ('I','L','G','T') /* lightness */ +#define GST_RIFF_INFO_IMED GST_MAKE_FOURCC ('I','M','E','D') /* medium */ +#define GST_RIFF_INFO_INAM GST_MAKE_FOURCC ('I','N','A','M') /* name */ +#define GST_RIFF_INFO_IPLT GST_MAKE_FOURCC ('I','P','L','T') /* palette setting */ +#define GST_RIFF_INFO_IPRD GST_MAKE_FOURCC ('I','P','R','D') /* product */ +#define GST_RIFF_INFO_ISBJ GST_MAKE_FOURCC ('I','S','B','J') /* subject */ +#define GST_RIFF_INFO_ISFT GST_MAKE_FOURCC ('I','S','F','T') /* software */ +#define GST_RIFF_INFO_ISHP GST_MAKE_FOURCC ('I','S','H','P') /* sharpness */ +#define GST_RIFF_INFO_ISRC GST_MAKE_FOURCC ('I','S','R','C') /* source */ +#define GST_RIFF_INFO_ISRF GST_MAKE_FOURCC ('I','S','R','F') /* source form */ +#define GST_RIFF_INFO_ITCH GST_MAKE_FOURCC ('I','T','C','H') /* technician(s) */ + +/*********Chunk Names***************/ +#define GST_RIFF_FF00 GST_MAKE_FOURCC (0xFF,0xFF,0x00,0x00) +#define GST_RIFF_00 GST_MAKE_FOURCC ('0', '0',0x00,0x00) +#define GST_RIFF_01 GST_MAKE_FOURCC ('0', '1',0x00,0x00) +#define GST_RIFF_02 GST_MAKE_FOURCC ('0', '2',0x00,0x00) +#define GST_RIFF_03 GST_MAKE_FOURCC ('0', '3',0x00,0x00) +#define GST_RIFF_04 GST_MAKE_FOURCC ('0', '4',0x00,0x00) +#define GST_RIFF_05 GST_MAKE_FOURCC ('0', '5',0x00,0x00) +#define GST_RIFF_06 GST_MAKE_FOURCC ('0', '6',0x00,0x00) +#define GST_RIFF_07 GST_MAKE_FOURCC ('0', '7',0x00,0x00) +#define GST_RIFF_00pc GST_MAKE_FOURCC ('0', '0', 'p', 'c') +#define GST_RIFF_01pc GST_MAKE_FOURCC ('0', '1', 'p', 'c') +#define GST_RIFF_00dc GST_MAKE_FOURCC ('0', '0', 'd', 'c') +#define GST_RIFF_00dx GST_MAKE_FOURCC ('0', '0', 'd', 'x') +#define GST_RIFF_00db GST_MAKE_FOURCC ('0', '0', 'd', 'b') +#define GST_RIFF_00xx GST_MAKE_FOURCC ('0', '0', 'x', 'x') +#define GST_RIFF_00id GST_MAKE_FOURCC ('0', '0', 'i', 'd') +#define GST_RIFF_00rt GST_MAKE_FOURCC ('0', '0', 'r', 't') +#define GST_RIFF_0021 GST_MAKE_FOURCC ('0', '0', '2', '1') +#define GST_RIFF_00iv GST_MAKE_FOURCC ('0', '0', 'i', 'v') +#define GST_RIFF_0031 GST_MAKE_FOURCC ('0', '0', '3', '1') +#define GST_RIFF_0032 GST_MAKE_FOURCC ('0', '0', '3', '2') +#define GST_RIFF_00vc GST_MAKE_FOURCC ('0', '0', 'v', 'c') +#define GST_RIFF_00xm GST_MAKE_FOURCC ('0', '0', 'x', 'm') +#define GST_RIFF_01wb GST_MAKE_FOURCC ('0', '1', 'w', 'b') +#define GST_RIFF_01dc GST_MAKE_FOURCC ('0', '1', 'd', 'c') +#define GST_RIFF_00__ GST_MAKE_FOURCC ('0', '0', '_', '_') + +/*********VIDEO CODECS**************/ +#define GST_RIFF_cram GST_MAKE_FOURCC ('c', 'r', 'a', 'm') +#define GST_RIFF_CRAM GST_MAKE_FOURCC ('C', 'R', 'A', 'M') +#define GST_RIFF_wham GST_MAKE_FOURCC ('w', 'h', 'a', 'm') +#define GST_RIFF_WHAM GST_MAKE_FOURCC ('W', 'H', 'A', 'M') +#define GST_RIFF_rgb GST_MAKE_FOURCC (0x00,0x00,0x00,0x00) +#define GST_RIFF_RGB GST_MAKE_FOURCC ('R', 'G', 'B', ' ') +#define GST_RIFF_rle8 GST_MAKE_FOURCC (0x01,0x00,0x00,0x00) +#define GST_RIFF_RLE8 GST_MAKE_FOURCC ('R', 'L', 'E', '8') +#define GST_RIFF_rle4 GST_MAKE_FOURCC (0x02,0x00,0x00,0x00) +#define GST_RIFF_RLE4 GST_MAKE_FOURCC ('R', 'L', 'E', '4') +#define GST_RIFF_none GST_MAKE_FOURCC (0x00,0x00,0xFF,0xFF) +#define GST_RIFF_NONE GST_MAKE_FOURCC ('N', 'O', 'N', 'E') +#define GST_RIFF_pack GST_MAKE_FOURCC (0x01,0x00,0xFF,0xFF) +#define GST_RIFF_PACK GST_MAKE_FOURCC ('P', 'A', 'C', 'K') +#define GST_RIFF_tran GST_MAKE_FOURCC (0x02,0x00,0xFF,0xFF) +#define GST_RIFF_TRAN GST_MAKE_FOURCC ('T', 'R', 'A', 'N') +#define GST_RIFF_ccc GST_MAKE_FOURCC (0x03,0x00,0xFF,0xFF) +#define GST_RIFF_CCC GST_MAKE_FOURCC ('C', 'C', 'C', ' ') +#define GST_RIFF_cyuv GST_MAKE_FOURCC ('c', 'y', 'u', 'v') +#define GST_RIFF_CYUV GST_MAKE_FOURCC ('C', 'Y', 'U', 'V') +#define GST_RIFF_jpeg GST_MAKE_FOURCC (0x04,0x00,0xFF,0xFF) +#define GST_RIFF_JPEG GST_MAKE_FOURCC ('J', 'P', 'E', 'G') +#define GST_RIFF_MJPG GST_MAKE_FOURCC ('M', 'J', 'P', 'G') +#define GST_RIFF_mJPG GST_MAKE_FOURCC ('m', 'J', 'P', 'G') +#define GST_RIFF_IJPG GST_MAKE_FOURCC ('I', 'J', 'P', 'G') +#define GST_RIFF_rt21 GST_MAKE_FOURCC ('r', 't', '2', '1') +#define GST_RIFF_RT21 GST_MAKE_FOURCC ('R', 'T', '2', '1') +#define GST_RIFF_iv31 GST_MAKE_FOURCC ('i', 'v', '3', '1') +#define GST_RIFF_IV31 GST_MAKE_FOURCC ('I', 'V', '3', '1') +#define GST_RIFF_iv32 GST_MAKE_FOURCC ('i', 'v', '3', '2') +#define GST_RIFF_IV32 GST_MAKE_FOURCC ('I', 'V', '3', '2') +#define GST_RIFF_iv41 GST_MAKE_FOURCC ('i', 'v', '4', '1') +#define GST_RIFF_IV41 GST_MAKE_FOURCC ('I', 'V', '4', '1') +#define GST_RIFF_iv50 GST_MAKE_FOURCC ('i', 'v', '5', '0') +#define GST_RIFF_IV50 GST_MAKE_FOURCC ('I', 'V', '5', '0') +#define GST_RIFF_cvid GST_MAKE_FOURCC ('c', 'v', 'i', 'd') +#define GST_RIFF_CVID GST_MAKE_FOURCC ('C', 'V', 'I', 'D') +#define GST_RIFF_ULTI GST_MAKE_FOURCC ('U', 'L', 'T', 'I') +#define GST_RIFF_ulti GST_MAKE_FOURCC ('u', 'l', 't', 'i') +#define GST_RIFF_YUV9 GST_MAKE_FOURCC ('Y', 'V', 'U', '9') +#define GST_RIFF_YVU9 GST_MAKE_FOURCC ('Y', 'U', 'V', '9') +#define GST_RIFF_XMPG GST_MAKE_FOURCC ('X', 'M', 'P', 'G') +#define GST_RIFF_xmpg GST_MAKE_FOURCC ('x', 'm', 'p', 'g') +#define GST_RIFF_VDOW GST_MAKE_FOURCC ('V', 'D', 'O', 'W') +#define GST_RIFF_MVI1 GST_MAKE_FOURCC ('M', 'V', 'I', '1') +#define GST_RIFF_v422 GST_MAKE_FOURCC ('v', '4', '2', '2') +#define GST_RIFF_V422 GST_MAKE_FOURCC ('V', '4', '2', '2') +#define GST_RIFF_mvi1 GST_MAKE_FOURCC ('m', 'v', 'i', '1') +#define GST_RIFF_MPIX GST_MAKE_FOURCC (0x04,0x00, 'i', '1') /* MotionPixels munged their id */ +#define GST_RIFF_AURA GST_MAKE_FOURCC ('A', 'U', 'R', 'A') +#define GST_RIFF_DMB1 GST_MAKE_FOURCC ('D', 'M', 'B', '1') +#define GST_RIFF_dmb1 GST_MAKE_FOURCC ('d', 'm', 'b', '1') + +#define GST_RIFF_BW10 GST_MAKE_FOURCC ('B', 'W', '1', '0') +#define GST_RIFF_bw10 GST_MAKE_FOURCC ('b', 'w', '1', '0') + +#define GST_RIFF_yuy2 GST_MAKE_FOURCC ('y', 'u', 'y', '2') +#define GST_RIFF_YUY2 GST_MAKE_FOURCC ('Y', 'U', 'Y', '2') +#define GST_RIFF_YUV8 GST_MAKE_FOURCC ('Y', 'U', 'V', '8') +#define GST_RIFF_WINX GST_MAKE_FOURCC ('W', 'I', 'N', 'X') +#define GST_RIFF_WPY2 GST_MAKE_FOURCC ('W', 'P', 'Y', '2') +#define GST_RIFF_m263 GST_MAKE_FOURCC ('m', '2', '6', '3') +#define GST_RIFF_M263 GST_MAKE_FOURCC ('M', '2', '6', '3') + +#define GST_RIFF_Q1_0 GST_MAKE_FOURCC ('Q', '1',0x2e, '0') +#define GST_RIFF_SFMC GST_MAKE_FOURCC ('S', 'F', 'M', 'C') + +#define GST_RIFF_y41p GST_MAKE_FOURCC ('y', '4', '1', 'p') +#define GST_RIFF_Y41P GST_MAKE_FOURCC ('Y', '4', '1', 'P') +#define GST_RIFF_yv12 GST_MAKE_FOURCC ('y', 'v', '1', '2') +#define GST_RIFF_YV12 GST_MAKE_FOURCC ('Y', 'V', '1', '2') +#define GST_RIFF_vixl GST_MAKE_FOURCC ('v', 'i', 'x', 'l') +#define GST_RIFF_VIXL GST_MAKE_FOURCC ('V', 'I', 'X', 'L') +#define GST_RIFF_iyuv GST_MAKE_FOURCC ('i', 'y', 'u', 'v') +#define GST_RIFF_IYUV GST_MAKE_FOURCC ('I', 'Y', 'U', 'V') +#define GST_RIFF_i420 GST_MAKE_FOURCC ('i', '4', '2', '0') +#define GST_RIFF_I420 GST_MAKE_FOURCC ('I', '4', '2', '0') +#define GST_RIFF_vyuy GST_MAKE_FOURCC ('v', 'y', 'u', 'y') +#define GST_RIFF_VYUY GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y') + +#define GST_RIFF_DIV3 GST_MAKE_FOURCC ('D', 'I', 'V', '3') + +#define GST_RIFF_rpza GST_MAKE_FOURCC ('r', 'p', 'z', 'a') +/* And this here's the mistakes that need to be supported */ +#define GST_RIFF_azpr GST_MAKE_FOURCC ('a', 'z', 'p', 'r') /* recognize Apple's rpza mangled? */ + +/*********** FND in MJPG **********/ +#define GST_RIFF_ISFT GST_MAKE_FOURCC ('I', 'S', 'F', 'T') +#define GST_RIFF_IDIT GST_MAKE_FOURCC ('I', 'D', 'I', 'T') + +#define GST_RIFF_00AM GST_MAKE_FOURCC ('0', '0', 'A', 'M') +#define GST_RIFF_DISP GST_MAKE_FOURCC ('D', 'I', 'S', 'P') +#define GST_RIFF_ISBJ GST_MAKE_FOURCC ('I', 'S', 'B', 'J') + +#define GST_RIFF_rec GST_MAKE_FOURCC ('r', 'e', 'c', ' ') + +/* common data structures */ +typedef struct _gst_riff_strh { + guint32 type; /* stream type */ + guint32 fcc_handler; /* fcc_handler */ + guint32 flags; +/* flags values */ +#define GST_RIFF_STRH_DISABLED 0x000000001 +#define GST_RIFF_STRH_VIDEOPALCHANGES 0x000010000 + guint32 priority; + guint32 init_frames; /* initial frames (???) */ + guint32 scale; + guint32 rate; + guint32 start; + guint32 length; + guint32 bufsize; /* suggested buffer size */ + guint32 quality; + guint32 samplesize; + /* XXX 16 bytes ? */ +} gst_riff_strh; + +typedef struct _gst_riff_strf_vids { /* == BitMapInfoHeader */ + guint32 size; + guint32 width; + guint32 height; + guint16 planes; + guint16 bit_cnt; + guint32 compression; + guint32 image_size; + guint32 xpels_meter; + guint32 ypels_meter; + guint32 num_colors; /* used colors */ + guint32 imp_colors; /* important colors */ + /* may be more for some codecs */ +} gst_riff_strf_vids; + + +typedef struct _gst_riff_strf_auds { /* == WaveHeader (?) */ + guint16 format; +/**** from public Microsoft RIFF docs ******/ +#define GST_RIFF_WAVE_FORMAT_UNKNOWN (0x0000) +#define GST_RIFF_WAVE_FORMAT_PCM (0x0001) +#define GST_RIFF_WAVE_FORMAT_ADPCM (0x0002) +#define GST_RIFF_WAVE_FORMAT_IBM_CVSD (0x0005) +#define GST_RIFF_WAVE_FORMAT_ALAW (0x0006) +#define GST_RIFF_WAVE_FORMAT_MULAW (0x0007) +#define GST_RIFF_WAVE_FORMAT_OKI_ADPCM (0x0010) +#define GST_RIFF_WAVE_FORMAT_DVI_ADPCM (0x0011) +#define GST_RIFF_WAVE_FORMAT_DIGISTD (0x0015) +#define GST_RIFF_WAVE_FORMAT_DIGIFIX (0x0016) +#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020) +#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022) +#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031) +#define GST_RIFF_WAVE_FORMAT_MSN (0x0032) +#define GST_RIFF_WAVE_FORMAT_MPEGL12 (0x0050) +#define GST_RIFF_WAVE_FORMAT_MPEGL3 (0x0055) +#define GST_RIFF_IBM_FORMAT_MULAW (0x0101) +#define GST_RIFF_IBM_FORMAT_ALAW (0x0102) +#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103) +#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV1 (0x0160) +#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV2 (0x0161) +#define GST_RIFF_WAVE_FORMAT_WMAV9 (0x0162) +#define GST_RIFF_WAVE_FORMAT_A52 (0x2000) +#define GST_RIFF_WAVE_FORMAT_VORBIS1 (0x674f) +#define GST_RIFF_WAVE_FORMAT_VORBIS2 (0x6750) +#define GST_RIFF_WAVE_FORMAT_VORBIS3 (0x6751) +#define GST_RIFF_WAVE_FORMAT_VORBIS1PLUS (0x676f) +#define GST_RIFF_WAVE_FORMAT_VORBIS2PLUS (0x6770) +#define GST_RIFF_WAVE_FORMAT_VORBIS3PLUS (0x6771) + guint16 channels; + guint32 rate; + guint32 av_bps; + guint16 blockalign; + guint16 size; +} gst_riff_strf_auds; + +typedef struct _gst_riff_strf_iavs { + guint32 DVAAuxSrc; + guint32 DVAAuxCtl; + guint32 DVAAuxSrc1; + guint32 DVAAuxCtl1; + guint32 DVVAuxSrc; + guint32 DVVAuxCtl; + guint32 DVReserved1; + guint32 DVReserved2; +} gst_riff_strf_iavs; + +typedef struct _gst_riff_index_entry { + guint32 id; + guint32 flags; +#define GST_RIFF_IF_LIST (0x00000001L) +#define GST_RIFF_IF_KEYFRAME (0x00000010L) +#define GST_RIFF_IF_NO_TIME (0x00000100L) +#define GST_RIFF_IF_COMPUSE (0x0FFF0000L) + guint32 offset; + guint32 size; +} gst_riff_index_entry; + +typedef struct _gst_riff_dmlh { + guint32 totalframes; +} gst_riff_dmlh; + +#endif /* __GST_RIFF_IDS_H__ */ diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c new file mode 100644 index 00000000..c074d0a4 --- /dev/null +++ b/gst-libs/gst/riff/riff-media.c @@ -0,0 +1,454 @@ +/* GStreamer RIFF I/O + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * riff-media.h: RIFF-id to/from caps routines + * + * 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 "riff-ids.h" +#include "riff-media.h" + +GstCaps * +gst_riff_create_video_caps (guint32 codec_fcc, + gst_riff_strh *strh, + gst_riff_strf_vids *strf) +{ + GstCaps *caps = NULL; + + switch (codec_fcc) { + case GST_MAKE_FOURCC('I','4','2','0'): + case GST_MAKE_FOURCC('Y','U','Y','2'): + caps = GST_CAPS_NEW ( + "riff_video_raw", + "video/x-raw-yuv", + "format", GST_PROPS_FOURCC (codec_fcc) + ); + break; + + case GST_MAKE_FOURCC('M','J','P','G'): /* YUY2 MJPEG */ + case GST_MAKE_FOURCC('J','P','E','G'): /* generic (mostly RGB) MJPEG */ + case GST_MAKE_FOURCC('P','I','X','L'): /* Miro/Pinnacle fourccs */ + case GST_MAKE_FOURCC('V','I','X','L'): /* Miro/Pinnacle fourccs */ + caps = GST_CAPS_NEW ( + "riff_video_jpeg", + "video/x-jpeg", + NULL + ); + break; + + case GST_MAKE_FOURCC('H','F','Y','U'): + caps = GST_CAPS_NEW ( + "riff_video_hfyu", + "video/x-huffyuv", + NULL + ); + break; + + case GST_MAKE_FOURCC('M','P','E','G'): + case GST_MAKE_FOURCC('M','P','G','I'): + caps = GST_CAPS_NEW ( + "riff_video_mpeg1", + "video/mpeg", + "systemstream", GST_PROPS_BOOLEAN (FALSE), + "mpegversion", GST_PROPS_BOOLEAN (1) + ); + break; + + case GST_MAKE_FOURCC('H','2','6','3'): + case GST_MAKE_FOURCC('i','2','6','3'): + case GST_MAKE_FOURCC('L','2','6','3'): + case GST_MAKE_FOURCC('M','2','6','3'): + case GST_MAKE_FOURCC('V','D','O','W'): + case GST_MAKE_FOURCC('V','I','V','O'): + case GST_MAKE_FOURCC('x','2','6','3'): + caps = GST_CAPS_NEW ( + "riff_video_h263", + "video/x-h263", + NULL + ); + break; + + case GST_MAKE_FOURCC('D','I','V','3'): + case GST_MAKE_FOURCC('D','I','V','4'): + case GST_MAKE_FOURCC('D','I','V','5'): + caps = GST_CAPS_NEW ( + "riff_video_divx3", + "video/x-divx", + "divxversion", GST_PROPS_INT(3) + ); + break; + + case GST_MAKE_FOURCC('d','i','v','x'): + case GST_MAKE_FOURCC('D','I','V','X'): + case GST_MAKE_FOURCC('D','X','5','0'): + caps = GST_CAPS_NEW ( + "riff_video_divx45", + "video/x-divx", + "divxversion", GST_PROPS_INT(5) + ); + break; + + case GST_MAKE_FOURCC('X','V','I','D'): + case GST_MAKE_FOURCC('x','v','i','d'): + caps = GST_CAPS_NEW ( + "riff_video_xvid", + "video/x-xvid", + NULL + ); + break; + + case GST_MAKE_FOURCC('M','P','G','4'): + caps = GST_CAPS_NEW ( + "riff_video_msmpeg41", + "video/x-msmpeg", + "msmpegversion", GST_PROPS_INT (41) + ); + break; + + case GST_MAKE_FOURCC('M','P','4','2'): + caps = GST_CAPS_NEW ( + "riff_video_msmpeg42", + "video/x-msmpeg", + "msmpegversion", GST_PROPS_INT (42) + ); + break; + + case GST_MAKE_FOURCC('M','P','4','3'): + caps = GST_CAPS_NEW ( + "riff_video_msmpeg43", + "video/x-msmpeg", + "msmpegversion", GST_PROPS_INT (43) + ); + break; + + case GST_MAKE_FOURCC('3','I','V','1'): + case GST_MAKE_FOURCC('3','I','V','2'): + caps = GST_CAPS_NEW ( + "riff_video_3ivx", + "video/x-3ivx", + NULL + ); + break; + + case GST_MAKE_FOURCC('D','V','S','D'): + case GST_MAKE_FOURCC('d','v','s','d'): + caps = GST_CAPS_NEW ( + "riff_video_dv", + "video/x-dv", + "systemstream", GST_PROPS_BOOLEAN (FALSE) + ); + break; + + case GST_MAKE_FOURCC('W','M','V','1'): + caps = GST_CAPS_NEW ( + "riff_video_wmv1", + "video/x-wmv", + "wmvversion", GST_PROPS_INT (1) + ); + break; + + case GST_MAKE_FOURCC('W','M','V','2'): + caps = GST_CAPS_NEW ( + "riff_video_wmv2", + "video/x-wmv", + "wmvversion", GST_PROPS_INT (2) + ); + break; + + default: + GST_WARNING ("Unkown video fourcc " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (codec_fcc)); + break; + } + + /* add general properties */ + if (caps != NULL) { + GstPropsEntry *framerate, *width, *height; + + if (strh != NULL) { + gfloat fps = 1. * strh->rate / strh->scale; + + framerate = gst_props_entry_new ("framerate", + GST_PROPS_FLOAT (fps)); + } else { + framerate = gst_props_entry_new ("framerate", + GST_PROPS_FLOAT_RANGE (0., G_MAXFLOAT)); + } + + if (strf != NULL) { + width = gst_props_entry_new ("width", + GST_PROPS_INT (strf->width)); + height = gst_props_entry_new ("height", + GST_PROPS_INT (strf->height)); + } else { + width = gst_props_entry_new ("width", + GST_PROPS_INT_RANGE (16, 4096)); + height = gst_props_entry_new ("height", + GST_PROPS_INT_RANGE (16, 4096)); + } + + if (!caps->properties) + caps->properties = gst_props_empty_new (); + + gst_props_add_entry (caps->properties, width); + gst_props_add_entry (caps->properties, height); + gst_props_add_entry (caps->properties, framerate); + } + + return caps; +} + +GstCaps * +gst_riff_create_audio_caps (guint16 codec_id, + gst_riff_strh *strh, + gst_riff_strf_auds *strf) +{ + GstCaps *caps = NULL; + + switch (codec_id) { + case GST_RIFF_WAVE_FORMAT_MPEGL3: /* mp3 */ + caps = GST_CAPS_NEW ("riff_audio_mp1l3", + "audio/mpeg", + "layer", GST_PROPS_INT (3)); + break; + + case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */ + caps = GST_CAPS_NEW ("riff_audio_mp1l12", + "audio/mpeg", + "layer", GST_PROPS_INT (2)); + break; + + case GST_RIFF_WAVE_FORMAT_PCM: /* PCM/wav */ { + GstPropsEntry *width = NULL, *depth = NULL, *signedness = NULL; + + if (strf != NULL) { + gint ba = GUINT16_FROM_LE (strf->blockalign); + gint ch = GUINT16_FROM_LE (strf->channels); + gint ws = GUINT16_FROM_LE (strf->size); + + width = gst_props_entry_new ("width", + GST_PROPS_INT (ba * 8 / ch)); + depth = gst_props_entry_new ("depth", + GST_PROPS_INT (ws)); + signedness = gst_props_entry_new ("signed", + GST_PROPS_BOOLEAN (ws != 8)); + } else { + signedness = gst_props_entry_new ("signed", + GST_PROPS_LIST ( + GST_PROPS_BOOLEAN (TRUE), + GST_PROPS_BOOLEAN (FALSE))); + width = gst_props_entry_new ("width", + GST_PROPS_LIST ( + GST_PROPS_INT (8), + GST_PROPS_INT (16))); + depth = gst_props_entry_new ("depth", + GST_PROPS_LIST ( + GST_PROPS_INT (8), + GST_PROPS_INT (16))); + } + + caps = GST_CAPS_NEW ("riff_audio_pcm", + "audio/x-raw-int", + "endianness", + GST_PROPS_INT (G_LITTLE_ENDIAN)); + gst_props_add_entry (caps->properties, width); + gst_props_add_entry (caps->properties, depth); + gst_props_add_entry (caps->properties, signedness); + + } + break; + + case GST_RIFF_WAVE_FORMAT_MULAW: + if (strf != NULL && strf->size != 8) { + GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.", + strf->size); + } + caps = GST_CAPS_NEW ("riff_audio_mulaw", + "audio/x-mulaw", + NULL); + break; + + case GST_RIFF_WAVE_FORMAT_ALAW: + if (strf != NULL && strf->size != 8) { + GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.", + strf->size); + } + caps = GST_CAPS_NEW ("riff_audio_alaw", + "audio/x-alaw", + NULL); + break; + + case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */ + case GST_RIFF_WAVE_FORMAT_VORBIS2: /* ogg/vorbis mode 2 */ + case GST_RIFF_WAVE_FORMAT_VORBIS3: /* ogg/vorbis mode 3 */ + case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS: /* ogg/vorbis mode 1+ */ + case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS: /* ogg/vorbis mode 2+ */ + case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS: /* ogg/vorbis mode 3+ */ + caps = GST_CAPS_NEW ("riff_audio_vorbis", + "audio/x-vorbis", + NULL); + break; + + case GST_RIFF_WAVE_FORMAT_A52: + caps = GST_CAPS_NEW ("riff_audio_ac3", + "audio/x-ac3", + NULL); + break; + + default: + GST_WARNING ("Unkown audio tag 0x%04x", + codec_id); + break; + } + + if (caps != NULL) { + GstPropsEntry *samplerate, *channels; + + if (strf != NULL) { + samplerate = gst_props_entry_new ("rate", + GST_PROPS_INT (strf->rate)); + channels = gst_props_entry_new ("channels", + GST_PROPS_INT (strf->channels)); + } else { + samplerate = gst_props_entry_new ("rate", + GST_PROPS_INT_RANGE (8000, 96000)); + channels = gst_props_entry_new ("channels", + GST_PROPS_INT_RANGE (1, 2)); + } + + if (!caps->properties) + caps->properties = gst_props_empty_new (); + + gst_props_add_entry (caps->properties, samplerate); + gst_props_add_entry (caps->properties, channels); + } + + return caps; +} + +GstCaps * +gst_riff_create_iavs_caps (guint32 codec_fcc, + gst_riff_strh *strh, + gst_riff_strf_iavs *strf) +{ + GstCaps *caps = NULL; + + switch (codec_fcc) { + /* is this correct? */ + case GST_MAKE_FOURCC ('D','V','S','D'): + case GST_MAKE_FOURCC ('d','v','s','d'): + caps = GST_CAPS_NEW ("riff_iavs_dv", + "video/x-dv", + "systemstream", GST_PROPS_BOOLEAN (TRUE)); + + default: + GST_WARNING ("Unkown IAVS fourcc " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (codec_fcc)); + break; + } + + return caps; +} + +/* + * Functions below are for template caps. All is variable. + */ + +GstCaps * +gst_riff_create_video_template_caps (void) +{ + guint32 tags[] = { + GST_MAKE_FOURCC ('I','4','2','0'), + GST_MAKE_FOURCC ('Y','U','Y','2'), + GST_MAKE_FOURCC ('M','J','P','G'), + GST_MAKE_FOURCC ('D','V','S','D'), + GST_MAKE_FOURCC ('W','M','V','1'), + GST_MAKE_FOURCC ('W','M','V','2'), + GST_MAKE_FOURCC ('M','P','G','4'), + GST_MAKE_FOURCC ('M','P','4','2'), + GST_MAKE_FOURCC ('M','P','4','3'), + GST_MAKE_FOURCC ('H','F','Y','U'), + GST_MAKE_FOURCC ('D','I','V','3'), + GST_MAKE_FOURCC ('M','P','E','G'), + GST_MAKE_FOURCC ('H','2','6','3'), + GST_MAKE_FOURCC ('D','I','V','X'), + GST_MAKE_FOURCC ('X','V','I','D'), + GST_MAKE_FOURCC ('3','I','V','1'), + /* FILL ME */ + 0 + }; + guint i; + GstCaps *caps = NULL, *one; + + for (i = 0; tags[i] != 0; i++) { + one = gst_riff_create_video_caps (tags[i], NULL, NULL); + if (one) + caps = gst_caps_append (caps, one); + } + + return caps; +} + +GstCaps * +gst_riff_create_audio_template_caps (void) +{ + guint16 tags[] = { + GST_RIFF_WAVE_FORMAT_MPEGL3, + GST_RIFF_WAVE_FORMAT_MPEGL12, + GST_RIFF_WAVE_FORMAT_PCM, + GST_RIFF_WAVE_FORMAT_VORBIS1, + GST_RIFF_WAVE_FORMAT_A52, + GST_RIFF_WAVE_FORMAT_ALAW, + GST_RIFF_WAVE_FORMAT_MULAW, + /* FILL ME */ + 0 + }; + guint i; + GstCaps *caps = NULL, *one; + + for (i = 0; tags[i] != 0; i++) { + one = gst_riff_create_audio_caps (tags[i], NULL, NULL); + if (one) + caps = gst_caps_append (caps, one); + } + + return caps; +} + +GstCaps * +gst_riff_create_iavs_template_caps (void) +{ + guint32 tags[] = { + GST_MAKE_FOURCC ('D','V','S','D'), + /* FILL ME */ + 0 + }; + guint i; + GstCaps *caps = NULL, *one; + + for (i = 0; tags[i] != 0; i++) { + one = gst_riff_create_iavs_caps (tags[i], NULL, NULL); + if (one) + caps = gst_caps_append (caps, one); + } + + return caps; +} diff --git a/gst-libs/gst/riff/riff-media.h b/gst-libs/gst/riff/riff-media.h new file mode 100644 index 00000000..256ed947 --- /dev/null +++ b/gst-libs/gst/riff/riff-media.h @@ -0,0 +1,55 @@ +/* GStreamer RIFF I/O + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * riff-media.h: RIFF-id to/from caps routines + * + * 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 __GST_RIFF_MEDIA_H__ +#define __GST_RIFF_MEDIA_H__ + +#include <glib.h> +#include <gst/gst.h> +#include "riff-ids.h" + +G_BEGIN_DECLS + +/* + * Create one caps. strh/strf can be NULL (for non-fixed caps). + */ + +GstCaps *gst_riff_create_video_caps (guint32 codec_fcc, + gst_riff_strh *strh, + gst_riff_strf_vids *strf); +GstCaps *gst_riff_create_audio_caps (guint16 codec_id, + gst_riff_strh *strh, + gst_riff_strf_auds *strf); +GstCaps *gst_riff_create_iavs_caps (guint32 codec_fcc, + gst_riff_strh *strh, + gst_riff_strf_iavs *strf); + +/* + * Create template caps (includes all known types). + */ + +GstCaps *gst_riff_create_video_template_caps (void); +GstCaps *gst_riff_create_audio_template_caps (void); +GstCaps *gst_riff_create_iavs_template_caps (void); + +G_END_DECLS + +#endif /* __GST_RIFF_READ_H__ */ diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c new file mode 100644 index 00000000..c264cced --- /dev/null +++ b/gst-libs/gst/riff/riff-read.c @@ -0,0 +1,877 @@ +/* GStreamer RIFF I/O + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * riff-read.c: RIFF input file parsing + * + * 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 "riff-ids.h" +#include "riff-read.h" + +enum { + ARG_0, + ARG_METADATA + /* FILL ME */ +}; + +static void gst_riff_read_class_init (GstRiffReadClass *klass); +static void gst_riff_read_init (GstRiffRead *riff); +static void gst_riff_read_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static GstElementStateReturn + gst_riff_read_change_state (GstElement *element); + +static GstElementClass *parent_class = NULL; + +GType +gst_riff_read_get_type (void) +{ + static GType gst_riff_read_type = 0; + + if (!gst_riff_read_type) { + static const GTypeInfo gst_riff_read_info = { + sizeof (GstRiffReadClass), + NULL, + NULL, + (GClassInitFunc) gst_riff_read_class_init, + NULL, + NULL, + sizeof (GstRiffRead), + 0, + (GInstanceInitFunc) gst_riff_read_init, + }; + + gst_riff_read_type = + g_type_register_static (GST_TYPE_ELEMENT, "GstRiffRead", + &gst_riff_read_info, 0); + } + + return gst_riff_read_type; +} + +static void +gst_riff_read_class_init (GstRiffReadClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + + g_object_class_install_property (gobject_class, ARG_METADATA, + g_param_spec_boxed ("metadata", "Metadata", "Metadata", + GST_TYPE_CAPS, G_PARAM_READABLE)); + + parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + + gobject_class->get_property = gst_riff_read_get_property; + + gstelement_class->change_state = gst_riff_read_change_state; +} + +static void +gst_riff_read_init (GstRiffRead *riff) +{ + riff->sinkpad = NULL; + riff->bs = NULL; + riff->level = NULL; + riff->metadata = NULL; +} + +static void +gst_riff_read_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GstRiffRead *riff = GST_RIFF_READ (object); + + switch (prop_id) { + case ARG_METADATA: + g_value_set_boxed (value, riff->metadata); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstElementStateReturn +gst_riff_read_change_state (GstElement *element) +{ + GstRiffRead *riff = GST_RIFF_READ (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_READY_TO_PAUSED: + if (!riff->sinkpad) + return GST_STATE_FAILURE; + riff->bs = gst_bytestream_new (riff->sinkpad); + break; + case GST_STATE_PAUSED_TO_READY: + gst_caps_replace (&riff->metadata, NULL); + gst_bytestream_destroy (riff->bs); + while (riff->level) { + GstRiffLevel *level = riff->level->data; + + riff->level = g_list_remove (riff->level, level); + g_free (level); + } + break; + default: + break; + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} + +/* + * Return: the amount of levels in the hierarchy that the + * current element lies higher than the previous one. + * The opposite isn't done - that's auto-done using list + * element reading. + */ + +static guint +gst_riff_read_element_level_up (GstRiffRead *riff) +{ + guint num = 0; + guint64 pos = gst_bytestream_tell (riff->bs); + + while (riff->level != NULL) { + GList *last = g_list_last (riff->level); + GstRiffLevel *level = last->data; + + if (pos >= level->start + level->length) { + riff->level = g_list_remove (riff->level, level); + g_free (level); + num++; + } else + break; + } + + return num; +} + +/* + * Read the next tag plus length (may be NULL). Return + * TRUE on success or FALSE on failure. + */ + +static gboolean +gst_riff_peek_head (GstRiffRead *riff, + guint32 *tag, + guint32 *length, + guint *level_up) +{ + guint8 *data; + + /* read */ + if (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8) { + GstEvent *event = NULL; + guint32 remaining; + + /* Here, we might encounter EOS */ + gst_bytestream_get_status (riff->bs, &remaining, &event); + if (event && GST_EVENT_TYPE (event) == GST_EVENT_EOS) { + gst_pad_event_default (riff->sinkpad, event); + } else { + gst_event_unref (event); + gst_element_error (GST_ELEMENT (riff), "Read error"); + } + return FALSE; + } + + /* parse tag + length (if wanted) */ + *tag = GUINT32_FROM_LE (((guint32 *) data)[0]); + if (length) + *length = GUINT32_FROM_LE (((guint32 *) data)[1]); + + /* level */ + if (level_up) + *level_up = gst_riff_read_element_level_up (riff); + + return TRUE; +} + +/* + * Read: the actual data (plus alignment and flush). + * Return: the data, as a GstBuffer. + */ + +static GstBuffer * +gst_riff_read_element_data (GstRiffRead *riff, + guint length) +{ + GstBuffer *buf = NULL; + + if (gst_bytestream_peek (riff->bs, &buf, length) != length) { + gst_element_error (GST_ELEMENT (riff), "Read error"); + if (buf) + gst_buffer_unref (buf); + return NULL; + } + + /* we need 16-bit alignment */ + if (length & 1) + length++; + + gst_bytestream_flush (riff->bs, length); + + return buf; +} + +/* + * Seek. + */ + +GstEvent * +gst_riff_read_seek (GstRiffRead *riff, + guint64 offset) +{ + guint64 length = gst_bytestream_length (riff->bs); + guint32 remaining; + GstEvent *event; + guchar *data; + + /* hack for AVI files with broken idx1 size chunk markers */ + if (offset > length) + offset = length; + + /* first, flush remaining buffers */ + gst_bytestream_get_status (riff->bs, &remaining, &event); + if (event) { + g_warning ("Unexpected event before seek"); + gst_event_unref (event); + } + if (remaining) + gst_bytestream_flush_fast (riff->bs, remaining); + + /* now seek */ + if (!gst_bytestream_seek (riff->bs, offset, GST_SEEK_METHOD_SET)) { + gst_element_error (GST_ELEMENT (riff), "Seek failed"); + return NULL; + } + + /* and now, peek a new byte. This will fail because there's a + * pending event. Then, take the event and return it. */ + if (gst_bytestream_peek_bytes (riff->bs, &data, 1)) + g_warning ("Unexpected data after seek"); + + /* get the discont event and return */ + gst_bytestream_get_status (riff->bs, &remaining, &event); + if (!event || GST_EVENT_TYPE (event) != GST_EVENT_DISCONTINUOUS) { + gst_element_error (GST_ELEMENT (riff), + "No discontinuity event after seek"); + if (event) + gst_event_unref (event); + return NULL; + } + + return event; +} + +/* + * Gives the tag of the next RIFF element. + */ + +guint32 +gst_riff_peek_tag (GstRiffRead *riff, + guint *level_up) +{ + guint32 tag; + + if (!gst_riff_peek_head (riff, &tag, NULL, level_up)) + return 0; + + return tag; +} + +/* + * Gives the tag of the next LIST/RIFF element. + */ + +guint32 +gst_riff_peek_list (GstRiffRead *riff) +{ + guint32 lst; + guint8 *data; + + if (!gst_riff_peek_head (riff, &lst, NULL, NULL)) + return FALSE; + if (lst != GST_RIFF_TAG_LIST) { + g_warning ("Not a LIST object"); + return 0; + } + + if (gst_bytestream_peek_bytes (riff->bs, &data, 12) != 12) { + gst_element_error (GST_ELEMENT (riff), "Read error"); + return 0; + } + + return GUINT32_FROM_LE (((guint32 *) data)[2]); +} + +/* + * Don't read data. + */ + +gboolean +gst_riff_read_skip (GstRiffRead *riff) +{ + guint32 tag, length; + GstEvent *event; + guint32 remaining; + + if (!gst_riff_peek_head (riff, &tag, &length, NULL)) + return FALSE; + + /* 16-bit alignment */ + if (length & 1) + length++; + + /* header itself */ + length += 8; + + /* see if we have that much data available */ + gst_bytestream_get_status (riff->bs, &remaining, &event); + if (event) { + g_warning ("Unexpected event in skip"); + gst_event_unref (event); + } + + /* yes */ + if (remaining >= length) { + gst_bytestream_flush_fast (riff->bs, length); + return TRUE; + } + + /* no */ + if (!(event = gst_riff_read_seek (riff, + gst_bytestream_tell (riff->bs) + length))) + return FALSE; + + gst_event_unref (event); + + return TRUE; +} + +/* + * Read any type of data. + */ + +gboolean +gst_riff_read_data (GstRiffRead *riff, + guint32 *tag, + GstBuffer **buf) +{ + guint32 length; + + if (!gst_riff_peek_head (riff, tag, &length, NULL)) + return FALSE; + gst_bytestream_flush_fast (riff->bs, 8); + + return ((*buf = gst_riff_read_element_data (riff, length)) != NULL); +} + +/* + * Read a string. + */ + +gboolean +gst_riff_read_ascii (GstRiffRead *riff, + guint32 *tag, + gchar **str) +{ + GstBuffer *buf; + + if (!gst_riff_read_data (riff, tag, &buf)) + return FALSE; + + *str = g_malloc (GST_BUFFER_SIZE (buf) + 1); + memcpy (*str, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + (*str)[GST_BUFFER_SIZE (buf)] = '\0'; + + gst_buffer_unref (buf); + + return TRUE; +} + +/* + * Read media structs. + */ + +gboolean +gst_riff_read_strh (GstRiffRead *riff, + gst_riff_strh **header) +{ + guint32 tag; + GstBuffer *buf; + gst_riff_strh *strh; + + if (!gst_riff_read_data (riff, &tag, &buf)) + return FALSE; + + if (tag != GST_RIFF_TAG_strh) { + g_warning ("Not a strh chunk"); + gst_buffer_unref (buf); + return FALSE; + } + if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strh)) { + g_warning ("Too small strh (%d available, %d needed)", + GST_BUFFER_SIZE (buf), sizeof (gst_riff_strh)); + gst_buffer_unref (buf); + return FALSE; + } + + strh = g_memdup (GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + gst_buffer_unref (buf); + +#if (G_BYTE_ORDER == G_BIG_ENDIAN) + strh->type = GUINT32_FROM_LE (strh->type); + strh->fcc_handler = GUINT32_FROM_LE (strh->fcc_handler); + strh->flags = GUINT32_FROM_LE (strh->flags); + strh->priority = GUINT32_FROM_LE (strh->priority); + strh->init_frames = GUINT32_FROM_LE (strh->init_frames); + strh->scale = GUINT32_FROM_LE (strh->scale); + strh->rate = GUINT32_FROM_LE (strh->rate); + strh->start = GUINT32_FROM_LE (strh->start); + strh->length = GUINT32_FROM_LE (strh->length); + strh->bufsize = GUINT32_FROM_LE (strh->bufsize); + strh->quality = GUINT32_FROM_LE (strh->quality); + strh->samplesize = GUINT32_FROM_LE (strh->samplesize); +#endif + + /* avoid divisions by zero */ + if (!strh->scale) + strh->scale = 1; + if (!strh->rate) + strh->rate = 1; + + /* debug */ + GST_INFO ("strh tag found"); + GST_INFO (" type " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (strh->type)); + GST_INFO (" fcc_handler " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (strh->fcc_handler)); + GST_INFO (" flags 0x%08x", strh->flags); + GST_INFO (" priority %d", strh->priority); + GST_INFO (" init_frames %d", strh->init_frames); + GST_INFO (" scale %d", strh->scale); + GST_INFO (" rate %d", strh->rate); + GST_INFO (" start %d", strh->start); + GST_INFO (" length %d", strh->length); + GST_INFO (" bufsize %d", strh->bufsize); + GST_INFO (" quality %d", strh->quality); + GST_INFO (" samplesize %d", strh->samplesize); + + *header = strh; + + return TRUE; +} + +gboolean +gst_riff_read_strf_vids (GstRiffRead *riff, + gst_riff_strf_vids **header) +{ + guint32 tag; + GstBuffer *buf; + gst_riff_strf_vids *strf; + + if (!gst_riff_read_data (riff, &tag, &buf)) + return FALSE; + + if (tag != GST_RIFF_TAG_strf) { + g_warning ("Not a strf chunk"); + gst_buffer_unref (buf); + return FALSE; + } + if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_vids)) { + g_warning ("Too small strf_vids (%d available, %d needed)", + GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_vids)); + gst_buffer_unref (buf); + return FALSE; + } + + strf = g_memdup (GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + +#if (G_BYTE_ORDER == G_BIG_ENDIAN) + strf->size = GUINT32_FROM_LE (strf->size); + strf->width = GUINT32_FROM_LE (strf->width); + strf->height = GUINT32_FROM_LE (strf->height); + strf->planes = GUINT16_FROM_LE (strf->planes); + strf->bit_cnt = GUINT16_FROM_LE (strf->bit_cnt); + strf->compression = GUINT32_FROM_LE (strf->compression); + strf->image_size = GUINT32_FROM_LE (strf->image_size); + strf->xpels_meter = GUINT32_FROM_LE (strf->xpels_meter); + strf->ypels_meter = GUINT32_FROM_LE (strf->ypels_meter); + strf->num_colors = GUINT32_FROM_LE (strf->num_colors); + strf->imp_colors = GUINT32_FROM_LE (strf->imp_colors); +#endif + + /* size checking */ + if (strf->size > GST_BUFFER_SIZE (buf)) { + g_warning ("strf_vids header gave %d bytes data, only %d available", + strf->size, GST_BUFFER_SIZE (buf)); + strf->size = GST_BUFFER_SIZE (buf); + } + + /* debug */ + GST_INFO ("strf tag found in context vids:"); + GST_INFO (" size %d", strf->size); + GST_INFO (" width %d", strf->width); + GST_INFO (" height %d", strf->height); + GST_INFO (" planes %d", strf->planes); + GST_INFO (" bit_cnt %d", strf->bit_cnt); + GST_INFO (" compression " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (strf->compression)); + GST_INFO (" image_size %d", strf->image_size); + GST_INFO (" xpels_meter %d", strf->xpels_meter); + GST_INFO (" ypels_meter %d", strf->ypels_meter); + GST_INFO (" num_colors %d", strf->num_colors); + GST_INFO (" imp_colors %d", strf->imp_colors); + + gst_buffer_unref (buf); + + *header = strf; + + return TRUE; +} + +gboolean +gst_riff_read_strf_auds (GstRiffRead *riff, + gst_riff_strf_auds **header) +{ + guint32 tag; + GstBuffer *buf; + gst_riff_strf_auds *strf; + + if (!gst_riff_read_data (riff, &tag, &buf)) + return FALSE; + + if (tag != GST_RIFF_TAG_strf) { + g_warning ("Not a strf chunk"); + gst_buffer_unref (buf); + return FALSE; + } + if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_auds)) { + g_warning ("Too small strf_auds (%d available, %d needed)", + GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_auds)); + gst_buffer_unref (buf); + return FALSE; + } + + strf = g_memdup (GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + +#if (G_BYTE_ORDER == G_BIG_ENDIAN) + strf->format = GUINT16_FROM_LE (strf->format); + strf->channels = GUINT16_FROM_LE (strf->channels); + strf->rate = GUINT32_FROM_LE (strf->rate); + strf->av_bps = GUINT32_FROM_LE (strf->av_bps); + strf->blockalign = GUINT16_FROM_LE (strf->blockalign); + strf->size = GUINT16_FROM_LE (strf->size); +#endif + + /* debug */ + GST_INFO ("strf tag found in context auds:"); + GST_INFO (" format %d", strf->format); + GST_INFO (" channels %d", strf->channels); + GST_INFO (" rate %d", strf->rate); + GST_INFO (" av_bps %d", strf->av_bps); + GST_INFO (" blockalign %d", strf->blockalign); + GST_INFO (" size %d", strf->size); /* wordsize, not extrasize! */ + + gst_buffer_unref (buf); + + *header = strf; + + return TRUE; +} + +gboolean +gst_riff_read_strf_iavs (GstRiffRead *riff, + gst_riff_strf_iavs **header) +{ + guint32 tag; + GstBuffer *buf; + gst_riff_strf_iavs *strf; + + if (!gst_riff_read_data (riff, &tag, &buf)) + return FALSE; + + if (tag != GST_RIFF_TAG_strf) { + g_warning ("Not a strf chunk"); + gst_buffer_unref (buf); + return FALSE; + } + if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_iavs)) { + g_warning ("Too small strf_iavs (%d available, %d needed)", + GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_iavs)); + gst_buffer_unref (buf); + return FALSE; + } + + strf = g_memdup (GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + gst_buffer_unref (buf); + +#if (G_BYTE_ORDER == G_BIG_ENDIAN) + strf->DVAAuxSrc = GUINT32_FROM_LE (strf->DVAAuxSrc); + strf->DVAAuxCtl = GUINT32_FROM_LE (strf->DVAAuxCtl); + strf->DVAAuxSrc1 = GUINT32_FROM_LE (strf->DVAAuxSrc1); + strf->DVAAuxCtl1 = GUINT32_FROM_LE (strf->DVAAuxCtl1); + strf->DVVAuxSrc = GUINT32_FROM_LE (strf->DVVAuxSrc); + strf->DVVAuxCtl = GUINT32_FROM_LE (strf->DVVAuxCtl); + strf->DVReserved1 = GUINT32_FROM_LE (strf->DVReserved1); + strf->DVReserved2 = GUINT32_FROM_LE (strf->DVReserved2); +#endif + + /* debug */ + GST_INFO ("strf tag found in context iavs"); + GST_INFO (" DVAAuxSrc %08x", strf->DVAAuxSrc); + GST_INFO (" DVAAuxCtl %08x", strf->DVAAuxCtl); + GST_INFO (" DVAAuxSrc1 %08x", strf->DVAAuxSrc1); + GST_INFO (" DVAAuxCtl1 %08x", strf->DVAAuxCtl1); + GST_INFO (" DVVAuxSrc %08x", strf->DVVAuxSrc); + GST_INFO (" DVVAuxCtl %08x", strf->DVVAuxCtl); + GST_INFO (" DVReserved1 %08x", strf->DVReserved1); + GST_INFO (" DVReserved2 %08x", strf->DVReserved2); + + *header = strf; + + return TRUE; +} + +/* + * Read a list. + */ + +gboolean +gst_riff_read_list (GstRiffRead *riff, + guint32 *tag) +{ + guint32 length, lst; + GstRiffLevel *level; + guint8 *data; + + if (!gst_riff_peek_head (riff, &lst, &length, NULL)) + return FALSE; + if (lst != GST_RIFF_TAG_LIST) { + g_warning ("Not a LIST object"); + return FALSE; + } + gst_bytestream_flush_fast (riff->bs, 8); + if (gst_bytestream_peek_bytes (riff->bs, &data, 4) != 4) { + gst_element_error (GST_ELEMENT (riff), "Read error"); + return FALSE; + } + gst_bytestream_flush_fast (riff->bs, 4); + *tag = GUINT32_FROM_LE (* (guint32 *) data); + + /* remember level */ + level = g_new (GstRiffLevel, 1); + level->start = gst_bytestream_tell (riff->bs); + level->length = length - 4; + riff->level = g_list_append (riff->level, level); + + return TRUE; +} + +/* + * Utility function for reading metadata in a RIFF file. + */ + +gboolean +gst_riff_read_info (GstRiffRead *riff) +{ + guint32 tag; + guint64 end; + GstRiffLevel *level; + GList *last; + gchar *name, *type; + GstProps *props; + + /* What we're doing here is ugly (oh no!); we look + * at our LIST tag size and assure that we do not + * cross boundaries. This is to maintain the level + * counter for the client app. */ + last = g_list_last (riff->level); + level = last->data; + riff->level = g_list_remove (riff->level, level); + end = level->start + level->length; + g_free (level); + + props = gst_props_empty_new (); + + while (gst_bytestream_tell (riff->bs) < end) { + if (!gst_riff_peek_head (riff, &tag, NULL, NULL)) { + gst_props_unref (props); + return FALSE; + } + + /* find out the type of metadata */ + switch (tag) { + case GST_RIFF_INFO_IARL: + type = "Location"; + break; + case GST_RIFF_INFO_IART: + type = "Artist"; + break; + case GST_RIFF_INFO_ICMS: + type = "Commissioner"; + break; + case GST_RIFF_INFO_ICMT: + type = "Comment"; + break; + case GST_RIFF_INFO_ICOP: + type = "Copyright"; + break; + case GST_RIFF_INFO_ICRD: + type = "Creation Date"; + break; + case GST_RIFF_INFO_ICRP: + type = "Cropped"; + break; + case GST_RIFF_INFO_IDIM: + type = "Dimensions"; + break; + case GST_RIFF_INFO_IDPI: + type = "Dots per Inch"; + break; + case GST_RIFF_INFO_IENG: + type = "Engineer"; + break; + case GST_RIFF_INFO_IGNR: + type = "Genre"; + break; + case GST_RIFF_INFO_IKEY: + type = "Keywords"; + break; + case GST_RIFF_INFO_ILGT: + type = "Lightness"; + break; + case GST_RIFF_INFO_IMED: + type = "Medium"; + break; + case GST_RIFF_INFO_INAM: + type = "Title"; /* "Name" */ + break; + case GST_RIFF_INFO_IPLT: + type = "Palette"; + break; + case GST_RIFF_INFO_IPRD: + type = "Product"; + break; + case GST_RIFF_INFO_ISBJ: + type = "Subject"; + break; + case GST_RIFF_INFO_ISFT: + type = "Encoder"; /* "Software" */ + break; + case GST_RIFF_INFO_ISHP: + type = "Sharpness"; + break; + case GST_RIFF_INFO_ISRC: + type = "Source"; + break; + case GST_RIFF_INFO_ISRF: + type = "Source Form"; + break; + case GST_RIFF_INFO_ITCH: + type = "Technician"; + break; + default: + type = NULL; + GST_WARNING ("Unknown INFO (metadata) tag entry " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (tag)); + break; + } + + if (type) { + GstPropsEntry *entry; + + if (!gst_riff_read_ascii (riff, &tag, &name)) { + gst_props_unref (props); + return FALSE; + } + + entry = gst_props_entry_new (type, GST_PROPS_STRING (name)); + gst_props_add_entry (props, entry); + } else { + gst_riff_read_skip (riff); + } + } + + /* let the world know about this wonderful thing */ + gst_props_debug (props); + gst_caps_replace_sink (&riff->metadata, + gst_caps_new ("riff_metadata", + "application/x-gst-metadata", + props)); + g_object_notify (G_OBJECT (riff), "metadata"); + + return TRUE; +} + +/* + * Read RIFF header and document type. + */ + +gboolean +gst_riff_read_header (GstRiffRead *riff, + guint32 *doctype) +{ + GstRiffLevel *level; + guint32 tag, length; + guint8 *data; + + /* We ignore size for openDML-2.0 support */ + if (!gst_riff_peek_head (riff, &tag, &length, NULL)) + return FALSE; + if (tag != GST_RIFF_TAG_RIFF) { + GST_WARNING ("Not a RIFF file"); + return FALSE; + } + gst_bytestream_flush_fast (riff->bs, 8); + + /* doctype */ + if (gst_bytestream_peek_bytes (riff->bs, &data, 4) != 4) { + gst_element_error (GST_ELEMENT (riff), "Read error"); + return FALSE; + } + gst_bytestream_flush_fast (riff->bs, 4); + *doctype = GUINT32_FROM_LE (* (guint32 *) data); + + /* remember level */ + level = g_new (GstRiffLevel, 1); + level->start = gst_bytestream_tell (riff->bs); + level->length = length - 4; + riff->level = g_list_append (riff->level, level); + + return TRUE; +} diff --git a/gst-libs/gst/riff/riff.c b/gst-libs/gst/riff/riff.c index 53a922a6..9c0ce2ae 100644 --- a/gst-libs/gst/riff/riff.c +++ b/gst-libs/gst/riff/riff.c @@ -1,5 +1,7 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> +/* GStreamer RIFF I/O + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * riff.c: plugin registering * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -18,22 +20,22 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif -#include <riff.h> +#include <gst/gst.h> static gboolean plugin_init (GstPlugin *plugin) { - return TRUE; + return gst_library_load ("gstbytestream"); } GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, - "gstriff", - "RIFF convenience routines", + "riff", + "RIFF I/O functions", plugin_init, VERSION, GST_LICENSE, diff --git a/gst-libs/gst/riff/riff.h b/gst-libs/gst/riff/riff.h deleted file mode 100644 index d8f57735..00000000 --- a/gst-libs/gst/riff/riff.h +++ /dev/null @@ -1,448 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * - * 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 __GST_RIFF_H__ -#define __GST_RIFF_H__ - - -#include <gst/gst.h> - -typedef enum { - GST_RIFF_OK = 0, - GST_RIFF_ENOTRIFF = -1, - GST_RIFF_EINVAL = -2, - GST_RIFF_ENOMEM = -3 -} GstRiffReturn; - -/* states */ -typedef enum { - GST_RIFF_STATE_INITIAL = 0, - GST_RIFF_STATE_HASAVIH = 1, - GST_RIFF_STATE_HASSTRH = 2, - GST_RIFF_STATE_HASSTRF = 3, - GST_RIFF_STATE_MOVI = 4 -} GstRiffParserState; - -#define MAKE_FOUR_CC(a,b,c,d) GST_MAKE_FOURCC(a,b,c,d) - -/* RIFF types */ -#define GST_RIFF_RIFF_WAVE MAKE_FOUR_CC('W','A','V','E') -#define GST_RIFF_RIFF_AVI MAKE_FOUR_CC('A','V','I',' ') - -/* tags */ -#define GST_RIFF_TAG_RIFF MAKE_FOUR_CC('R','I','F','F') -#define GST_RIFF_TAG_RIFX MAKE_FOUR_CC('R','I','F','X') -#define GST_RIFF_TAG_LIST MAKE_FOUR_CC('L','I','S','T') -#define GST_RIFF_TAG_avih MAKE_FOUR_CC('a','v','i','h') -#define GST_RIFF_TAG_strd MAKE_FOUR_CC('s','t','r','d') -#define GST_RIFF_TAG_strn MAKE_FOUR_CC('s','t','r','n') -#define GST_RIFF_TAG_strh MAKE_FOUR_CC('s','t','r','h') -#define GST_RIFF_TAG_strf MAKE_FOUR_CC('s','t','r','f') -#define GST_RIFF_TAG_vedt MAKE_FOUR_CC('v','e','d','t') -#define GST_RIFF_TAG_JUNK MAKE_FOUR_CC('J','U','N','K') -#define GST_RIFF_TAG_idx1 MAKE_FOUR_CC('i','d','x','1') -#define GST_RIFF_TAG_dmlh MAKE_FOUR_CC('d','m','l','h') -/* WAV stuff */ -#define GST_RIFF_TAG_fmt MAKE_FOUR_CC('f','m','t',' ') -#define GST_RIFF_TAG_data MAKE_FOUR_CC('d','a','t','a') - -/* LIST types */ -#define GST_RIFF_LIST_movi MAKE_FOUR_CC('m','o','v','i') -#define GST_RIFF_LIST_hdrl MAKE_FOUR_CC('h','d','r','l') -#define GST_RIFF_LIST_strl MAKE_FOUR_CC('s','t','r','l') -#define GST_RIFF_LIST_INFO MAKE_FOUR_CC('I','N','F','O') - -/* fcc types */ -#define GST_RIFF_FCC_vids MAKE_FOUR_CC('v','i','d','s') -#define GST_RIFF_FCC_auds MAKE_FOUR_CC('a','u','d','s') -#define GST_RIFF_FCC_pads MAKE_FOUR_CC('p','a','d','s') -#define GST_RIFF_FCC_txts MAKE_FOUR_CC('t','x','t','s') -#define GST_RIFF_FCC_vidc MAKE_FOUR_CC('v','i','d','c') -#define GST_RIFF_FCC_iavs MAKE_FOUR_CC('i','a','v','s') -/* fcc handlers */ -#define GST_RIFF_FCCH_RLE MAKE_FOUR_CC('R','L','E',' ') -#define GST_RIFF_FCCH_msvc MAKE_FOUR_CC('m','s','v','c') -#define GST_RIFF_FCCH_MSVC MAKE_FOUR_CC('M','S','V','C') - -/* INFO types - see http://www.saettler.com/RIFFMCI/riffmci.html */ -#define GST_RIFF_INFO_IARL MAKE_FOUR_CC('I','A','R','L') /* location */ -#define GST_RIFF_INFO_IART MAKE_FOUR_CC('I','A','R','T') /* artist */ -#define GST_RIFF_INFO_ICMS MAKE_FOUR_CC('I','C','M','S') /* commissioned */ -#define GST_RIFF_INFO_ICMT MAKE_FOUR_CC('I','C','M','T') /* comment */ -#define GST_RIFF_INFO_ICOP MAKE_FOUR_CC('I','C','O','P') /* copyright */ -#define GST_RIFF_INFO_ICRD MAKE_FOUR_CC('I','C','R','D') /* creation date */ -#define GST_RIFF_INFO_ICRP MAKE_FOUR_CC('I','C','R','P') /* cropped */ -#define GST_RIFF_INFO_IDIM MAKE_FOUR_CC('I','D','I','M') /* dimensions */ -#define GST_RIFF_INFO_IDPI MAKE_FOUR_CC('I','D','P','I') /* dots-per-inch */ -#define GST_RIFF_INFO_IENG MAKE_FOUR_CC('I','E','N','G') /* engineer(s) */ -#define GST_RIFF_INFO_IGNR MAKE_FOUR_CC('I','G','N','R') /* genre */ -#define GST_RIFF_INFO_IKEY MAKE_FOUR_CC('I','K','E','Y') /* keywords */ -#define GST_RIFF_INFO_ILGT MAKE_FOUR_CC('I','L','G','T') /* lightness */ -#define GST_RIFF_INFO_IMED MAKE_FOUR_CC('I','M','E','D') /* medium */ -#define GST_RIFF_INFO_INAM MAKE_FOUR_CC('I','N','A','M') /* name */ -#define GST_RIFF_INFO_IPLT MAKE_FOUR_CC('I','P','L','T') /* palette setting */ -#define GST_RIFF_INFO_IPRD MAKE_FOUR_CC('I','P','R','D') /* product */ -#define GST_RIFF_INFO_ISBJ MAKE_FOUR_CC('I','S','B','J') /* subject */ -#define GST_RIFF_INFO_ISFT MAKE_FOUR_CC('I','S','F','T') /* software */ -#define GST_RIFF_INFO_ISHP MAKE_FOUR_CC('I','S','H','P') /* sharpness */ -#define GST_RIFF_INFO_ISRC MAKE_FOUR_CC('I','S','R','C') /* source */ -#define GST_RIFF_INFO_ISRF MAKE_FOUR_CC('I','S','R','F') /* source form */ -#define GST_RIFF_INFO_ITCH MAKE_FOUR_CC('I','T','C','H') /* technician(s) */ - -/*********Chunk Names***************/ -#define GST_RIFF_FF00 MAKE_FOUR_CC(0xFF,0xFF,0x00,0x00) -#define GST_RIFF_00 MAKE_FOUR_CC( '0', '0',0x00,0x00) -#define GST_RIFF_01 MAKE_FOUR_CC( '0', '1',0x00,0x00) -#define GST_RIFF_02 MAKE_FOUR_CC( '0', '2',0x00,0x00) -#define GST_RIFF_03 MAKE_FOUR_CC( '0', '3',0x00,0x00) -#define GST_RIFF_04 MAKE_FOUR_CC( '0', '4',0x00,0x00) -#define GST_RIFF_05 MAKE_FOUR_CC( '0', '5',0x00,0x00) -#define GST_RIFF_06 MAKE_FOUR_CC( '0', '6',0x00,0x00) -#define GST_RIFF_07 MAKE_FOUR_CC( '0', '7',0x00,0x00) -#define GST_RIFF_00pc MAKE_FOUR_CC( '0', '0', 'p', 'c') -#define GST_RIFF_01pc MAKE_FOUR_CC( '0', '1', 'p', 'c') -#define GST_RIFF_00dc MAKE_FOUR_CC( '0', '0', 'd', 'c') -#define GST_RIFF_00dx MAKE_FOUR_CC( '0', '0', 'd', 'x') -#define GST_RIFF_00db MAKE_FOUR_CC( '0', '0', 'd', 'b') -#define GST_RIFF_00xx MAKE_FOUR_CC( '0', '0', 'x', 'x') -#define GST_RIFF_00id MAKE_FOUR_CC( '0', '0', 'i', 'd') -#define GST_RIFF_00rt MAKE_FOUR_CC( '0', '0', 'r', 't') -#define GST_RIFF_0021 MAKE_FOUR_CC( '0', '0', '2', '1') -#define GST_RIFF_00iv MAKE_FOUR_CC( '0', '0', 'i', 'v') -#define GST_RIFF_0031 MAKE_FOUR_CC( '0', '0', '3', '1') -#define GST_RIFF_0032 MAKE_FOUR_CC( '0', '0', '3', '2') -#define GST_RIFF_00vc MAKE_FOUR_CC( '0', '0', 'v', 'c') -#define GST_RIFF_00xm MAKE_FOUR_CC( '0', '0', 'x', 'm') -#define GST_RIFF_01wb MAKE_FOUR_CC( '0', '1', 'w', 'b') -#define GST_RIFF_01dc MAKE_FOUR_CC( '0', '1', 'd', 'c') -#define GST_RIFF_00__ MAKE_FOUR_CC( '0', '0', '_', '_') - -/*********VIDEO CODECS**************/ -#define GST_RIFF_cram MAKE_FOUR_CC( 'c', 'r', 'a', 'm') -#define GST_RIFF_CRAM MAKE_FOUR_CC( 'C', 'R', 'A', 'M') -#define GST_RIFF_wham MAKE_FOUR_CC( 'w', 'h', 'a', 'm') -#define GST_RIFF_WHAM MAKE_FOUR_CC( 'W', 'H', 'A', 'M') -#define GST_RIFF_rgb MAKE_FOUR_CC(0x00,0x00,0x00,0x00) -#define GST_RIFF_RGB MAKE_FOUR_CC( 'R', 'G', 'B', ' ') -#define GST_RIFF_rle8 MAKE_FOUR_CC(0x01,0x00,0x00,0x00) -#define GST_RIFF_RLE8 MAKE_FOUR_CC( 'R', 'L', 'E', '8') -#define GST_RIFF_rle4 MAKE_FOUR_CC(0x02,0x00,0x00,0x00) -#define GST_RIFF_RLE4 MAKE_FOUR_CC( 'R', 'L', 'E', '4') -#define GST_RIFF_none MAKE_FOUR_CC(0x00,0x00,0xFF,0xFF) -#define GST_RIFF_NONE MAKE_FOUR_CC( 'N', 'O', 'N', 'E') -#define GST_RIFF_pack MAKE_FOUR_CC(0x01,0x00,0xFF,0xFF) -#define GST_RIFF_PACK MAKE_FOUR_CC( 'P', 'A', 'C', 'K') -#define GST_RIFF_tran MAKE_FOUR_CC(0x02,0x00,0xFF,0xFF) -#define GST_RIFF_TRAN MAKE_FOUR_CC( 'T', 'R', 'A', 'N') -#define GST_RIFF_ccc MAKE_FOUR_CC(0x03,0x00,0xFF,0xFF) -#define GST_RIFF_CCC MAKE_FOUR_CC( 'C', 'C', 'C', ' ') -#define GST_RIFF_cyuv MAKE_FOUR_CC( 'c', 'y', 'u', 'v') -#define GST_RIFF_CYUV MAKE_FOUR_CC( 'C', 'Y', 'U', 'V') -#define GST_RIFF_jpeg MAKE_FOUR_CC(0x04,0x00,0xFF,0xFF) -#define GST_RIFF_JPEG MAKE_FOUR_CC( 'J', 'P', 'E', 'G') -#define GST_RIFF_MJPG MAKE_FOUR_CC( 'M', 'J', 'P', 'G') -#define GST_RIFF_mJPG MAKE_FOUR_CC( 'm', 'J', 'P', 'G') -#define GST_RIFF_IJPG MAKE_FOUR_CC( 'I', 'J', 'P', 'G') -#define GST_RIFF_rt21 MAKE_FOUR_CC( 'r', 't', '2', '1') -#define GST_RIFF_RT21 MAKE_FOUR_CC( 'R', 'T', '2', '1') -#define GST_RIFF_iv31 MAKE_FOUR_CC( 'i', 'v', '3', '1') -#define GST_RIFF_IV31 MAKE_FOUR_CC( 'I', 'V', '3', '1') -#define GST_RIFF_iv32 MAKE_FOUR_CC( 'i', 'v', '3', '2') -#define GST_RIFF_IV32 MAKE_FOUR_CC( 'I', 'V', '3', '2') -#define GST_RIFF_iv41 MAKE_FOUR_CC( 'i', 'v', '4', '1') -#define GST_RIFF_IV41 MAKE_FOUR_CC( 'I', 'V', '4', '1') -#define GST_RIFF_iv50 MAKE_FOUR_CC( 'i', 'v', '5', '0') -#define GST_RIFF_IV50 MAKE_FOUR_CC( 'I', 'V', '5', '0') -#define GST_RIFF_cvid MAKE_FOUR_CC( 'c', 'v', 'i', 'd') -#define GST_RIFF_CVID MAKE_FOUR_CC( 'C', 'V', 'I', 'D') -#define GST_RIFF_ULTI MAKE_FOUR_CC( 'U', 'L', 'T', 'I') -#define GST_RIFF_ulti MAKE_FOUR_CC( 'u', 'l', 't', 'i') -#define GST_RIFF_YUV9 MAKE_FOUR_CC( 'Y', 'V', 'U', '9') -#define GST_RIFF_YVU9 MAKE_FOUR_CC( 'Y', 'U', 'V', '9') -#define GST_RIFF_XMPG MAKE_FOUR_CC( 'X', 'M', 'P', 'G') -#define GST_RIFF_xmpg MAKE_FOUR_CC( 'x', 'm', 'p', 'g') -#define GST_RIFF_VDOW MAKE_FOUR_CC( 'V', 'D', 'O', 'W') -#define GST_RIFF_MVI1 MAKE_FOUR_CC( 'M', 'V', 'I', '1') -#define GST_RIFF_v422 MAKE_FOUR_CC( 'v', '4', '2', '2') -#define GST_RIFF_V422 MAKE_FOUR_CC( 'V', '4', '2', '2') -#define GST_RIFF_mvi1 MAKE_FOUR_CC( 'm', 'v', 'i', '1') -#define GST_RIFF_MPIX MAKE_FOUR_CC(0x04,0x00, 'i', '1') /* MotionPixels munged their id */ -#define GST_RIFF_AURA MAKE_FOUR_CC( 'A', 'U', 'R', 'A') -#define GST_RIFF_DMB1 MAKE_FOUR_CC( 'D', 'M', 'B', '1') -#define GST_RIFF_dmb1 MAKE_FOUR_CC( 'd', 'm', 'b', '1') - -#define GST_RIFF_BW10 MAKE_FOUR_CC( 'B', 'W', '1', '0') -#define GST_RIFF_bw10 MAKE_FOUR_CC( 'b', 'w', '1', '0') - -#define GST_RIFF_yuy2 MAKE_FOUR_CC( 'y', 'u', 'y', '2') -#define GST_RIFF_YUY2 MAKE_FOUR_CC( 'Y', 'U', 'Y', '2') -#define GST_RIFF_YUV8 MAKE_FOUR_CC( 'Y', 'U', 'V', '8') -#define GST_RIFF_WINX MAKE_FOUR_CC( 'W', 'I', 'N', 'X') -#define GST_RIFF_WPY2 MAKE_FOUR_CC( 'W', 'P', 'Y', '2') -#define GST_RIFF_m263 MAKE_FOUR_CC( 'm', '2', '6', '3') -#define GST_RIFF_M263 MAKE_FOUR_CC( 'M', '2', '6', '3') - -#define GST_RIFF_Q1_0 MAKE_FOUR_CC( 'Q', '1',0x2e, '0') -#define GST_RIFF_SFMC MAKE_FOUR_CC( 'S', 'F', 'M', 'C') - -#define GST_RIFF_y41p MAKE_FOUR_CC( 'y', '4', '1', 'p') -#define GST_RIFF_Y41P MAKE_FOUR_CC( 'Y', '4', '1', 'P') -#define GST_RIFF_yv12 MAKE_FOUR_CC( 'y', 'v', '1', '2') -#define GST_RIFF_YV12 MAKE_FOUR_CC( 'Y', 'V', '1', '2') -#define GST_RIFF_vixl MAKE_FOUR_CC( 'v', 'i', 'x', 'l') -#define GST_RIFF_VIXL MAKE_FOUR_CC( 'V', 'I', 'X', 'L') -#define GST_RIFF_iyuv MAKE_FOUR_CC( 'i', 'y', 'u', 'v') -#define GST_RIFF_IYUV MAKE_FOUR_CC( 'I', 'Y', 'U', 'V') -#define GST_RIFF_i420 MAKE_FOUR_CC( 'i', '4', '2', '0') -#define GST_RIFF_I420 MAKE_FOUR_CC( 'I', '4', '2', '0') -#define GST_RIFF_vyuy MAKE_FOUR_CC( 'v', 'y', 'u', 'y') -#define GST_RIFF_VYUY MAKE_FOUR_CC( 'V', 'Y', 'U', 'Y') - -#define GST_RIFF_DIV3 MAKE_FOUR_CC( 'D', 'I', 'V', '3') - -#define GST_RIFF_rpza MAKE_FOUR_CC( 'r', 'p', 'z', 'a') -/* And this here's the mistakes that need to be supported */ -#define GST_RIFF_azpr MAKE_FOUR_CC( 'a', 'z', 'p', 'r') /* recognize Apple's rpza mangled? */ - -/*********** FND in MJPG **********/ -#define GST_RIFF_ISFT MAKE_FOUR_CC( 'I', 'S', 'F', 'T') -#define GST_RIFF_IDIT MAKE_FOUR_CC( 'I', 'D', 'I', 'T') - -#define GST_RIFF_00AM MAKE_FOUR_CC( '0', '0', 'A', 'M') -#define GST_RIFF_DISP MAKE_FOUR_CC( 'D', 'I', 'S', 'P') -#define GST_RIFF_ISBJ MAKE_FOUR_CC( 'I', 'S', 'B', 'J') - -#define GST_RIFF_rec MAKE_FOUR_CC( 'r', 'e', 'c', ' ') - -/* common data structures */ -struct _gst_riff_avih { - guint32 us_frame; /* microsec per frame */ - guint32 max_bps; /* byte/s overall */ - guint32 pad_gran; /* pad_gran (???) */ - guint32 flags; -/* flags values */ -#define GST_RIFF_AVIH_HASINDEX 0x00000010 /* has idx1 chunk */ -#define GST_RIFF_AVIH_MUSTUSEINDEX 0x00000020 /* must use idx1 chunk to determine order */ -#define GST_RIFF_AVIH_ISINTERLEAVED 0x00000100 /* AVI file is interleaved */ -#define GST_RIFF_AVIH_WASCAPTUREFILE 0x00010000 /* specially allocated used for capturing real time video */ -#define GST_RIFF_AVIH_COPYRIGHTED 0x00020000 /* contains copyrighted data */ - guint32 tot_frames; /* # of frames (all) */ - guint32 init_frames; /* initial frames (???) */ - guint32 streams; - guint32 bufsize; /* suggested buffer size */ - guint32 width; - guint32 height; - guint32 scale; - guint32 rate; - guint32 start; - guint32 length; -}; - -struct _gst_riff_strh { - guint32 type; /* stream type */ - guint32 fcc_handler; /* fcc_handler */ - guint32 flags; -/* flags values */ -#define GST_RIFF_STRH_DISABLED 0x000000001 -#define GST_RIFF_STRH_VIDEOPALCHANGES 0x000010000 - guint32 priority; - guint32 init_frames; /* initial frames (???) */ - guint32 scale; - guint32 rate; - guint32 start; - guint32 length; - guint32 bufsize; /* suggested buffer size */ - guint32 quality; - guint32 samplesize; - /* XXX 16 bytes ? */ -}; - -struct _gst_riff_strf_vids { /* == BitMapInfoHeader */ - guint32 size; - guint32 width; - guint32 height; - guint16 planes; - guint16 bit_cnt; - guint32 compression; - guint32 image_size; - guint32 xpels_meter; - guint32 ypels_meter; - guint32 num_colors; /* used colors */ - guint32 imp_colors; /* important colors */ - /* may be more for some codecs */ -}; - - -struct _gst_riff_strf_auds { /* == WaveHeader (?) */ - guint16 format; -/**** from public Microsoft RIFF docs ******/ -#define GST_RIFF_WAVE_FORMAT_UNKNOWN (0x0000) -#define GST_RIFF_WAVE_FORMAT_PCM (0x0001) -#define GST_RIFF_WAVE_FORMAT_ADPCM (0x0002) -#define GST_RIFF_WAVE_FORMAT_IBM_CVSD (0x0005) -#define GST_RIFF_WAVE_FORMAT_ALAW (0x0006) -#define GST_RIFF_WAVE_FORMAT_MULAW (0x0007) -#define GST_RIFF_WAVE_FORMAT_OKI_ADPCM (0x0010) -#define GST_RIFF_WAVE_FORMAT_DVI_ADPCM (0x0011) -#define GST_RIFF_WAVE_FORMAT_DIGISTD (0x0015) -#define GST_RIFF_WAVE_FORMAT_DIGIFIX (0x0016) -#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020) -#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022) -#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031) -#define GST_RIFF_WAVE_FORMAT_MSN (0x0032) -#define GST_RIFF_WAVE_FORMAT_MPEGL12 (0x0050) -#define GST_RIFF_WAVE_FORMAT_MPEGL3 (0x0055) -#define GST_RIFF_IBM_FORMAT_MULAW (0x0101) -#define GST_RIFF_IBM_FORMAT_ALAW (0x0102) -#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103) -#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV1 (0x0160) -#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV2 (0x0161) -#define GST_RIFF_WAVE_FORMAT_WMAV9 (0x0162) -#define GST_RIFF_WAVE_FORMAT_A52 (0x2000) -#define GST_RIFF_WAVE_FORMAT_VORBIS1 (0x674f) -#define GST_RIFF_WAVE_FORMAT_VORBIS2 (0x6750) -#define GST_RIFF_WAVE_FORMAT_VORBIS3 (0x6751) -#define GST_RIFF_WAVE_FORMAT_VORBIS1PLUS (0x676f) -#define GST_RIFF_WAVE_FORMAT_VORBIS2PLUS (0x6770) -#define GST_RIFF_WAVE_FORMAT_VORBIS3PLUS (0x6771) - guint16 channels; - guint32 rate; - guint32 av_bps; - guint16 blockalign; - guint16 size; -}; - -struct _gst_riff_strf_iavs { - guint32 DVAAuxSrc; - guint32 DVAAuxCtl; - guint32 DVAAuxSrc1; - guint32 DVAAuxCtl1; - guint32 DVVAuxSrc; - guint32 DVVAuxCtl; - guint32 DVReserved1; - guint32 DVReserved2; -}; - -struct _gst_riff_riff { - guint32 id; - guint32 size; - guint32 type; -}; - -struct _gst_riff_list { - guint32 id; - guint32 size; - guint32 type; -}; - -struct _gst_riff_chunk { - guint32 id; - guint32 size; -}; - -struct _gst_riff_index_entry { - guint32 id; - guint32 flags; -#define GST_RIFF_IF_LIST (0x00000001L) -#define GST_RIFF_IF_KEYFRAME (0x00000010L) -#define GST_RIFF_IF_NO_TIME (0x00000100L) -#define GST_RIFF_IF_COMPUSE (0x0FFF0000L) - guint32 offset; - guint32 size; -}; - -struct _gst_riff_dmlh { - guint32 totalframes; -}; - -typedef struct _gst_riff_riff gst_riff_riff; -typedef struct _gst_riff_list gst_riff_list; -typedef struct _gst_riff_chunk gst_riff_chunk; -typedef struct _gst_riff_index_entry gst_riff_index_entry; - -typedef struct _gst_riff_avih gst_riff_avih; -typedef struct _gst_riff_strh gst_riff_strh; -typedef struct _gst_riff_strf_vids gst_riff_strf_vids; -typedef struct _gst_riff_strf_auds gst_riff_strf_auds; -typedef struct _gst_riff_strf_iavs gst_riff_strf_iavs; -typedef struct _gst_riff_dmlh gst_riff_dmlh; -typedef struct _GstRiff GstRiff; -typedef struct _GstRiffChunk GstRiffChunk; - -typedef void (*GstRiffCallback) (GstRiffChunk *chunk, gpointer data); - -struct _GstRiff { - guint32 form; - - /* list of chunks, most recent at the head */ - GList *chunks; - - /* incomplete chunks are assembled here */ - GstRiffChunk *incomplete_chunk; - guint32 incomplete_chunk_size; - /* parse state */ - GstRiffParserState state; - guint32 curoffset; - guint32 nextlikely; - /* leftover data */ - guchar *dataleft; - guint32 dataleft_size; - - /* callback function and data pointer */ - GstRiffCallback new_tag_found; - gpointer callback_data; -}; - -struct _GstRiffChunk { - gulong offset; - - guint32 id; - guint32 size; - guint32 form; /* for list chunks */ - - gchar *data; -}; - - -/* from gstriffparse.c */ -GstRiff* gst_riff_parser_new (GstRiffCallback function, gpointer data); -GstRiffReturn gst_riff_parser_next_buffer (GstRiff *riff, GstBuffer *buf, gulong off); -void gst_riff_parser_resync (GstRiff *riff, gulong offset); -GstRiffChunk* gst_riff_parser_get_chunk (GstRiff *riff, guint32 fourcc); -guint32 gst_riff_parser_get_nextlikely (GstRiff *riff); - -/* from gstriffencode.c */ -GstRiff* gst_riff_encoder_new (guint32 type); -GstRiffReturn gst_riff_encoder_avih (GstRiff *riff, gst_riff_avih *head, gulong size); -GstRiffReturn gst_riff_encoder_strh (GstRiff *riff, guint32 fcc_type, - gst_riff_strh *head, gulong size); -GstRiffReturn gst_riff_encoder_strf (GstRiff *riff, void *format, gulong size); -GstRiffReturn gst_riff_encoder_chunk (GstRiff *riff, guint32 chunk_type, - void *chunk, gulong size); - -GstBuffer* gst_riff_encoder_get_buffer (GstRiff *riff); -GstBuffer* gst_riff_encoder_get_and_reset_buffer (GstRiff *riff); - -/* from gstriffutil.c */ -gulong gst_riff_fourcc_to_id (gchar *fourcc); -gchar* gst_riff_id_to_fourcc (gulong id); - - -#endif /* __GST_RIFF_H__ */ diff --git a/gst-libs/gst/riff/riffencode.c b/gst-libs/gst/riff/riffencode.c deleted file mode 100644 index 630725d5..00000000 --- a/gst-libs/gst/riff/riffencode.c +++ /dev/null @@ -1,181 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * - * 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> - -/*#define DEBUG_ENABLED */ -#include "riff.h" - -#define GST_RIFF_ENCODER_BUF_SIZE 1024 - -#define ADD_CHUNK(riffenc, chunkid, chunksize) \ -{ \ - gst_riff_chunk *chunk;\ - chunk = (gst_riff_chunk *)(riffenc->dataleft + riffenc->nextlikely);\ - chunk->id = chunkid; \ - chunk->size = chunksize; \ - riffenc->nextlikely += sizeof(gst_riff_chunk); \ -} - -#define ADD_LIST(riffenc, listsize, listtype) \ -{ \ - gst_riff_list *list;\ - list = (gst_riff_list *)(riffenc->dataleft + riffenc->nextlikely); \ - list->id = GST_RIFF_TAG_LIST; \ - list->size = listsize; \ - list->type = listtype; \ - riffenc->nextlikely += sizeof(gst_riff_list); \ -} - - -GstRiff *gst_riff_encoder_new(guint32 type) { - GstRiff *riff; - gst_riff_list *list; - - GST_DEBUG ("gst_riff_encoder: making %4.4s encoder", (char *)&type); - riff = (GstRiff *)g_malloc(sizeof(GstRiff)); - g_return_val_if_fail(riff != NULL, NULL); - - riff->form = 0; - riff->chunks = NULL; - riff->state = GST_RIFF_STATE_INITIAL; - riff->curoffset = 0; - riff->incomplete_chunk = NULL; - riff->dataleft = g_malloc(GST_RIFF_ENCODER_BUF_SIZE); - riff->dataleft_size = GST_RIFF_ENCODER_BUF_SIZE; - riff->nextlikely = 0; - - list = (gst_riff_list *)riff->dataleft; - list->id = GST_RIFF_TAG_RIFF; - list->size = 0x00FFFFFF; - list->type = GST_RIFF_RIFF_AVI; - - riff->nextlikely += sizeof(gst_riff_list); - - return riff; -} - -gint gst_riff_encoder_avih(GstRiff *riff, gst_riff_avih *head, gulong size) { - gst_riff_chunk *chunk; - - g_return_val_if_fail(riff->state == GST_RIFF_STATE_INITIAL, GST_RIFF_EINVAL); - - GST_DEBUG ("gst_riff_encoder: add avih"); - - ADD_LIST(riff, 0xB8, GST_RIFF_LIST_hdrl); - - ADD_CHUNK(riff, GST_RIFF_TAG_avih, size); - - chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely); - memcpy(chunk, head, size); - riff->nextlikely += size; - - riff->state = GST_RIFF_STATE_HASAVIH; - return GST_RIFF_OK; -} - -gint gst_riff_encoder_strh(GstRiff *riff, guint32 fcc_type, gst_riff_strh *head, gulong size) { - gst_riff_chunk *chunk; - - g_return_val_if_fail(riff->state == GST_RIFF_STATE_HASAVIH || - riff->state == GST_RIFF_STATE_HASSTRF, GST_RIFF_EINVAL); - - GST_DEBUG ("gst_riff_encoder: add strh type %08x (%4.4s)", fcc_type, (char *)&fcc_type); - - ADD_LIST(riff, 108, GST_RIFF_LIST_strl); - - ADD_CHUNK(riff, GST_RIFF_TAG_strh, size); - - chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely); - head->type = fcc_type; - memcpy(chunk, head, size); - - riff->nextlikely += size; - - riff->state = GST_RIFF_STATE_HASSTRH; - return GST_RIFF_OK; -} - -gint gst_riff_encoder_strf(GstRiff *riff, void *format, gulong size) { - gst_riff_chunk *chunk; - - g_return_val_if_fail(riff->state == GST_RIFF_STATE_HASSTRH, GST_RIFF_EINVAL); - - GST_DEBUG ("gst_riff_encoder: add strf"); - - ADD_CHUNK(riff, GST_RIFF_TAG_strf, size); - - chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely); - memcpy(chunk, format, size); - riff->nextlikely += size; - - riff->state = GST_RIFF_STATE_HASSTRF; - return GST_RIFF_OK; -} - -gint gst_riff_encoder_chunk(GstRiff *riff, guint32 chunk_type, void *chunkdata, gulong size) { - gst_riff_chunk *chunk; - - g_return_val_if_fail(riff->state == GST_RIFF_STATE_HASSTRF || - riff->state == GST_RIFF_STATE_MOVI, GST_RIFF_EINVAL); - - if (riff->state != GST_RIFF_STATE_MOVI) { - ADD_LIST(riff, 0x00FFFFFF, GST_RIFF_LIST_movi); - riff->state = GST_RIFF_STATE_MOVI; - } - - GST_DEBUG ("gst_riff_encoder: add chunk type %08x (%4.4s)", chunk_type, (char *)&chunk_type); - - ADD_CHUNK(riff, chunk_type, size); - - if (chunkdata != NULL) { - chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely); - memcpy(chunk, chunkdata, size); - riff->nextlikely += size + (size&1); - } - - return GST_RIFF_OK; -} - -GstBuffer *gst_riff_encoder_get_buffer(GstRiff *riff) { - GstBuffer *newbuf; - - newbuf = gst_buffer_new(); - GST_BUFFER_DATA(newbuf) = riff->dataleft; - GST_BUFFER_SIZE(newbuf) = riff->nextlikely; - - return newbuf; -} - -GstBuffer *gst_riff_encoder_get_and_reset_buffer(GstRiff *riff) { - GstBuffer *newbuf; - - newbuf = gst_riff_encoder_get_buffer(riff); - - riff->dataleft = g_malloc(GST_RIFF_ENCODER_BUF_SIZE); - riff->dataleft_size = GST_RIFF_ENCODER_BUF_SIZE; - riff->nextlikely = 0; - - return newbuf; -} - diff --git a/gst-libs/gst/riff/riffparse.c b/gst-libs/gst/riff/riffparse.c deleted file mode 100644 index 72c9e4bb..00000000 --- a/gst-libs/gst/riff/riffparse.c +++ /dev/null @@ -1,250 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * - * 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> - -/*#define DEBUG_ENABLED */ -#include <riff.h> - -GstRiff* -gst_riff_parser_new (GstRiffCallback function, gpointer data) -{ - GstRiff *riff; - - riff = (GstRiff *)g_malloc(sizeof(GstRiff)); - g_return_val_if_fail(riff != NULL, NULL); - - riff->form = 0; - riff->chunks = NULL; - riff->state = 0; - riff->curoffset = 0; - riff->nextlikely = 0; - riff->new_tag_found = function; - riff->callback_data = data; - riff->incomplete_chunk = NULL; - riff->dataleft = NULL; - - return riff; -} - -gint -gst_riff_parser_next_buffer (GstRiff *riff, GstBuffer *buf, gulong off) -{ - gulong last, size; - GstRiffChunk *chunk; - - g_return_val_if_fail(riff != NULL, GST_RIFF_EINVAL); - g_return_val_if_fail(buf != NULL, GST_RIFF_EINVAL); - g_return_val_if_fail(GST_BUFFER_DATA(buf) != NULL, GST_RIFF_EINVAL); - - size = GST_BUFFER_SIZE(buf); - last = off + size; - - GST_DEBUG ("gst_riff_parser: offset new buffer 0x%08lx size 0x%08x", off, GST_BUFFER_SIZE(buf)); - - if (riff->dataleft) { - gulong newsize; - - GST_DEBUG ("gst_riff_parser: recovering left data"); - newsize = riff->dataleft_size + size; - riff->dataleft = g_realloc(riff->dataleft, newsize); - memcpy(riff->dataleft+riff->dataleft_size, GST_BUFFER_DATA(buf), size); - gst_buffer_unref(buf); - - buf = gst_buffer_new(); - GST_BUFFER_DATA(buf) = riff->dataleft; - size = GST_BUFFER_SIZE(buf) = newsize; - off -= riff->dataleft_size; - /*last -= riff->dataleft_size; */ - riff->dataleft = NULL; - } - - if (off == 0) { - guint32 *words = (guint32 *)GST_BUFFER_DATA(buf); - - /* don't even try to parse the head if it's not there FIXME */ - if (last < 12) { - riff->state = GST_RIFF_ENOTRIFF; - return riff->state; - } - - /*g_print("testing is 0x%08lx '%s'\n",words[0],gst_riff_id_to_fourcc(words[0])); */ - /* verify this is a valid RIFF file, first of all */ - if (GUINT32_FROM_LE (words[0]) != GST_RIFF_TAG_RIFF) { - riff->state = GST_RIFF_ENOTRIFF; - return riff->state; - } - riff->form = GUINT32_FROM_LE (words[2]); - /*g_print("form is 0x%08lx '%s'\n",words[2],gst_riff_id_to_fourcc(words[2])); */ - riff->nextlikely = 12; /* skip 'RIFF', length, and form */ - /* all OK here */ - riff->incomplete_chunk = NULL; - } - - /* if we have an incomplete chunk from the previous buffer */ - if (riff->incomplete_chunk) { - guint leftover; - GST_DEBUG ("gst_riff_parser: have incomplete chunk %08x filled", riff->incomplete_chunk_size); - leftover = riff->incomplete_chunk->size - riff->incomplete_chunk_size; - if (leftover <= size) { - GST_DEBUG ("gst_riff_parser: we can fill it from %08x with %08x bytes = %08x", - riff->incomplete_chunk_size, leftover, - riff->incomplete_chunk_size+leftover); - memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), leftover); - - if (riff->new_tag_found) { - riff->new_tag_found(riff->incomplete_chunk, riff->callback_data); - } - g_free(riff->incomplete_chunk->data); - g_free(riff->incomplete_chunk); - riff->incomplete_chunk = NULL; - } - else { - GST_DEBUG ("gst_riff_parser: we cannot fill it %08x >= %08lx", leftover, size); - memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), size); - riff->incomplete_chunk_size += size; - return 0; - } - } - - if (riff->nextlikely & 0x01) riff->nextlikely++; - - GST_DEBUG ("gst_riff_parser: next 0x%08x last 0x%08lx offset %08lx",riff->nextlikely, last, off); - /* loop while the next likely chunk header is in this buffer */ - while ((riff->nextlikely+12) <= last) { - guint32 *words = (guint32 *)((guchar *)GST_BUFFER_DATA(buf) + riff->nextlikely - off ); - - /* loop over all of the chunks to check which one is finished */ - while (riff->chunks) { - chunk = g_list_nth_data(riff->chunks, 0); - - GST_DEBUG ("gst_riff_parser: next 0x%08x offset 0x%08lx size 0x%08x",riff->nextlikely, - chunk->offset, chunk->size); - if (riff->nextlikely >= chunk->offset+chunk->size) { - GST_DEBUG ("gst_riff_parser: found END LIST"); - /* we have the end of the chunk on the stack, remove it */ - riff->chunks = g_list_remove(riff->chunks, chunk); - } - else break; - } - - GST_DEBUG ("gst_riff_parser: next likely chunk is at offset 0x%08x",riff->nextlikely); - - chunk = (GstRiffChunk *)g_malloc(sizeof(GstRiffChunk)); - g_return_val_if_fail(chunk != NULL, GST_RIFF_ENOMEM); - - chunk->offset = riff->nextlikely+8; /* point to the actual data */ - chunk->id = GUINT32_FROM_LE (words[0]); - chunk->size = GUINT32_FROM_LE (words[1]); - chunk->data = (gchar *)(words+2); - /* we need word alignment */ - /*if (chunk->size & 0x01) chunk->size++; */ - chunk->form = GUINT32_FROM_LE (words[2]); /* fill in the form, might not be valid */ - - - if (chunk->id == GST_RIFF_TAG_LIST) { - GST_DEBUG ("found LIST %s", gst_riff_id_to_fourcc(chunk->form)); - riff->nextlikely += 12; - /* we push the list chunk on our 'stack' */ - riff->chunks = g_list_prepend(riff->chunks,chunk); - /* send the buffer to the listener if we have received a function */ - if (riff->new_tag_found) { - riff->new_tag_found(chunk, riff->callback_data); - } - } - else { - - GST_DEBUG ("gst_riff_parser: chunk id offset %08x is 0x%08x '" GST_FOURCC_FORMAT "' and is 0x%08x long", - riff->nextlikely, chunk->id, GST_FOURCC_ARGS(chunk->id), - chunk->size); - - riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */ - /* if this buffer is incomplete */ - if (riff->nextlikely > last) { - guint left = size - (riff->nextlikely - chunk->size - off); - - GST_DEBUG ("make incomplete buffer %08x", left); - chunk->data = g_malloc(chunk->size); - memcpy(chunk->data, (gchar *)(words+2), left); - riff->incomplete_chunk = chunk; - riff->incomplete_chunk_size = left; - } - else { - /* send the buffer to the listener if we have received a function */ - if (riff->new_tag_found) { - riff->new_tag_found(chunk, riff->callback_data); - } - g_free(chunk); - } - if (riff->nextlikely & 0x01) riff->nextlikely++; - - /*riff->chunks = g_list_prepend(riff->chunks,chunk);*/ - } - } - if ((riff->nextlikely+12) > last && !riff->incomplete_chunk) { - guint left = last - riff->nextlikely; - GST_DEBUG ("gst_riff_parser: not enough data next 0x%08x last 0x%08lx %08x %08lx",riff->nextlikely, - last, left, off); - - riff->dataleft = g_malloc(left); - riff->dataleft_size = left; - memcpy(riff->dataleft, GST_BUFFER_DATA(buf)+size-left, left); - - return 0; - } - - return 0; -} - -void -gst_riff_parser_resync (GstRiff *riff, gulong offset) -{ - riff->incomplete_chunk = NULL; - riff->dataleft = NULL; - riff->nextlikely = offset; -} - - -GstRiffChunk *gst_riff_parser_get_chunk(GstRiff *riff, guint32 fourcc) -{ - GList *chunk; - - g_return_val_if_fail(riff != NULL, NULL); - - chunk = riff->chunks; - while (chunk) { - if (((GstRiffChunk *)(chunk->data))->id == fourcc) - return (GstRiffChunk *)(chunk->data); - chunk = g_list_next(chunk); - } - - return NULL; -} - -guint32 gst_riff_parser_get_nextlikely(GstRiff *riff) -{ - g_return_val_if_fail(riff != NULL, 0); - - return riff->nextlikely; -} - diff --git a/gst-libs/gst/riff/riffutil.c b/gst-libs/gst/riff/riffutil.c deleted file mode 100644 index d33aefe3..00000000 --- a/gst-libs/gst/riff/riffutil.c +++ /dev/null @@ -1,47 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * - * 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 <riff.h> - - -gulong gst_riff_fourcc_to_id(gchar *fourcc) { - g_return_val_if_fail(fourcc != NULL, 0); - - return GUINT32_FROM_LE((gulong)(fourcc[0] << 0) | (fourcc[1] << 8) | - (fourcc[2] << 16) | (fourcc[3] << 24)); -} - -gchar *gst_riff_id_to_fourcc(gulong id) { - static gchar fourcc[5]; - - g_return_val_if_fail(fourcc != NULL, NULL); - - id = GUINT32_FROM_LE(id); - fourcc[0] = (id >> 0) & 0xff; - fourcc[1] = (id >> 8) & 0xff; - fourcc[2] = (id >> 16) & 0xff; - fourcc[3] = (id >> 24) & 0xff; - fourcc[4] = 0; - - return fourcc; -} |