mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-08 13:18:52 +00:00
Hm, darn, forgot to commit one dir
Original commit message from CVS: Hm, darn, forgot to commit one dir
This commit is contained in:
parent
61ea5d0a17
commit
ec9841f4ec
10 changed files with 1724 additions and 936 deletions
|
@ -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)
|
||||
|
|
319
gst-libs/gst/riff/riff-ids.h
Normal file
319
gst-libs/gst/riff/riff-ids.h
Normal file
|
@ -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__ */
|
454
gst-libs/gst/riff/riff-media.c
Normal file
454
gst-libs/gst/riff/riff-media.c
Normal file
|
@ -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;
|
||||
}
|
55
gst-libs/gst/riff/riff-media.h
Normal file
55
gst-libs/gst/riff/riff-media.h
Normal file
|
@ -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__ */
|
877
gst-libs/gst/riff/riff-read.c
Normal file
877
gst-libs/gst/riff/riff-read.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue