aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile30
-rw-r--r--cfg-mplayer.h12
-rw-r--r--command.c3
-rwxr-xr-xconfigure166
-rw-r--r--etc/codecs.conf111
-rw-r--r--libmpcodecs/ad.c16
-rw-r--r--libmpcodecs/ad_dk3adpcm.c262
-rw-r--r--libmpcodecs/ad_libvorbis.c350
-rw-r--r--libmpcodecs/ad_mpc.c231
-rw-r--r--libmpcodecs/ad_speex.c179
-rw-r--r--libmpcodecs/ad_twin.c523
-rw-r--r--libmpcodecs/dec_video.c1
-rw-r--r--libmpcodecs/vd.c12
-rw-r--r--libmpcodecs/vd_mpegpes.c84
-rw-r--r--libmpcodecs/vd_sgi.c343
-rw-r--r--libmpcodecs/vd_theora.c207
-rw-r--r--libmpcodecs/vd_xvid4.c393
-rw-r--r--libmpdemux/aac_hdr.c47
-rw-r--r--libmpdemux/aac_hdr.h26
-rw-r--r--libmpdemux/demux_aac.c260
-rw-r--r--libmpdemux/demux_avi.c39
-rw-r--r--libmpdemux/demux_film.c490
-rw-r--r--libmpdemux/demux_fli.c228
-rw-r--r--libmpdemux/demux_lmlm4.c385
-rw-r--r--libmpdemux/demux_mov.c2350
-rw-r--r--libmpdemux/demux_mov.h24
-rw-r--r--libmpdemux/demux_mpc.c235
-rw-r--r--libmpdemux/demux_mpg.c1248
-rw-r--r--libmpdemux/demux_nsv.c345
-rw-r--r--libmpdemux/demux_nut.c321
-rw-r--r--libmpdemux/demux_ogg.c1660
-rw-r--r--libmpdemux/demux_ogg.h27
-rw-r--r--libmpdemux/demux_pva.c536
-rw-r--r--libmpdemux/demux_roq.c281
-rw-r--r--libmpdemux/demux_smjpeg.c200
-rw-r--r--libmpdemux/demux_ts.c3533
-rw-r--r--libmpdemux/demux_ts.h24
-rw-r--r--libmpdemux/demux_ty.c899
-rw-r--r--libmpdemux/demux_ty_osd.c911
-rw-r--r--libmpdemux/demux_ty_osd.h25
-rw-r--r--libmpdemux/demux_vqf.c240
-rw-r--r--libmpdemux/demux_y4m.c325
-rw-r--r--libmpdemux/demuxer.c68
-rw-r--r--libmpdemux/demuxer.h17
-rw-r--r--libmpdemux/extension.c23
-rw-r--r--libmpdemux/mpeg_hdr.c539
-rw-r--r--libmpdemux/mpeg_hdr.h55
-rw-r--r--libmpdemux/parse_es.c158
-rw-r--r--libmpdemux/parse_es.h45
-rw-r--r--libmpdemux/parse_mp4.c173
-rw-r--r--libmpdemux/parse_mp4.h127
-rw-r--r--libmpdemux/video.c521
-rw-r--r--mplayer.c6
-rw-r--r--stream/network.c21
54 files changed, 34 insertions, 19301 deletions
diff --git a/Makefile b/Makefile
index cb35d0fb39..01c4d59305 100644
--- a/Makefile
+++ b/Makefile
@@ -88,11 +88,9 @@ SRCS_COMMON-$(LIBMAD) += libmpcodecs/ad_libmad.c
SRCS_COMMON-$(LIBNEMESI) += libmpdemux/demux_nemesi.c \
stream/stream_nemesi.c
-SRCS_COMMON-$(LIBNUT) += libmpdemux/demux_nut.c
SRCS_COMMON-$(LIBPOSTPROC) += libmpcodecs/vf_pp.c
SRCS_COMMON-$(LIBSMBCLIENT) += stream/stream_smb.c
-SRCS_COMMON-$(LIBTHEORA) += libmpcodecs/vd_theora.c
SRCS_COMMON-$(LIVE555) += libmpdemux/demux_rtp.cpp \
libmpdemux/demux_rtp_codec.cpp \
stream/stream_live555.c
@@ -103,8 +101,6 @@ SRCS_COMMON-$(COCOA) += libvo/osx_common.c \
SRCS_COMMON-$(MNG) += libmpdemux/demux_mng.c
SRCS_COMMON-$(MPG123) += libmpcodecs/ad_mpg123.c
-SRCS_COMMON-$(MUSEPACK) += libmpcodecs/ad_mpc.c \
- libmpdemux/demux_mpc.c
SRCS_COMMON-$(NATIVE_RTSP) += stream/stream_rtsp.c \
stream/freesdp/common.c \
stream/freesdp/errorlist.c \
@@ -148,7 +144,6 @@ SRCS_COMMON-$(RADIO) += stream/stream_radio.c
SRCS_COMMON-$(RADIO_CAPTURE) += stream/audio_in.c
SRCS_COMMON-$(REAL_CODECS) += libmpcodecs/ad_realaud.c \
libmpcodecs/vd_realvid.c
-SRCS_COMMON-$(SPEEX) += libmpcodecs/ad_speex.c
SRCS_COMMON-$(STREAM_CACHE) += stream/cache2.c
SRCS_COMMON-$(TV) += stream/stream_tv.c stream/tv.c \
@@ -161,8 +156,6 @@ SRCS_COMMON-$(TV_DSHOW) += stream/tvi_dshow.c \
SRCS_COMMON-$(TV_V4L1) += stream/tvi_v4l.c stream/audio_in.c
SRCS_COMMON-$(TV_V4L2) += stream/tvi_v4l2.c stream/audio_in.c
SRCS_COMMON-$(VCD) += stream/stream_vcd.c
-SRCS_COMMON-$(VORBIS) += libmpcodecs/ad_libvorbis.c \
- libmpdemux/demux_ogg.c
SRCS_COMMON-$(VSTREAM) += stream/stream_vstream.c
SRCS_QTX_EMULATION += loader/wrapper.S
SRCS_COMMON-$(QTX_EMULATION) += $(SRCS_QTX_EMULATION)
@@ -181,7 +174,6 @@ SRCS_COMMON-$(WIN32_EMULATION) += $(SRCS_WIN32_EMULATION)
SRCS_COMMON-$(WIN32DLL) += libmpcodecs/ad_acm.c \
libmpcodecs/ad_dmo.c \
libmpcodecs/ad_dshow.c \
- libmpcodecs/ad_twin.c \
libmpcodecs/vd_dmo.c \
libmpcodecs/vd_dshow.c \
libmpcodecs/vd_vfw.c \
@@ -207,7 +199,6 @@ SRCS_COMMON-$(WIN32DLL) += libmpcodecs/ad_acm.c \
loader/dmo/dmo_guids.c \
SRCS_COMMON-$(XANIM_CODECS) += libmpcodecs/vd_xanim.c
-SRCS_COMMON-$(XVID4) += libmpcodecs/vd_xvid4.c
SRCS_COMMON-$(DUMMY_OSD) += sub/osd_dummy.c
SRCS_COMMON-$(LIBASS_OSD) += sub/osd_libass.c
@@ -262,7 +253,6 @@ SRCS_COMMON = asxparser.c \
libaf/window.c \
libmpcodecs/ad.c \
libmpcodecs/ad_alaw.c \
- libmpcodecs/ad_dk3adpcm.c \
libmpcodecs/ad_dvdpcm.c \
libmpcodecs/ad_ffmpeg.c \
libmpcodecs/ad_hwac3.c \
@@ -280,11 +270,9 @@ SRCS_COMMON = asxparser.c \
libmpcodecs/vd_ffmpeg.c \
libmpcodecs/vd_hmblck.c \
libmpcodecs/vd_lzo.c \
- libmpcodecs/vd_mpegpes.c \
libmpcodecs/vd_mtga.c \
libmpcodecs/vd_null.c \
libmpcodecs/vd_raw.c \
- libmpcodecs/vd_sgi.c \
libmpcodecs/vf.c \
libmpcodecs/vf_1bpp.c \
libmpcodecs/vf_2xsai.c \
@@ -357,48 +345,30 @@ SRCS_COMMON = asxparser.c \
libmpcodecs/vf_yadif.c \
libmpcodecs/vf_yuvcsp.c \
libmpcodecs/vf_yvu9.c \
- libmpdemux/aac_hdr.c \
libmpdemux/asfheader.c \
libmpdemux/aviheader.c \
libmpdemux/aviprint.c \
libmpdemux/demuxer.c \
- libmpdemux/demux_aac.c \
libmpdemux/demux_asf.c \
libmpdemux/demux_audio.c \
libmpdemux/demux_avi.c \
libmpdemux/demux_demuxers.c \
libmpdemux/demux_edl.c \
libmpdemux/demux_cue.c \
- libmpdemux/demux_film.c \
- libmpdemux/demux_fli.c \
libmpdemux/demux_lavf.c \
- libmpdemux/demux_lmlm4.c \
libmpdemux/demux_mf.c \
libmpdemux/demux_mkv.c \
- libmpdemux/demux_mov.c \
- libmpdemux/demux_mpg.c \
- libmpdemux/demux_nsv.c \
- libmpdemux/demux_pva.c \
libmpdemux/demux_rawaudio.c \
libmpdemux/demux_rawvideo.c \
libmpdemux/demux_realaud.c \
libmpdemux/demux_real.c \
- libmpdemux/demux_roq.c \
- libmpdemux/demux_smjpeg.c \
- libmpdemux/demux_ts.c \
- libmpdemux/demux_ty.c \
libmpdemux/demux_viv.c \
- libmpdemux/demux_vqf.c \
- libmpdemux/demux_y4m.c \
libmpdemux/ebml.c \
libmpdemux/extension.c \
libmpdemux/mf.c \
libmpdemux/mp3_hdr.c \
libmpdemux/mp_taglists.c \
- libmpdemux/mpeg_hdr.c \
libmpdemux/mpeg_packetizer.c \
- libmpdemux/parse_es.c \
- libmpdemux/parse_mp4.c \
libmpdemux/video.c \
libmpdemux/yuv4mpeg.c \
libmpdemux/yuv4mpeg_ratio.c \
diff --git a/cfg-mplayer.h b/cfg-mplayer.h
index 489419d941..8dc026a00d 100644
--- a/cfg-mplayer.h
+++ b/cfg-mplayer.h
@@ -30,7 +30,6 @@
#include "config.h"
#include "m_config.h"
#include "m_option.h"
-#include "libmpdemux/demux_ts.h"
#include "stream/tv.h"
#include "stream/stream_radio.h"
#include "libvo/csputils.h"
@@ -77,12 +76,6 @@ extern const m_option_t demux_rawaudio_opts[];
extern const m_option_t demux_rawvideo_opts[];
extern const m_option_t cdda_opts[];
-extern int ts_prog;
-extern int ts_keep_broken;
-extern off_t ts_probe;
-extern int audio_substream_id;
-extern off_t ps_probe;
-
extern int sws_flags;
extern const char pp_help[];
@@ -465,7 +458,6 @@ const m_option_t common_opts[] = {
// select audio/video/subtitle stream
OPT_INTRANGE("aid", audio_id, 0, -2, 8190),
- {"ausid", &audio_substream_id, CONF_TYPE_INT, 0, 0, 0, NULL},
OPT_INTRANGE("vid", video_id, 0, -2, 8190),
OPT_INTRANGE("sid", sub_id, 0, -2, 8190),
OPT_FLAG_CONSTANTS("no-sub", sub_id, 0, -1, -2),
@@ -566,10 +558,6 @@ const m_option_t common_opts[] = {
OPT_FLAG_CONSTANTS("flip", flip, 0, -1, 1),
OPT_FLAG_CONSTANTS("no-flip", flip, 0, -1, 0),
- {"tsprog", &ts_prog, CONF_TYPE_INT, CONF_RANGE, 0, 65534, NULL},
- {"tsprobe", &ts_probe, CONF_TYPE_POSITION, 0, 0, TS_MAX_PROBE_SIZE, NULL},
- {"psprobe", &ps_probe, CONF_TYPE_POSITION, 0, 0, TS_MAX_PROBE_SIZE, NULL},
- {"tskeepbroken", &ts_keep_broken, CONF_TYPE_FLAG, 0, 0, 1, NULL},
// draw by slices or whole frame (useful with libmpeg2/libavcodec)
OPT_MAKE_FLAGS("slices", vd_use_slices, 0),
diff --git a/command.c b/command.c
index 1f38603aff..9a696348da 100644
--- a/command.c
+++ b/command.c
@@ -1610,8 +1610,7 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
if ((d_sub->demuxer->type == DEMUXER_TYPE_MATROSKA
|| d_sub->demuxer->type == DEMUXER_TYPE_LAVF
- || d_sub->demuxer->type == DEMUXER_TYPE_LAVF_PREFERRED
- || d_sub->demuxer->type == DEMUXER_TYPE_OGG)
+ || d_sub->demuxer->type == DEMUXER_TYPE_LAVF_PREFERRED)
&& d_sub->sh && opts->sub_id >= 0) {
struct sh_sub *sh = d_sub->sh;
char *lang = sh->lang ? sh->lang : mp_gtext("unknown");
diff --git a/configure b/configure
index d5a30aec8e..95acce4f47 100755
--- a/configure
+++ b/configure
@@ -349,13 +349,7 @@ Codecs:
--disable-qtx disable QuickTime codecs support [enabled]
--disable-xanim disable XAnim codecs support [enabled]
--disable-real disable RealPlayer codecs support [enabled]
- --disable-xvid disable Xvid [autodetect]
- --disable-libnut disable libnut [autodetect]
--enable-libav skip Libav autodetection [autodetect]
- --disable-libvorbis disable libvorbis support [autodetect]
- --disable-tremor disable Tremor [autodetect if no libvorbis]
- --disable-speex disable Speex support [autodetect]
- --enable-theora enable OggTheora libraries [autodetect]
--enable-faad enable FAAD2 (AAC) [autodetect]
--disable-ladspa disable LADSPA plugin support [autodetect]
--disable-libbs2b disable libbs2b audio filter support [autodetect]
@@ -364,8 +358,6 @@ Codecs:
--disable-mad disable libmad (MPEG audio) support [autodetect]
--enable-libdca enable libdca support [autodetect]
--disable-liba52 disable liba52 [autodetect]
- --enable-musepack enable libmpcdec support (deprecated, libavcodec
- Musepack decoder is preferred) [disabled]
Video output:
--enable-gl enable OpenGL video output [autodetect]
@@ -492,10 +484,6 @@ _jack=auto
_openal=no
_libcdio=auto
_mad=auto
-_tremor=auto
-_libvorbis=auto
-_speex=auto
-_theora=auto
_mpg123=auto
_liba52=auto
_libdca=auto
@@ -538,8 +526,6 @@ _winsock2_h=auto
_smb=auto
_libquvi=auto
_joystick=no
-_xvid=auto
-_libnut=auto
_lirc=auto
_lircc=auto
_apple_remote=auto
@@ -568,7 +554,6 @@ _enca=auto
_inet6=auto
_gethostbyname2=auto
_ftp=auto
-_musepack=no
_vstream=auto
_pthreads=auto
_w32threads=auto
@@ -751,22 +736,12 @@ for ac_option do
--disable-mad) _mad=no ;;
--enable-libcdio) _libcdio=yes ;;
--disable-libcdio) _libcdio=no ;;
- --enable-libvorbis) _libvorbis=yes ;;
- --disable-libvorbis) _libvorbis=no ;;
- --enable-speex) _speex=yes ;;
- --disable-speex) _speex=no ;;
- --enable-tremor) _tremor=yes ;;
- --disable-tremor) _tremor=no ;;
- --enable-theora) _theora=yes ;;
- --disable-theora) _theora=no ;;
--enable-mpg123) _mpg123=yes ;;
--disable-mpg123) _mpg123=no ;;
--enable-liba52) _liba52=yes ;;
--disable-liba52) _liba52=no ;;
--enable-libdca) _libdca=yes ;;
--disable-libdca) _libdca=no ;;
- --enable-musepack) _musepack=yes ;;
- --disable-musepack) _musepack=no ;;
--enable-faad) _faad=yes ;;
--disable-faad) _faad=no ;;
--enable-ladspa) _ladspa=yes ;;
@@ -835,10 +810,6 @@ for ac_option do
--disable-libquvi) _libquvi=no ;;
--enable-joystick) _joystick=yes ;;
--disable-joystick) _joystick=no ;;
- --enable-xvid) _xvid=yes ;;
- --disable-xvid) _xvid=no ;;
- --enable-libnut) _libnut=yes ;;
- --disable-libnut) _libnut=no ;;
--enable-libav) ffmpeg=yes ;;
--ffmpeg-source-dir=*)
_ffmpeg_source=$(echo $ac_option | cut -d '=' -f 2 ) ;;
@@ -3396,71 +3367,6 @@ else
fi
echores "$_mad"
-echocheck "OggVorbis support"
-if test "$_libvorbis" = auto; then
- _libvorbis=no
- statement_check vorbis/codec.h 'vorbis_packet_blocksize(0, 0)' -lvorbis -logg $_ld_lm && _libvorbis=yes && _tremor=no
-elif test "$_libvorbis" = yes ; then
- _tremor=no
-fi
-if test "$_tremor" = auto; then
- _tremor=no
- statement_check tremor/ivorbiscodec.h 'vorbis_packet_blocksize(0, 0)' -logg -lvorbisidec $_ld_lm && _tremor=yes
-fi
-if test "$_tremor" = yes ; then
- _vorbis=yes
- def_vorbis='#define CONFIG_OGGVORBIS 1'
- def_tremor='#define CONFIG_TREMOR 1'
- codecmodules="tremor(external) $codecmodules"
- res_comment="external Tremor"
- extra_ldflags="$extra_ldflags -logg -lvorbisidec"
-elif test "$_libvorbis" = yes ; then
- _vorbis=yes
- def_vorbis='#define CONFIG_OGGVORBIS 1'
- codecmodules="libvorbis $codecmodules"
- res_comment="libvorbis"
- extra_ldflags="$extra_ldflags -lvorbis -logg"
-else
- _vorbis=no
- nocodecmodules="libvorbis $nocodecmodules"
-fi
-echores "$_vorbis"
-
-echocheck "libspeex (version >= 1.1 required)"
-if test "$_speex" = auto ; then
- _speex=no
- cat > $TMPC << EOF
-#include <stddef.h>
-#include <speex/speex.h>
-int main(void) { SpeexBits bits; void *dec = NULL; speex_decode_int(dec, &bits, dec); return 0; }
-EOF
- cc_check -lspeex $_ld_lm && _speex=yes
-fi
-if test "$_speex" = yes ; then
- def_speex='#define CONFIG_SPEEX 1'
- extra_ldflags="$extra_ldflags -lspeex"
- codecmodules="speex $codecmodules"
-else
- def_speex='#undef CONFIG_SPEEX'
- nocodecmodules="speex $nocodecmodules"
-fi
-echores "$_speex"
-
-echocheck "OggTheora support"
-if test "$_theora" = auto ; then
- _theora=no
- if pkg_config_add theora ; then
- _theora=yes
- fi
-fi
-if test "$_theora" = yes ; then
- def_theora='#define CONFIG_OGGTHEORA 1'
- codecmodules="libtheora $codecmodules"
-else
- def_theora='#undef CONFIG_OGGTHEORA'
- nocodecmodules="libtheora $nocodecmodules"
-fi
-echores "$_theora"
# Any version of libmpg123 that knows MPG123_RESYNC_LIMIT shall be fine.
# That is, 1.2.0 onwards. Recommened is 1.14 onwards, though.
@@ -3514,32 +3420,6 @@ else
fi
echores "$_libdca"
-echocheck "libmpcdec (musepack, version >= 1.2.1 required)"
-if test "$_musepack" = yes ; then
- _musepack=no
- cat > $TMPC << EOF
-#include <stddef.h>
-#include <mpcdec/mpcdec.h>
-int main(void) {
- mpc_streaminfo info;
- mpc_decoder decoder;
- mpc_decoder_set_streaminfo(&decoder, &info);
- mpc_decoder_decode_frame(&decoder, NULL, 0, NULL);
- return 0;
-}
-EOF
- cc_check -lmpcdec $_ld_lm && _musepack=yes
-fi
-if test "$_musepack" = yes ; then
- def_musepack='#define CONFIG_MUSEPACK 1'
- extra_ldflags="$extra_ldflags -lmpcdec"
- codecmodules="musepack $codecmodules"
-else
- def_musepack='#undef CONFIG_MUSEPACK'
- nocodecmodules="musepack $nocodecmodules"
-fi
-echores "$_musepack"
-
echocheck "FAAD2 support"
if test "$_faad" = auto ; then
@@ -3819,40 +3699,6 @@ fi
echores "$_libdv"
-echocheck "Xvid"
-if test "$_xvid" = auto ; then
- _xvid=no
- for _ld_tmp in "-lxvidcore $_ld_lm" "-lxvidcore $_ld_lm $_ld_pthread" ; do
- statement_check xvid.h 'xvid_global(0, 0, 0, 0)' $_ld_tmp &&
- extra_ldflags="$extra_ldflags $_ld_tmp" && _xvid=yes && break
- done
-fi
-
-if test "$_xvid" = yes ; then
- def_xvid='#define CONFIG_XVID4 1'
- codecmodules="xvid $codecmodules"
-else
- def_xvid='#undef CONFIG_XVID4'
- nocodecmodules="xvid $nocodecmodules"
-fi
-echores "$_xvid"
-
-
-echocheck "libnut"
-if test "$_libnut" = auto ; then
- _libnut=no
- statement_check libnut.h 'nut_context_tt * nut; nut_error(0)' -lnut && _libnut=yes
-fi
-
-if test "$_libnut" = yes ; then
- def_libnut='#define CONFIG_LIBNUT 1'
- extra_ldflags="$extra_ldflags -lnut"
-else
- def_libnut='#undef CONFIG_LIBNUT'
-fi
-echores "$_libnut"
-
-
echocheck "TV interface"
if test "$_tv" = yes ; then
def_tv='#define CONFIG_TV 1'
@@ -4391,7 +4237,6 @@ LIBDVDCSS_INTERNAL = $_libdvdcss_internal
LIBMAD = $_mad
LIBNEMESI = $_nemesi
LCMS2 = $_lcms2
-LIBNUT = $_libnut
LIBPOSTPROC = $libpostproc
LIBSMBCLIENT = $_smb
LIBQUVI = $_libquvi
@@ -4402,7 +4247,6 @@ MACOSX_FINDER = $_macosx_finder
MD5SUM = $_md5sum
MNG = $_mng
MPG123 = $_mpg123
-MUSEPACK = $_musepack
NATIVE_RTSP = $_native_rtsp
NETWORKING = $networking
OPENAL = $_openal
@@ -4421,7 +4265,6 @@ RADIO=$_radio
RADIO_CAPTURE=$_radio_capture
REAL_CODECS = $_real
RSOUND = $_rsound
-SPEEX = $_speex
STREAM_CACHE = $_stream_cache
TGA = $_tga
TV = $_tv
@@ -4433,14 +4276,12 @@ TV_V4L2 = $_tv_v4l2
V4L2 = $_v4l2
VCD = $_vcd
VDPAU = $_vdpau
-VORBIS = $_vorbis
VSTREAM = $_vstream
WIN32DLL = $_win32dll
WIN32_EMULATION = $_win32_emulation
X11 = $_x11
XANIM_CODECS = $_xanim
XV = $_xv
-XVID4 = $_xvid
YUV4MPEG = $_yuv4mpeg
# FFmpeg
@@ -4624,16 +4465,9 @@ $def_libdca
$def_libdv
$def_mad
$def_mpg123
-$def_musepack
-$def_speex
-$def_theora
-$def_tremor
-$def_vorbis
-$def_xvid
$def_zlib
$def_libpostproc
-$def_libnut
/* binary codecs */
diff --git a/etc/codecs.conf b/etc/codecs.conf
index 5120406f12..e4618a92d0 100644
--- a/etc/codecs.conf
+++ b/etc/codecs.conf
@@ -445,13 +445,6 @@ videocodec ffsgi
driver ffmpeg
dll sgi
-videocodec sgi
- info "SGI image"
- status working
- fourcc SGI1 ; SGI1 is an internal MPlayer FOURCC
- driver sgi
- out BGR24
-
videocodec ffsunras
info "FFmpeg SUN Rasterfile"
status working
@@ -562,14 +555,6 @@ videocodec lzo
out YV12,I420
out BGR24 flip
-videocodec theora
- info "Theora (free, reworked VP3)"
- status working
- fourcc theo,Thra
- driver theora
- dll libtheora
- out YV12,422P,444P
-
; prefer native codecs over win32?
; the win32 codecs probably are (better) optimized and support direct
; rendering, so this may be not the best idea...
@@ -1099,41 +1084,6 @@ videocodec fflibdirac
driver ffmpeg
dll libdirac
-videocodec xvid
- info "Xvid (MPEG-4)"
- status working
- fourcc FMP4,fmp4
- fourcc DIVX,divx
- fourcc xvid,XVID,XviD,XVIX
- fourcc DIV1,div1 divx
- fourcc MP4S,mp4s ; ISO MPEG-4 Video V1
- fourcc M4S2,m4s2
- fourcc DX50,dx50,BLZ0 DX50
- fourcc mp4v,MP4V
- format 0x4
- fourcc UMP4
- fourcc RMP4
- fourcc 3IV2,3iv2 ; 3ivx Delta 4
- fourcc DXGM
- fourcc SEDG ; diskless camcorder Samsung Miniket VP-M110
- fourcc SMP4,smp4 ; Samsung SMP4 video codec
- fourcc VIDM ; vidm 4.01 codec
- fourcc FFDS
- fourcc DCOD,MVXM,EM4A,PM4V
- fourcc M4T3,DMK2,DIGI,INMC
- fourcc EPHV,SN40,WAWV
- fourcc uldx,ULDX,VSPX
- format 0x10000004 ; mpeg 4 es
- fourcc SIPP ; Samsung SHR-6040
- driver xvid
- out YV12
- out I420
- out YUY2
- out UYVY
- out YVYU
- out BGR32,BGR24,BGR16,BGR15
- dll "libxvidcore.a"
-
; is divx4vfw stable enough, working everywhere and faster than divxds?
videocodec divx4vfw
@@ -3860,13 +3810,6 @@ audiocodec ffadpcmimadk3
driver ffmpeg
dll adpcm_ima_dk3
-audiocodec dk3adpcm
- info "Duck DK3 ADPCM (rogue format number)"
- status working
- format 0x62 ; This format number was used by Duck Corp. but not officially
- ; registered with Microsoft
- driver dk3adpcm
-
audiocodec ffroqaudio
info "Id RoQ File Audio"
status working
@@ -4501,13 +4444,6 @@ audiocodec ffmusepack8
driver ffmpeg
dll "mpc8"
-audiocodec musepack
- info "Musepack audio codec"
- status working
- fourcc "MPC "
- format 0x2b4d
- driver mpcdec
-
audiocodec ffamrnb
info "AMR Narrowband"
status working
@@ -4630,46 +4566,6 @@ audiocodec ffvorbis
driver ffmpeg
dll "vorbis"
-audiocodec vorbis
- info "OggVorbis Audio"
- status working
- comment "OggVorbis driver using libvorbis"
- fourcc vrbs
- format 0x566F
- driver libvorbis
- dll "libvorbis"
-
-audiocodec tremor
- info "OggVorbis audio"
- status working
- comment "fixed-point decoder useful for systems without floating-point unit"
- fourcc vrbs
- format 0x566F
- driver tremor
- dll "tremor"
-
-audiocodec vorbisacm
- info "OggVorbis ACM"
- status working
- comment "OggVorbis driver using vorbis.acm"
- format 0x674F ; mode1
- format 0x6750 ; mode2
-; format 0x6751 ; mode3
- format 0x676F ; mode1+
- format 0x6770 ; mode2+
- format 0x6771 ; mode3+
- driver acm
- dll "vorbis.acm"
-
-audiocodec speex
- info "Speex audio"
- status working
- comment "Speex driver using libspeex"
- fourcc 'spx '
- format 0xA109
- driver speex
- dll "speex"
-
audiocodec vivoaudio
info "Vivo G.723/Siren Audio Codec"
status working
@@ -4797,13 +4693,6 @@ audiocodec fftwinvq
driver ffmpeg
dll twinvq
-audiocodec TwinVQ
- info "VQF codec by NTTLabs"
- status working
- fourcc TWIN
- driver vqf
- dll "tvqdec.dll"
-
audiocodec hwmpa
info "MPEG audio pass-through for hardware MPEG decoders"
status working
diff --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c
index 0ab5d44971..dce8f9f710 100644
--- a/libmpcodecs/ad.c
+++ b/libmpcodecs/ad.c
@@ -41,20 +41,14 @@ extern const ad_functions_t mpcodecs_ad_dvdpcm;
extern const ad_functions_t mpcodecs_ad_alaw;
extern const ad_functions_t mpcodecs_ad_imaadpcm;
extern const ad_functions_t mpcodecs_ad_msadpcm;
-extern const ad_functions_t mpcodecs_ad_dk3adpcm;
-extern const ad_functions_t mpcodecs_ad_dk4adpcm;
extern const ad_functions_t mpcodecs_ad_dshow;
extern const ad_functions_t mpcodecs_ad_dmo;
extern const ad_functions_t mpcodecs_ad_acm;
extern const ad_functions_t mpcodecs_ad_faad;
-extern const ad_functions_t mpcodecs_ad_libvorbis;
-extern const ad_functions_t mpcodecs_ad_speex;
extern const ad_functions_t mpcodecs_ad_libmad;
extern const ad_functions_t mpcodecs_ad_realaud;
extern const ad_functions_t mpcodecs_ad_libdv;
extern const ad_functions_t mpcodecs_ad_qtaudio;
-extern const ad_functions_t mpcodecs_ad_twin;
-extern const ad_functions_t mpcodecs_ad_libmusepack;
extern const ad_functions_t mpcodecs_ad_libdca;
const ad_functions_t * const mpcodecs_ad_drivers[] =
@@ -73,7 +67,6 @@ const ad_functions_t * const mpcodecs_ad_drivers[] =
&mpcodecs_ad_alaw,
&mpcodecs_ad_imaadpcm,
&mpcodecs_ad_msadpcm,
- &mpcodecs_ad_dk3adpcm,
#ifdef CONFIG_WIN32DLL
&mpcodecs_ad_dshow,
&mpcodecs_ad_dmo,
@@ -86,12 +79,6 @@ const ad_functions_t * const mpcodecs_ad_drivers[] =
#ifdef CONFIG_FAAD
&mpcodecs_ad_faad,
#endif
-#ifdef CONFIG_OGGVORBIS
- &mpcodecs_ad_libvorbis,
-#endif
-#ifdef CONFIG_SPEEX
- &mpcodecs_ad_speex,
-#endif
#ifdef CONFIG_LIBMAD
&mpcodecs_ad_libmad,
#endif
@@ -101,9 +88,6 @@ const ad_functions_t * const mpcodecs_ad_drivers[] =
#ifdef CONFIG_LIBDV095
&mpcodecs_ad_libdv,
#endif
-#ifdef CONFIG_MUSEPACK
- &mpcodecs_ad_libmusepack,
-#endif
#ifdef CONFIG_LIBDCA
&mpcodecs_ad_libdca,
#endif
diff --git a/libmpcodecs/ad_dk3adpcm.c b/libmpcodecs/ad_dk3adpcm.c
deleted file mode 100644
index 15027f88b1..0000000000
--- a/libmpcodecs/ad_dk3adpcm.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * DK3 ADPCM decoder
- *
- * "This format number was used by Duck Corp. but not officially
- * registered with Microsoft"
- *
- * This file is responsible for decoding audio data encoded with
- * Duck Corp's DK3 ADPCM algorithm. Details about the data format
- * can be found here:
- * http://www.pcisys.net/~melanson/codecs/
- *
- * Copyright (c) 2002 Mike Melanson
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <libavutil/intreadwrite.h>
-
-#include "config.h"
-#include "ad_internal.h"
-
-static const ad_info_t info =
-{
- "Duck Corp. DK3 ADPCM decoder",
- "dk3adpcm",
- "Nick Kurshev",
- "Mike Melanson",
- ""
-};
-
-LIBAD_EXTERN(dk3adpcm)
-
-#define DK3_ADPCM_PREAMBLE_SIZE 16
-
-// useful macros
-// clamp a number between 0 and 88
-#define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88;
-// clamp a number within a signed 16-bit range
-#define CLAMP_S16(x) if (x < -32768) x = -32768; \
- else if (x > 32767) x = 32767;
-// clamp a number above 16
-#define CLAMP_ABOVE_16(x) if (x < 16) x = 16;
-// sign extend a 16-bit value
-#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
-// sign extend a 4-bit value
-#define SE_4BIT(x) if (x & 0x8) x -= 0x10;
-
-// pertinent tables
-static int adpcm_step[89] =
-{
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
-static int adpcm_index[16] =
-{
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8
-};
-
-static int preinit(sh_audio_t *sh_audio)
-{
- sh_audio->audio_out_minsize = sh_audio->wf->nBlockAlign * 6;
- sh_audio->ds->ss_div =
- (sh_audio->wf->nBlockAlign - DK3_ADPCM_PREAMBLE_SIZE) * 8 / 3;
- sh_audio->audio_in_minsize=
- sh_audio->ds->ss_mul = sh_audio->wf->nBlockAlign;
- return 1;
-}
-
-static int init(sh_audio_t *sh_audio)
-{
- sh_audio->channels = sh_audio->wf->nChannels;
- sh_audio->samplerate = sh_audio->wf->nSamplesPerSec;
- sh_audio->i_bps =
- (sh_audio->ds->ss_mul * sh_audio->samplerate) / sh_audio->ds->ss_div;
- sh_audio->samplesize=2;
- return 1;
-}
-
-static void uninit(sh_audio_t *sh_audio)
-{
-}
-
-static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
-{
- if(cmd==ADCTRL_SKIP_FRAME){
- demux_read_data(sh_audio->ds, sh_audio->a_in_buffer,sh_audio->ds->ss_mul);
- return CONTROL_TRUE;
- }
- return CONTROL_UNKNOWN;
-}
-
-#define DK3_GET_NEXT_NIBBLE() \
- if (decode_top_nibble_next) \
- { \
- nibble = (last_byte >> 4) & 0x0F; \
- decode_top_nibble_next = 0; \
- } \
- else \
- { \
- last_byte = input[in_ptr++]; \
- nibble = last_byte & 0x0F; \
- decode_top_nibble_next = 1; \
- }
-
-// note: This decoder assumes the format 0x62 data always comes in
-// stereo flavor
-static int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input,
- int block_size)
-{
- int sum_pred;
- int diff_pred;
- int sum_index;
- int diff_index;
- int diff_channel;
- int in_ptr = 0x10;
- int out_ptr = 0;
-
- unsigned char last_byte = 0;
- unsigned char nibble;
- int decode_top_nibble_next = 0;
-
- // ADPCM work variables
- int sign;
- int delta;
- int step;
- int diff;
-
- sum_pred = AV_RL16(&input[10]);
- diff_pred = AV_RL16(&input[12]);
- SE_16BIT(sum_pred);
- SE_16BIT(diff_pred);
- diff_channel = diff_pred;
- sum_index = input[14];
- diff_index = input[15];
-
- while (in_ptr < block_size - !decode_top_nibble_next)
-// while (in_ptr < 2048)
- {
- // process the first predictor of the sum channel
- DK3_GET_NEXT_NIBBLE();
-
- step = adpcm_step[sum_index];
-
- sign = nibble & 8;
- delta = nibble & 7;
-
- diff = step >> 3;
- if (delta & 4) diff += step;
- if (delta & 2) diff += step >> 1;
- if (delta & 1) diff += step >> 2;
-
- if (sign)
- sum_pred -= diff;
- else
- sum_pred += diff;
-
- CLAMP_S16(sum_pred);
-
- sum_index += adpcm_index[nibble];
- CLAMP_0_TO_88(sum_index);
-
- // process the diff channel predictor
- DK3_GET_NEXT_NIBBLE();
-
- step = adpcm_step[diff_index];
-
- sign = nibble & 8;
- delta = nibble & 7;
-
- diff = step >> 3;
- if (delta & 4) diff += step;
- if (delta & 2) diff += step >> 1;
- if (delta & 1) diff += step >> 2;
-
- if (sign)
- diff_pred -= diff;
- else
- diff_pred += diff;
-
- CLAMP_S16(diff_pred);
-
- diff_index += adpcm_index[nibble];
- CLAMP_0_TO_88(diff_index);
-
- // output the first pair of stereo PCM samples
- diff_channel = (diff_channel + diff_pred) / 2;
- output[out_ptr++] = sum_pred + diff_channel;
- output[out_ptr++] = sum_pred - diff_channel;
-
- // process the second predictor of the sum channel
- DK3_GET_NEXT_NIBBLE();
-
- step = adpcm_step[sum_index];
-
- sign = nibble & 8;
- delta = nibble & 7;
-
- diff = step >> 3;
- if (delta & 4) diff += step;
- if (delta & 2) diff += step >> 1;
- if (delta & 1) diff += step >> 2;
-
- if (sign)
- sum_pred -= diff;
- else
- sum_pred += diff;
-
- CLAMP_S16(sum_pred);
-
- sum_index += adpcm_index[nibble];
- CLAMP_0_TO_88(sum_index);
-
- // output the second pair of stereo PCM samples
- output[out_ptr++] = sum_pred + diff_channel;
- output[out_ptr++] = sum_pred - diff_channel;
- }
-
- return out_ptr;
-}
-
-static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
-{
- if (demux_read_data(sh_audio->ds, sh_audio->a_in_buffer,
- sh_audio->ds->ss_mul) !=
- sh_audio->ds->ss_mul)
- return -1; /* EOF */
-
- if (maxlen < 2 * 4 * sh_audio->wf->nBlockAlign * 2 / 3) {
- mp_msg(MSGT_DECAUDIO, MSGL_V, "dk3adpcm: maxlen too small in decode_audio\n");
- return -1;
- }
- return 2 * dk3_adpcm_decode_block(
- (unsigned short*)buf, sh_audio->a_in_buffer,
- sh_audio->ds->ss_mul);
-}
diff --git a/libmpcodecs/ad_libvorbis.c b/libmpcodecs/ad_libvorbis.c
deleted file mode 100644
index a768095187..0000000000
--- a/libmpcodecs/ad_libvorbis.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <math.h>
-
-#include "config.h"
-#include "ad_internal.h"
-#include "libaf/reorder_ch.h"
-
-static const ad_info_t info =
-{
- "Ogg/Vorbis audio decoder",
-#ifdef CONFIG_TREMOR
- "tremor",
-#else
- "libvorbis",
-#endif
- "Felix Buenemann, A'rpi",
- "libvorbis",
- ""
-};
-
-LIBAD_EXTERN(libvorbis)
-
-#ifdef CONFIG_TREMOR
-#include <tremor/ivorbiscodec.h>
-#else
-#include <vorbis/codec.h>
-#endif
-
-// This struct is also defined in demux_ogg.c => common header ?
-typedef struct ov_struct_st {
- vorbis_info vi; /* struct that stores all the static vorbis bitstream
- settings */
- vorbis_comment vc; /* struct that stores all the bitstream user comments */
- vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
- vorbis_block vb; /* local working space for packet->PCM decode */
- float rg_scale; /* replaygain scale */
-#ifdef CONFIG_TREMOR
- int rg_scale_int;
-#endif
-} ov_struct_t;
-
-static int read_vorbis_comment( char* ptr, const char* comment, const char* format, ... ) {
- va_list va;
- int clen, ret;
-
- va_start( va, format );
- clen = strlen( comment );
- ret = strncasecmp( ptr, comment, clen) == 0 ? vsscanf( ptr+clen, format, va ) : 0;
- va_end( va );
-
- return ret;
-}
-
-static int preinit(sh_audio_t *sh)
-{
- sh->audio_out_minsize=1024*4; // 1024 samples/frame
- return 1;
-}
-
-static int init(sh_audio_t *sh)
-{
- unsigned int offset, i, length, hsizes[3];
- void *headers[3];
- unsigned char* extradata;
- ogg_packet op;
- vorbis_comment vc;
- struct ov_struct_st *ov;
-#define ERROR() { \
- vorbis_comment_clear(&vc); \
- vorbis_info_clear(&ov->vi); \
- free(ov); \
- return 0; \
- }
-
- /// Init the decoder with the 3 header packets
- ov = malloc(sizeof(struct ov_struct_st));
- vorbis_info_init(&ov->vi);
- vorbis_comment_init(&vc);
-
- if(! sh->wf) {
- mp_msg(MSGT_DECAUDIO,MSGL_ERR,"ad_vorbis, extradata seems to be absent! exit\n");
- ERROR();
- }
-
- if(! sh->wf->cbSize) {
- mp_msg(MSGT_DECAUDIO,MSGL_ERR,"ad_vorbis, extradata seems to be absent!, exit\n");
- ERROR();
- }
-
- mp_msg(MSGT_DECAUDIO,MSGL_V,"ad_vorbis, extradata seems is %d bytes long\n", sh->wf->cbSize);
- extradata = (char*) (sh->wf+1);
- if(!extradata) {
- mp_msg(MSGT_DECAUDIO,MSGL_ERR,"ad_vorbis, extradata seems to be NULL!, exit\n");
- ERROR();
- }
-
- if(*extradata != 2) {
- mp_msg (MSGT_DEMUX, MSGL_WARN, "ad_vorbis: Vorbis track does not contain valid headers.\n");
- ERROR();
- }
-
- offset = 1;
- for (i=0; i < 2; i++) {
- length = 0;
- while ((extradata[offset] == (unsigned char) 0xFF) && length < sh->wf->cbSize) {
- length += 255;
- offset++;
- }
- if(offset >= (sh->wf->cbSize - 1)) {
- mp_msg (MSGT_DEMUX, MSGL_WARN, "ad_vorbis: Vorbis track does not contain valid headers.\n");
- ERROR();
- }
- length += extradata[offset];
- offset++;
- mp_msg (MSGT_DEMUX, MSGL_V, "ad_vorbis, offset: %u, length: %u\n", offset, length);
- hsizes[i] = length;
- }
-
- headers[0] = &extradata[offset];
- headers[1] = &extradata[offset + hsizes[0]];
- headers[2] = &extradata[offset + hsizes[0] + hsizes[1]];
- hsizes[2] = sh->wf->cbSize - offset - hsizes[0] - hsizes[1];
- mp_msg (MSGT_DEMUX, MSGL_V, "ad_vorbis, header sizes: %d %d %d\n", hsizes[0], hsizes[1], hsizes[2]);
-
- for(i=0; i<3; i++) {
- op.bytes = hsizes[i];
- op.packet = headers[i];
- op.b_o_s = (i == 0);
- if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) {
- mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: header n. %d broken! len=%ld\n", i, op.bytes);
- ERROR();
- }
- if(i == 2) {
- float rg_gain=0.f, rg_peak=0.f;
- char **ptr=vc.user_comments;
- while(*ptr){
- mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbisComment: %s\n",*ptr);
- /* replaygain */
- read_vorbis_comment( *ptr, "replaygain_album_gain=", "%f", &rg_gain );
- read_vorbis_comment( *ptr, "rg_audiophile=", "%f", &rg_gain );
- if( !rg_gain ) {
- read_vorbis_comment( *ptr, "replaygain_track_gain=", "%f", &rg_gain );
- read_vorbis_comment( *ptr, "rg_radio=", "%f", &rg_gain );
- }
- read_vorbis_comment( *ptr, "replaygain_album_peak=", "%f", &rg_peak );
- if( !rg_peak ) {
- read_vorbis_comment( *ptr, "replaygain_track_peak=", "%f", &rg_peak );
- read_vorbis_comment( *ptr, "rg_peak=", "%f", &rg_peak );
- }
- ++ptr;
- }
- /* replaygain: scale */
- if(!rg_gain)
- ov->rg_scale = 1.f; /* just in case pow() isn't standard-conformant */
- else
- ov->rg_scale = pow(10.f, rg_gain/20);
- /* replaygain: anticlip */
- if(ov->rg_scale * rg_peak > 1.f)
- ov->rg_scale = 1.f / rg_peak;
- /* replaygain: security */
- if(ov->rg_scale > 15.)
- ov->rg_scale = 15.;
-#ifdef CONFIG_TREMOR
- ov->rg_scale_int = (int)(ov->rg_scale*64.f);
-#endif
- mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Bitstream is %d channel%s, %dHz, %dbit/s %cBR\n",(int)ov->vi.channels,ov->vi.channels>1?"s":"",(int)ov->vi.rate,(int)ov->vi.bitrate_nominal,
- (ov->vi.bitrate_lower!=ov->vi.bitrate_nominal)||(ov->vi.bitrate_upper!=ov->vi.bitrate_nominal)?'V':'C');
- if(rg_gain || rg_peak)
- mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Gain = %+.2f dB, Peak = %.4f, Scale = %.2f\n", rg_gain, rg_peak, ov->rg_scale);
- mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Encoded by: %s\n",vc.vendor);
- }
- }
-
- vorbis_comment_clear(&vc);
-
-// printf("lower=%d upper=%d \n",(int)ov->vi.bitrate_lower,(int)ov->vi.bitrate_upper);
-
- // Setup the decoder
- sh->channels=ov->vi.channels;
- sh->samplerate=ov->vi.rate;
- sh->samplesize=2;
- // assume 128kbit if bitrate not specified in the header
- sh->i_bps=((ov->vi.bitrate_nominal>0) ? ov->vi.bitrate_nominal : 128000)/8;
- sh->context = ov;
-
- /// Finish the decoder init
- vorbis_synthesis_init(&ov->vd,&ov->vi);
- vorbis_block_init(&ov->vd,&ov->vb);
- mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Init OK!\n");
-
- return 1;
-}
-
-static void uninit(sh_audio_t *sh)
-{
- struct ov_struct_st *ov = sh->context;
- vorbis_dsp_clear(&ov->vd);
- vorbis_block_clear(&ov->vb);
- vorbis_info_clear(&ov->vi);
- free(ov);
-}
-
-static int control(sh_audio_t *sh,int cmd,void* arg, ...)
-{
- switch(cmd)
- {
-#if 0
- case ADCTRL_RESYNC_STREAM:
- return CONTROL_TRUE;
- case ADCTRL_SKIP_FRAME:
- return CONTROL_TRUE;
-#endif
- }
- return CONTROL_UNKNOWN;
-}
-
-static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
-{
- int len = 0;
- int samples;
-#ifdef CONFIG_TREMOR
- ogg_int32_t **pcm;
-#else
- float scale;
- float **pcm;
-#endif
- struct ov_struct_st *ov = sh->context;
- while(len < minlen) {
- while((samples=vorbis_synthesis_pcmout(&ov->vd,&pcm))<=0){
- ogg_packet op;
- double pts;
- memset(&op,0,sizeof(op)); //op.b_o_s = op.e_o_s = 0;
- op.bytes = ds_get_packet_pts(sh->ds,&op.packet, &pts);
- if(op.bytes<=0) break;
- if (pts != MP_NOPTS_VALUE) {
- sh->pts = pts;
- sh->pts_bytes = 0;
- }
- if(vorbis_synthesis(&ov->vb,&op)==0) /* test for success! */
- vorbis_synthesis_blockin(&ov->vd,&ov->vb);
- }
- if(samples<=0) break; // error/EOF
- while(samples>0){
- int i,j;
- int clipflag=0;
- int convsize=(maxlen-len)/(2*ov->vi.channels); // max size!
- int bout=((samples<convsize)?samples:convsize);
-
- if(bout<=0) break; // no buffer space
-
- /* convert floats to 16 bit signed ints (host order) and
- interleave */
-#ifdef CONFIG_TREMOR
- if (ov->rg_scale_int == 64) {
- for(i=0;i<ov->vi.channels;i++){
- ogg_int16_t *convbuffer=(ogg_int16_t *)(&buf[len]);
- ogg_int16_t *ptr=convbuffer+i;
- ogg_int32_t *mono=pcm[i];
- for(j=0;j<bout;j++){
- int val=mono[j]>>9;
- /* might as well guard against clipping */
- if(val>32767){
- val=32767;
- clipflag=1;
- }
- if(val<-32768){
- val=-32768;
- clipflag=1;
- }
- *ptr=val;
- ptr+=ov->vi.channels;
- }
- }
- } else
-#endif /* CONFIG_TREMOR */
- {
-#ifndef CONFIG_TREMOR
- scale = 32767.f * ov->rg_scale;
-#endif
- for(i=0;i<ov->vi.channels;i++){
- ogg_int16_t *convbuffer=(ogg_int16_t *)(&buf[len]);
- ogg_int16_t *ptr=convbuffer+i;
-#ifdef CONFIG_TREMOR
- ogg_int32_t *mono=pcm[i];
- for(j=0;j<bout;j++){
- int val=(mono[j]*ov->rg_scale_int)>>(9+6);
-#else
- float *mono=pcm[i];
- for(j=0;j<bout;j++){
- int val=mono[j]*scale;
- /* might as well guard against clipping */
- if(val>32767){
- val=32767;
- clipflag=1;
- }
- if(val<-32768){
- val=-32768;
- clipflag=1;
- }
-#endif /* CONFIG_TREMOR */
- *ptr=val;
- ptr+=ov->vi.channels;
- }
- }
- }
-
- if(clipflag)
- mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"Clipping in frame %ld\n",(long)(ov->vd.sequence));
- len+=2*ov->vi.channels*bout;
- sh->pts_bytes += 2*ov->vi.channels*bout;
- mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\n[decoded: %d / %d ]\n",bout,samples);
- samples-=bout;
- vorbis_synthesis_read(&ov->vd,bout); /* tell libvorbis how
- many samples we
- actually consumed */
- } //while(samples>0)
-// if (!samples) break; // why? how?
- }
-
- if (len > 0 && ov->vi.channels >= 5) {
- reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_VORBIS_DEFAULT,
- AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
- ov->vi.channels, len / sh->samplesize,
- sh->samplesize);
- }
-
-
- return len;
-}
diff --git a/libmpcodecs/ad_mpc.c b/libmpcodecs/ad_mpc.c
deleted file mode 100644
index 979dce6178..0000000000
--- a/libmpcodecs/ad_mpc.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Musepack audio files decoder for MPlayer
- * by Reza Jelveh <reza.jelveh@tuhh.de> and
- * Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>
- *
- * This code may be be relicensed under the terms of the GNU LGPL when it
- * becomes part of the FFmpeg project (ffmpeg.org)
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "ad_internal.h"
-#include "libaf/af_format.h"
-#include "libvo/fastmemcpy.h"
-
-static const ad_info_t info =
-{
- "Musepack audio decoder",
- "mpcdec",
- "Reza Jelveh and Reimar Döffinger",
- "",
- ""
-};
-
-LIBAD_EXTERN(libmusepack)
-
-#include <mpcdec/mpcdec.h>
-
-// BUFFER_LENGTH is in MPC_SAMPLE_FORMAT units
-#define MAX_FRAMESIZE (4 * MPC_DECODER_BUFFER_LENGTH)
-//! this many frames should decode good after seeking
-#define MIN_SEEK_GOOD 5
-//! how many frames to discard at most after seeking
-#define MAX_SEEK_DISCARD 50
-
-typedef struct context_s {
- char *header;
- int header_len;
- sh_audio_t *sh;
- uint32_t pos;
- mpc_decoder decoder;
-} context_t;
-
-/**
- * \brief mpc_reader callback function for reading the header
- */
-static mpc_int32_t cb_read(void *data, void *buf, mpc_int32_t size) {
- context_t *d = (context_t *)data;
- char *p = (char *)buf;
- int s = size;
- if (d->pos < d->header_len) {
- if (s > d->header_len - d->pos)
- s = d->header_len - d->pos;
- fast_memcpy(p, &d->header[d->pos], s);
- } else
- s = 0;
- memset(&p[s], 0, size - s);
- d->pos += size;
- return size;
-}
-
-/**
- * \brief dummy mpc_reader callback function for seeking
- */
-static mpc_bool_t cb_seek(void *data, mpc_int32_t offset ) {
- context_t *d = (context_t *)data;
- d->pos = offset;
- return 1;
-}
-
-/**
- * \brief dummy mpc_reader callback function for getting stream position
- */
-static mpc_int32_t cb_tell(void *data) {
- context_t *d = (context_t *)data;
- return d->pos;
-}
-
-/**
- * \brief dummy mpc_reader callback function for getting stream length
- */
-static mpc_int32_t cb_get_size(void *data) {
- return 1 << 30;
-}
-
-/**
- * \brief mpc_reader callback function, we cannot seek.
- */
-static mpc_bool_t cb_canseek(void *data) {
- return 0;
-}
-
-
-mpc_reader header_reader = {
- .read = cb_read, .seek = cb_seek, .tell = cb_tell,
- .get_size = cb_get_size, .canseek = cb_canseek
-};
-
-static int preinit(sh_audio_t *sh) {
- sh->audio_out_minsize = MAX_FRAMESIZE;
- return 1;
-}
-
-static void uninit(sh_audio_t *sh) {
- free(sh->context);
- sh->context = NULL;
-}
-
-static int init(sh_audio_t *sh) {
- mpc_streaminfo info;
- context_t *cd = malloc(sizeof(context_t));
-
- if (!sh->wf || (sh->wf->cbSize < 6 * 4)) {
- mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n");
- return 0;
- }
- cd->header = (char *)(sh->wf + 1);
- cd->header_len = sh->wf->cbSize;
- cd->sh = sh;
- cd->pos = 0;
- sh->context = (char *)cd;
-
- /* read file's streaminfo data */
- mpc_streaminfo_init(&info);
- header_reader.data = cd;
- if (mpc_streaminfo_read(&info, &header_reader) != ERROR_CODE_OK) {
- mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Not a valid musepack file.\n");
- return 0;
- }
-// this value is nonsense, since it relies on the get_size function.
-// use the value from the demuxer instead.
-// sh->i_bps = info.average_bitrate / 8;
- sh->channels = info.channels;
- sh->samplerate = info.sample_freq;
- sh->samplesize = 4;
- sh->sample_format =
-#if MPC_SAMPLE_FORMAT == float
- AF_FORMAT_FLOAT_NE;
-#elif MPC_SAMPLE_FORMAT == mpc_int32_t
- AF_FORMAT_S32_NE;
-#else
- #error musepack lib must use either float or mpc_int32_t sample format
-#endif
-
- mpc_decoder_setup(&cd->decoder, NULL);
- mpc_decoder_set_streaminfo(&cd->decoder, &info);
- return 1;
-}
-
-// FIXME: minlen is currently ignored
-static int decode_audio(sh_audio_t *sh, unsigned char *buf,
- int minlen, int maxlen) {
- int status, len;
- MPC_SAMPLE_FORMAT *sample_buffer = (MPC_SAMPLE_FORMAT *)buf;
- mpc_uint32_t *packet = NULL;
-
- context_t *cd = (context_t *) sh->context;
- if (maxlen < MAX_FRAMESIZE) {
- mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n");
- return -1;
- }
- len = ds_get_packet(sh->ds, (unsigned char **)&packet);
- if (len <= 0) return -1;
- status = mpc_decoder_decode_frame(&cd->decoder, packet, len, sample_buffer);
- if (status == -1) // decode error
- mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Error decoding file.\n");
- if (status <= 0) // error or EOF
- return -1;
-
- status = MPC_FRAME_LENGTH * sh->channels; // one sample per channel
-#if MPC_SAMPLE_FORMAT == float || MPC_SAMPLE_FORMAT == mpc_int32_t
- status *= 4;
-#else
- // should not happen
- status *= 2;
-#endif
- return status;
-}
-
-/**
- * \brief check if the decoded values are in a sane range
- * \param buf decoded buffer
- * \param len length of buffer in bytes
- * \return 1 if all values are in (-1.01, 1.01) range, 0 otherwise
- */
-static int check_clip(void *buf, int len) {
-#if MPC_SAMPLE_FORMAT == float
- float *p = buf;
- if (len < 4) return 1;
- len = -len / 4;
- p = &p[-len];
- do {
- if (p[len] < -1 || p[len] > 1) return 0;
- } while (++len);
-#endif
- return 1;
-}
-
-static int control(sh_audio_t *sh, int cmd, void* arg, ...) {
- if (cmd == ADCTRL_RESYNC_STREAM) {
- unsigned char *buf = malloc(MAX_FRAMESIZE);
- int i;
- int nr_ok = 0;
- for (i = 0; i < MAX_SEEK_DISCARD; i++) {
- int len = decode_audio(sh, buf, 0, MAX_FRAMESIZE);
- if (check_clip(buf, len)) nr_ok++; else nr_ok = 0;
- if (nr_ok > MIN_SEEK_GOOD) break;
- }
- free(buf);
- }
- return CONTROL_UNKNOWN;
-}
diff --git a/libmpcodecs/ad_speex.c b/libmpcodecs/ad_speex.c
deleted file mode 100644
index c9ac1a42c6..0000000000
--- a/libmpcodecs/ad_speex.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Speex decoder by Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>
- *
- * This code may be be relicensed under the terms of the GNU LGPL when it
- * becomes part of the FFmpeg project (ffmpeg.org)
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-#include <stdlib.h>
-#include <speex/speex.h>
-#include <speex/speex_stereo.h>
-#include <speex/speex_header.h>
-#include "ad_internal.h"
-
-static const ad_info_t info = {
- "Speex audio decoder",
- "speex",
- "Reimar Döffinger",
- "",
- ""
-};
-
-LIBAD_EXTERN(speex)
-
-typedef struct {
- SpeexBits bits;
- void *dec_context;
- SpeexStereoState stereo;
- SpeexHeader *hdr;
-} context_t;
-
-#define MAX_FRAMES_PER_PACKET 100
-
-static int preinit(sh_audio_t *sh) {
- sh->audio_out_minsize = 2 * 320 * MAX_FRAMES_PER_PACKET * 2 * sizeof(short);
- return 1;
-}
-
-static int read_le32(const uint8_t **src) {
- const uint8_t *p = *src;
- *src += 4;
- return p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
-}
-
-static int init(sh_audio_t *sh) {
- context_t *ctx = calloc(1, sizeof(context_t));
- const uint8_t *hdr = (const uint8_t *)(sh->wf + 1);
- const SpeexMode *spx_mode;
- const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT; // hack
- if (sh->wf && sh->wf->cbSize >= 80)
- ctx->hdr = speex_packet_to_header((char *)&sh->wf[1], sh->wf->cbSize);
- if (!ctx->hdr && sh->wf->cbSize == 0x72 && hdr[0] == 1 && hdr[1] == 0) {
- // speex.acm format: raw SpeexHeader dump
- ctx->hdr = calloc(1, sizeof(*ctx->hdr));
- hdr += 2;
- hdr += 8; // identifier string
- hdr += 20; // version string
- ctx->hdr->speex_version_id = read_le32(&hdr);
- ctx->hdr->header_size = read_le32(&hdr);
- ctx->hdr->rate = read_le32(&hdr);
- ctx->hdr->mode = read_le32(&hdr);
- ctx->hdr->mode_bitstream_version = read_le32(&hdr);
- ctx->hdr->nb_channels = read_le32(&hdr);
- ctx->hdr->bitrate = read_le32(&hdr);
- ctx->hdr->frame_size = read_le32(&hdr);
- ctx->hdr->vbr = read_le32(&hdr);
- ctx->hdr->frames_per_packet = read_le32(&hdr);
- }
- if (!ctx->hdr) {
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Invalid or missing extradata! Assuming defaults.\n");
- ctx->hdr = calloc(1, sizeof(*ctx->hdr));
- ctx->hdr->frames_per_packet = 1;
- ctx->hdr->mode = 0;
- if (sh->wf) {
- ctx->hdr->nb_channels = sh->wf->nChannels;
- ctx->hdr->rate = sh->wf->nSamplesPerSec;
- if (ctx->hdr->rate > 16000)
- ctx->hdr->mode = 2;
- else if (ctx->hdr->rate > 8000)
- ctx->hdr->mode = 1;
- }
- }
- if (ctx->hdr->nb_channels != 1 && ctx->hdr->nb_channels != 2) {
- mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of channels (%i), "
- "assuming mono\n", ctx->hdr->nb_channels);
- ctx->hdr->nb_channels = 1;
- }
- if (ctx->hdr->frames_per_packet > MAX_FRAMES_PER_PACKET) {
- mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of frames per packet (%i), "
- "assuming 1\n", ctx->hdr->frames_per_packet);
- ctx->hdr->frames_per_packet = 1;
- }
- switch (ctx->hdr->mode) {
- case 0:
- spx_mode = &speex_nb_mode; break;
- case 1:
- spx_mode = &speex_wb_mode; break;
- case 2:
- spx_mode = &speex_uwb_mode; break;
- default:
- mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Unknown speex mode (%i)\n", ctx->hdr->mode);
- spx_mode = &speex_nb_mode;
- }
- ctx->dec_context = speex_decoder_init(spx_mode);
- speex_bits_init(&ctx->bits);
- memcpy(&ctx->stereo, &st_st, sizeof(ctx->stereo)); // hack part 2
- sh->channels = ctx->hdr->nb_channels;
- sh->samplerate = ctx->hdr->rate;
- sh->samplesize = 2;
- sh->sample_format = AF_FORMAT_S16_NE;
- sh->context = ctx;
- return 1;
-}
-
-static void uninit(sh_audio_t *sh) {
- context_t *ctx = sh->context;
- if (ctx) {
- speex_bits_destroy(&ctx->bits);
- speex_decoder_destroy(ctx->dec_context);
- free(ctx->hdr);
- free(ctx);
- }
- ctx = NULL;
-}
-
-static int decode_audio(sh_audio_t *sh, unsigned char *buf,
- int minlen, int maxlen) {
- double pts;
- context_t *ctx = sh->context;
- int len, framelen, framesamples;
- char *packet;
- int i, err;
- speex_decoder_ctl(ctx->dec_context, SPEEX_GET_FRAME_SIZE, &framesamples);
- framelen = framesamples * ctx->hdr->nb_channels * sizeof(short);
- if (maxlen < ctx->hdr->frames_per_packet * framelen) {
- mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n");
- return -1;
- }
- len = ds_get_packet_pts(sh->ds, (unsigned char **)&packet, &pts);
- if (len <= 0) return -1;
- if (sh->pts == MP_NOPTS_VALUE)
- sh->pts = 0;
- if (pts != MP_NOPTS_VALUE) {
- sh->pts = pts;
- sh->pts_bytes = 0;
- }
- speex_bits_read_from(&ctx->bits, packet, len);
- i = ctx->hdr->frames_per_packet;
- do {
- err = speex_decode_int(ctx->dec_context, &ctx->bits, (short *)buf);
- if (err == -2)
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error decoding file.\n");
- if (ctx->hdr->nb_channels == 2)
- speex_decode_stereo_int((short *)buf, framesamples, &ctx->stereo);
- buf = &buf[framelen];
- } while (--i > 0);
- sh->pts_bytes += ctx->hdr->frames_per_packet * framelen;
- return ctx->hdr->frames_per_packet * framelen;
-}
-
-static int control(sh_audio_t *sh, int cmd, void *arg, ...) {
- return CONTROL_UNKNOWN;
-}
diff --git a/libmpcodecs/ad_twin.c b/libmpcodecs/ad_twin.c
deleted file mode 100644
index 9aa304e4fc..0000000000
--- a/libmpcodecs/ad_twin.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "config.h"
-
-#include "ad_internal.h"
-#include "vqf.h"
-#include "libmpdemux/aviprint.h"
-#include "loader/ldt_keeper.h"
-#include "loader/wine/windef.h"
-#include "libaf/af_format.h"
-
-
-static const ad_info_t info =
-{
- "TWinVQ decoder",
- "vqf",
- "Roberto Togni",
- "Nick Kurshev",
- "Ported from MPlayerXP"
-};
-
-LIBAD_EXTERN(twin)
-
-void* WINAPI LoadLibraryA(char* name);
-void* WINAPI GetProcAddress(void* handle, char* func);
-int WINAPI FreeLibrary(void* handle);
-
-static int (*TvqInitialize)( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox );
-static void (*TvqTerminate)( INDEX *index );
-static void (*TvqGetVectorInfo)(int *bits0[], int *bits1[]);
-
-static void (*TvqDecodeFrame)(INDEX *indexp, float out[]);
-static int (*TvqWtypeToBtype)( int w_type, int *btype );
-static void (*TvqUpdateVectorInfo)(int varbits, int *ndiv, int bits0[], int bits1[]);
-
-static int (*TvqCheckVersion)(char *versionID);
-static void (*TvqGetConfInfo)(tvqConfInfo *cf);
-static int (*TvqGetFrameSize)(void);
-static int (*TvqGetNumFixedBitsPerFrame)(void);
-
-#define BYTE_BIT 8
-#define BBUFSIZ 1024 /* Bit buffer size (bytes) */
-#define BBUFLEN (BBUFSIZ*BYTE_BIT) /* Bit buffer length (bits) */
-typedef struct vqf_priv_s
-{
- float pts;
- WAVEFORMATEX o_wf; // out format
- INDEX index;
- tvqConfInfo cf;
- headerInfo hi;
- int *bits_0[N_INTR_TYPE], *bits_1[N_INTR_TYPE];
- unsigned framesize;
- /* stream related */
- int readable;
- int ptr; /* current point in the bit buffer */
- int nbuf; /* bit buffer size */
- char buf[BBUFSIZ]; /* the bit buffer */
- int skip_cnt;
-}vqf_priv_t;
-
-static void* vqf_dll;
-
-static int load_dll( char *libname )
-{
-#ifdef WIN32_LOADER
- Setup_LDT_Keeper();
-#endif
- vqf_dll = LoadLibraryA(libname);
- if( vqf_dll == NULL )
- {
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "failed loading dll\n" );
- return 0;
- }
- TvqInitialize = GetProcAddress(vqf_dll,"TvqInitialize");
- TvqTerminate = GetProcAddress(vqf_dll,"TvqTerminate");
- TvqGetVectorInfo = GetProcAddress(vqf_dll,"TvqGetVectorInfo");
- TvqDecodeFrame = GetProcAddress(vqf_dll,"TvqDecodeFrame");
- TvqWtypeToBtype = GetProcAddress(vqf_dll,"TvqWtypeToBtype");
- TvqUpdateVectorInfo = GetProcAddress(vqf_dll,"TvqUpdateVectorInfo");
- TvqCheckVersion = GetProcAddress(vqf_dll,"TvqCheckVersion");
- TvqGetConfInfo = GetProcAddress(vqf_dll,"TvqGetConfInfo");
- TvqGetFrameSize = GetProcAddress(vqf_dll,"TvqGetFrameSize");
- TvqGetNumFixedBitsPerFrame = GetProcAddress(vqf_dll,"TvqGetNumFixedBitsPerFrame");
- return TvqInitialize && TvqTerminate && TvqGetVectorInfo &&
- TvqDecodeFrame && TvqWtypeToBtype && TvqUpdateVectorInfo &&
- TvqCheckVersion && TvqGetConfInfo && TvqGetFrameSize &&
- TvqGetNumFixedBitsPerFrame;
-}
-
-static int init_vqf_audio_codec(sh_audio_t *sh_audio){
- WAVEFORMATEX *in_fmt=sh_audio->wf;
- vqf_priv_t*priv=sh_audio->context;
- int ver;
- mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n");
-
- sh_audio->channels=in_fmt->nChannels;
- sh_audio->samplerate=in_fmt->nSamplesPerSec;
- sh_audio->sample_format=AF_FORMAT_S16_NE;
-// sh_audio->sample_format=AF_FORMAT_FLOAT_NE;
- sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8;
- priv->o_wf.nChannels=in_fmt->nChannels;
- priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec;
- priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels;
- priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels;
- priv->o_wf.wFormatTag=0x01;
- priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample;
- priv->o_wf.cbSize=0;
-
- if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) )
- {
- mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n");
- print_wave_header(in_fmt, MSGL_V);
- mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n");
- print_wave_header(&priv->o_wf, MSGL_V);
- }
- memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo));
- if((ver=TvqInitialize(&priv->hi,&priv->index,0))){
- const char *tvqe[]={
- "No errors",
- "General error",
- "Wrong version",
- "Channel setting error",
- "Wrong coding mode",
- "Inner parameter setting error",
- "Wrong number of VQ pre-selection candidates, used only in encoder" };
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown");
- return 0;
- }
- ver=TvqCheckVersion(priv->hi.ID);
- if(ver==TVQ_UNKNOWN_VERSION){
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" );
- return 0;
- }
- TvqGetConfInfo(&priv->cf);
- TvqGetVectorInfo(priv->bits_0,priv->bits_1);
- priv->framesize=TvqGetFrameSize();
- sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels;
- sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize;
- sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size);
- sh_audio->a_in_buffer_len=0;
-
-
- return 1;
-}
-
-static int close_vqf_audio_codec(sh_audio_t *sh_audio)
-{
- vqf_priv_t*priv=sh_audio->context;
- TvqTerminate(&priv->index);
- return 1;
-}
-
-int init(sh_audio_t *sh_audio)
-{
- return 1;
-}
-
-int preinit(sh_audio_t *sh_audio)
-{
- /* Win32 VQF audio codec: */
- vqf_priv_t *priv;
- if(!(sh_audio->context=malloc(sizeof(vqf_priv_t)))) return 0;
- priv=sh_audio->context;
- if(!load_dll(sh_audio->codec->dll))
- {
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "win32.dll looks broken :(\n");
- return 0;
- }
- if(!init_vqf_audio_codec(sh_audio)){
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "TWinVQ initialization fail\n");
- return 0;
- }
- mp_msg(MSGT_DECAUDIO, MSGL_INFO, "INFO: TWinVQ (%s) audio codec init OK!\n",sh_audio->codec->dll);
- priv->skip_cnt = 2;
- return 1;
-}
-
-void uninit(sh_audio_t *sh)
-{
- close_vqf_audio_codec(sh);
- free(sh->context);
- FreeLibrary(vqf_dll);
-}
-
-static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
-{
- switch(cmd) {
- case ADCTRL_QUERY_FORMAT:
- return CONTROL_TRUE;
- default:
- return CONTROL_UNKNOWN;
- }
-}
-
-static int bread(char *data, /* Output: Output data array */
- int size, /* Input: Length of each data */
- int nbits, /* Input: Number of bits to write */
- sh_audio_t *sh) /* Input: File pointer */
-{
- /*--- Variables ---*/
- int ibits, iptr, idata, ibufadr, ibufbit, icl;
- unsigned char mask, tmpdat;
- int retval;
- vqf_priv_t *priv=sh->context;
-
- /*--- Main operation ---*/
- retval = 0;
- mask = 0x1;
- for ( ibits=0; ibits<nbits; ibits++ ){
- if ( priv->readable == 0 ){ /* when the file data buffer is empty */
- priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ);
- priv->nbuf *= 8;
- priv->readable = 1;
- }
- iptr = priv->ptr; /* current file data buffer pointer */
- if ( iptr >= priv->nbuf ) /* If data file is empty then return */
- return retval;
- ibufadr = iptr/BYTE_BIT; /* current file data buffer address */
- ibufbit = iptr%BYTE_BIT; /* current file data buffer bit */
- /* tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */
- tmpdat = (unsigned char)priv->buf[ibufadr];
- tmpdat >>= (BYTE_BIT-ibufbit-1);
- /* current data bit */
-
- idata = ibits*size; /* output data address */
- data[idata] = (char)(tmpdat & mask); /* set output data */
- for (icl=1; icl<size; icl++)
- data[idata+icl] = 0; /* clear the rest output data buffer */
- priv->ptr += 1; /* update data buffer pointer */
- if (priv->ptr == BBUFLEN){
- priv->ptr = 0;
- priv->readable = 0;
- }
- ++retval;
- }
- return retval;
-}
-
-#define BITS_INT (sizeof(int)*8)
-
-static int get_bstm(int *data, /* Input: input data */
- unsigned nbits, /* Input: number of bits */
- sh_audio_t *sh) /* Input: bit file pointer */
-{
- unsigned ibit;
- unsigned mask;
- unsigned work;
- char tmpbit[BITS_INT];
- int retval;
-
- if ( nbits > BITS_INT ){
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "get_bstm(): %d: %d Error.\n",
- nbits, BITS_INT);
- exit(1);
- }
- retval = bread(tmpbit, sizeof(*tmpbit), nbits, sh);
- for (ibit=retval; ibit<nbits; ibit++){
- tmpbit[ibit] = 0;
- }
- mask = 0x1<<(nbits-1);
- work=0;
- for ( ibit=0; ibit<nbits; ibit++ ){
- work += mask*tmpbit[ibit];
- mask >>= 1;
- }
- *data = work;
- return retval;
-}
-
-static int GetVqInfo( tvqConfInfoSubBlock *cfg,
- int bits0[],
- int bits1[],
- int variableBits,
- INDEX *index,
- sh_audio_t *sh)
-{
- int idiv;
- int bitcount = 0;
-
- if ( index->btype == BLK_LONG ){
- TvqUpdateVectorInfo( variableBits, &cfg->ndiv, bits0, bits1 ); // re-calculate VQ bits
- }
- for ( idiv=0; idiv<cfg->ndiv; idiv++ ){
- bitcount += get_bstm(&index->wvq[idiv],bits0[idiv],sh); /* CB 0 */
- bitcount += get_bstm(&index->wvq[idiv+cfg->ndiv],bits1[idiv],sh); /* CB 1 */
- }
- return bitcount;
-}
-
-static int GetBseInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh)
-{
- int i_sup, isf, itmp, idiv;
- int bitcount = 0;
-
- for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
- for ( isf=0; isf<cfg->nsf; isf++ ){
- for ( idiv=0; idiv<cfg->fw_ndiv; idiv++ ){
- itmp = idiv + ( isf + i_sup * cfg->nsf ) * cfg->fw_ndiv;
- bitcount += get_bstm(&index->fw[itmp],cfg->fw_nbit,sh);
- }
- }
- }
- for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
- for ( isf=0; isf<cfg->nsf; isf++ ){
- bitcount += get_bstm(&index->fw_alf[i_sup * cfg->nsf + isf],cf->FW_ARSW_BITS,sh);
- }
- }
- return bitcount;
-}
-
-static int GetGainInfo(tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh )
-{
- int i_sup, iptop, isf;
- int bitcount = 0;
-
- for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
- iptop = ( cfg->nsubg + 1 ) * i_sup;
- bitcount += get_bstm(&index->pow[iptop], cf->GAIN_BITS,sh);
- for ( isf=0; isf<cfg->nsubg; isf++ ){
- bitcount += get_bstm(&index->pow[iptop+isf+1], cf->SUB_GAIN_BITS,sh);
- }
- }
- return bitcount;
-}
-
-static int GetLspInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh )
-{
- int i_sup, itmp;
- int bitcount = 0;
-
- for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
- bitcount += get_bstm(&index->lsp[i_sup][0], cf->LSP_BIT0,sh); /* pred. switch */
- bitcount += get_bstm(&index->lsp[i_sup][1], cf->LSP_BIT1,sh); /* first stage */
- for ( itmp=0; itmp<cf->LSP_SPLIT; itmp++ ){ /* second stage */
- bitcount += get_bstm(&index->lsp[i_sup][itmp+2], cf->LSP_BIT2,sh);
- }
- }
-
- return bitcount;
-}
-
-static int GetPpcInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh)
-{
- int idiv, i_sup;
- int bitcount = 0;
- vqf_priv_t*priv=sh->context;
-
- for ( idiv=0; idiv<cf->N_DIV_P; idiv++ ){
- bitcount += get_bstm(&(index->pls[idiv]), priv->bits_0[BLK_PPC][idiv],sh); /*CB0*/
- bitcount += get_bstm(&(index->pls[idiv+cf->N_DIV_P]), priv->bits_1[BLK_PPC][idiv],sh);/*CB1*/
- }
- for (i_sup=0; i_sup<cf->N_CH; i_sup++){
- bitcount += get_bstm(&(index->pit[i_sup]), cf->BASF_BIT,sh);
- bitcount += get_bstm(&(index->pgain[i_sup]), cf->PGAIN_BIT,sh);
- }
-
- return bitcount;
-}
-
-static int GetEbcInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh)
-{
- int i_sup, isf, itmp;
- int bitcount = 0;
-
- for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
- for ( isf=0; isf<cfg->nsf; isf++){
- int indexSfOffset = isf * ( cfg->ncrb - cfg->ebc_crb_base ) - cfg->ebc_crb_base;
- for ( itmp=cfg->ebc_crb_base; itmp<cfg->ncrb; itmp++ ){
- bitcount += get_bstm(&index->bc[i_sup][itmp+indexSfOffset], cfg->ebc_bits,sh);
- }
- }
- }
-
- return bitcount;
-}
-
-static int vqf_read_frame(sh_audio_t *sh,INDEX *index)
-{
- /*--- Variables ---*/
- tvqConfInfoSubBlock *cfg;
- int variableBits;
- int bitcount;
- int numFixedBitsPerFrame = TvqGetNumFixedBitsPerFrame();
- int btype;
- vqf_priv_t *priv=sh->context;
-
- /*--- Initialization ---*/
- variableBits = 0;
- bitcount = 0;
-
- /*--- read block independent factors ---*/
- /* Window type */
- bitcount += get_bstm( &index->w_type, priv->cf.BITS_WTYPE, sh );
- if ( TvqWtypeToBtype( index->w_type, &index->btype ) ) {
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error: unknown window type: %d\n", index->w_type);
- return 0;
- }
- btype = index->btype;
-
- /*--- read block dependent factors ---*/
- cfg = &priv->cf.cfg[btype]; // set the block dependent paremeters table
-
- bitcount += variableBits;
-
- /* Interleaved vector quantization */
- bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh );
-
- /* Bark-scale envelope */
- bitcount += GetBseInfo( &priv->cf, cfg, index, sh );
- /* Gain */
- bitcount += GetGainInfo( &priv->cf, cfg, index, sh );
- /* LSP */
- bitcount += GetLspInfo( &priv->cf, index, sh );
- /* PPC */
- if ( cfg->ppc_enable ){
- bitcount += GetPpcInfo( &priv->cf, index, sh );
- }
- /* Energy Balance Calibration */
- if ( cfg->ebc_enable ){
- bitcount += GetEbcInfo( &priv->cf, cfg, index, sh );
- }
-
- return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0;
-}
-
-static void frtobuf_s16(float out[], /* Input --- input data frame */
- short bufout[], /* Output --- output data buffer array */
- unsigned frameSize, /* Input --- frame size */
- unsigned numChannels) /* Input --- number of channels */
-{
- /*--- Variables ---*/
- unsigned ismp, ich;
- float *ptr;
- float dtmp;
-
- for ( ich=0; ich<numChannels; ich++ ){
- ptr = out+ich*frameSize;
- for ( ismp=0; ismp<frameSize; ismp++ ){
- dtmp = ptr[ismp];
- if ( dtmp >= 0. ) {
- if ( dtmp > 32700. )
- dtmp = 32700.;
- bufout[ismp*numChannels+ich] = (short)(dtmp+0.5);
- } else {
- if ( dtmp < -32700. )
- dtmp = -32700.;
- bufout[ismp*numChannels+ich] = (short)(dtmp-0.5);
- }
- }
- }
-}
-
-static void frtobuf_float(float out[], /* Input --- input data frame */
- float bufout[], /* Output --- output data buffer array */
- unsigned frameSize, /* Input --- frame size */
- unsigned numChannels) /* Input --- number of channels */
-{
- /*--- Variables ---*/
- unsigned ismp, ich;
- float *ptr;
- float dtmp;
-
- for ( ich=0; ich<numChannels; ich++ ){
- ptr = out+ich*frameSize;
- for ( ismp=0; ismp<frameSize; ismp++ ){
- dtmp = ptr[ismp];
- if ( dtmp >= 0. ) {
- if ( dtmp > 32700. )
- dtmp = 32700.;
- bufout[ismp*numChannels+ich] = dtmp/32767.;
- } else {
- if ( dtmp < -32700. )
- dtmp = -32700.;
- bufout[ismp*numChannels+ich] = dtmp/32767.;
- }
- }
- }
-}
-
-int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
-{
- int l, len=0;
- vqf_priv_t *priv=sh_audio->context;
- while(len<minlen)
- {
- float out[priv->framesize*sh_audio->channels];
- l=vqf_read_frame(sh_audio,&priv->index);
- if(!l) break;
- TvqDecodeFrame(&priv->index, out);
- if (priv->skip_cnt) {
- // Ingnore first two frames, replace them with silence
- priv->skip_cnt--;
- memset(buf, 0, priv->framesize*sh_audio->channels*sh_audio->samplesize);
- } else {
- if (sh_audio->sample_format == AF_FORMAT_S16_NE)
- frtobuf_s16(out, (short *)buf, priv->framesize, sh_audio->channels);
- else
- frtobuf_float(out, (float *)buf, priv->framesize, sh_audio->channels);
- }
- len += priv->framesize*sh_audio->channels*sh_audio->samplesize;
- buf += priv->framesize*sh_audio->channels*sh_audio->samplesize;
- }
- return len;
-}
diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c
index a221a089b4..804b4d60b4 100644
--- a/libmpcodecs/dec_video.c
+++ b/libmpcodecs/dec_video.c
@@ -31,7 +31,6 @@
#include "stream/stream.h"
#include "libmpdemux/demuxer.h"
-#include "libmpdemux/parse_es.h"
#include "codec-cfg.h"
diff --git a/libmpcodecs/vd.c b/libmpcodecs/vd.c
index c01796ac78..e7a497009a 100644
--- a/libmpcodecs/vd.c
+++ b/libmpcodecs/vd.c
@@ -39,7 +39,6 @@
extern const vd_functions_t mpcodecs_vd_null;
extern const vd_functions_t mpcodecs_vd_ffmpeg;
-extern const vd_functions_t mpcodecs_vd_theora;
extern const vd_functions_t mpcodecs_vd_dshow;
extern const vd_functions_t mpcodecs_vd_dmo;
extern const vd_functions_t mpcodecs_vd_vfw;
@@ -50,10 +49,7 @@ extern const vd_functions_t mpcodecs_vd_xanim;
extern const vd_functions_t mpcodecs_vd_mpng;
extern const vd_functions_t mpcodecs_vd_ijpg;
extern const vd_functions_t mpcodecs_vd_mtga;
-extern const vd_functions_t mpcodecs_vd_sgi;
-extern const vd_functions_t mpcodecs_vd_mpegpes;
extern const vd_functions_t mpcodecs_vd_realvid;
-extern const vd_functions_t mpcodecs_vd_xvid;
extern const vd_functions_t mpcodecs_vd_libdv;
extern const vd_functions_t mpcodecs_vd_lzo;
extern const vd_functions_t mpcodecs_vd_qtvideo;
@@ -65,9 +61,6 @@ extern const vd_functions_t mpcodecs_vd_qtvideo;
const vd_functions_t * const mpcodecs_vd_drivers[] = {
&mpcodecs_vd_null,
&mpcodecs_vd_ffmpeg,
-#ifdef CONFIG_OGGTHEORA
- &mpcodecs_vd_theora,
-#endif
#ifdef CONFIG_WIN32DLL
&mpcodecs_vd_dshow,
&mpcodecs_vd_dmo,
@@ -87,14 +80,9 @@ const vd_functions_t * const mpcodecs_vd_drivers[] = {
&mpcodecs_vd_ijpg,
#endif
&mpcodecs_vd_mtga,
- &mpcodecs_vd_sgi,
- &mpcodecs_vd_mpegpes,
#ifdef CONFIG_REALCODECS
&mpcodecs_vd_realvid,
#endif
-#ifdef CONFIG_XVID4
- &mpcodecs_vd_xvid,
-#endif
#ifdef CONFIG_LIBDV095
&mpcodecs_vd_libdv,
#endif
diff --git a/libmpcodecs/vd_mpegpes.c b/libmpcodecs/vd_mpegpes.c
deleted file mode 100644
index 22060bfc60..0000000000
--- a/libmpcodecs/vd_mpegpes.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "libmpdemux/mpeg_hdr.h"
-
-#include "vd_internal.h"
-
-static const vd_info_t info =
-{
- "MPEG 1/2 Video passthrough",
- "mpegpes",
- "A'rpi",
- "A'rpi",
- "for hw decoders"
-};
-
-LIBVD_EXTERN(mpegpes)
-
-//#include "libmpdemux/parse_es.h"
-
-#include "libvo/video_out.h"
-
-// to set/get/query special features/parameters
-static int control(sh_video_t *sh,int cmd,void* arg,...){
- return CONTROL_UNKNOWN;
-}
-
-// init driver
-static int init(sh_video_t *sh){
- return mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_MPEGPES);
-}
-
-// uninit driver
-static void uninit(sh_video_t *sh){
-}
-
-// decode a frame
-static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
- mp_image_t* mpi;
- static vo_mpegpes_t packet;
- mp_mpeg_header_t picture;
- const unsigned char *d = data;
-
- if(len>10 && !d[0] && !d[1] && d[2]==1 && d[3]==0xB3) {
- float old_aspect = sh->aspect;
- int oldw = sh->disp_w, oldh = sh->disp_h;
- mp_header_process_sequence_header(&picture, &d[4]);
- sh->aspect = mpeg12_aspect_info(&picture);
- sh->disp_w = picture.display_picture_width;
- sh->disp_h = picture.display_picture_height;
- if(sh->aspect != old_aspect || sh->disp_w != oldw || sh->disp_h != oldh) {
- if(!mpcodecs_config_vo(sh, sh->disp_w,sh->disp_h,IMGFMT_MPEGPES))
- return 0;
- }
- }
-
- mpi=mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, sh->disp_w, sh->disp_h);
- packet.data=data;
- packet.size=len;
- packet.timestamp=sh->timer*90000.0;
- packet.id=0x1E0; //+sh_video->ds->id;
- mpi->planes[0]=(uint8_t*)(&packet);
- return mpi;
-}
diff --git a/libmpcodecs/vd_sgi.c b/libmpcodecs/vd_sgi.c
deleted file mode 100644
index 1ec9b2e868..0000000000
--- a/libmpcodecs/vd_sgi.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2003 Todd Kirby <slapcat@pacbell.net>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <libavutil/intreadwrite.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "mpbswap.h"
-#include "vd_internal.h"
-
-#define SGI_HEADER_LEN 512
-#define SGI_MAGIC 474
-
-#define SGI_GRAYSCALE_IMAGE 1
-#define SGI_RGB_IMAGE 3
-#define SGI_RGBA_IMAGE 4
-
-#define OUT_PIXEL_STRIDE 3 /* RGB */
-
-
-static const vd_info_t info =
-{
- "SGI Image decoder",
- "sgi",
- "Todd Kirby",
- "Todd Kirby",
- ""
-};
-
-LIBVD_EXTERN(sgi)
-
-typedef struct {
- short magic;
- char rle;
- char bytes_per_channel;
- unsigned short dimension;
- unsigned short xsize;
- unsigned short ysize;
- unsigned short zsize;
-} SGIInfo;
-
-static unsigned int outfmt = IMGFMT_BGR24;
-
-static unsigned short last_x = -1;
-static unsigned short last_y = -1;
-
-
-/* to set/get/query special features/parameters */
-static int
-control(sh_video_t* sh, int cmd, void *arg, ...)
-{
- switch (cmd)
- {
- case VDCTRL_QUERY_FORMAT:
- if (*((unsigned int *) arg) == outfmt) {
- return CONTROL_TRUE;
- }
- return CONTROL_FALSE;
- }
- return CONTROL_UNKNOWN;
-}
-
-
-/* init driver */
-static int
-init(sh_video_t *sh)
-{
- sh->context = calloc(1, sizeof(SGIInfo));
- last_x = -1;
-
- return 1;
-}
-
-
-/* uninit driver */
-static void
-uninit(sh_video_t *sh)
-{
- SGIInfo *info = sh->context;
- free(info);
-}
-
-
-/* expand an rle row into a channel */
-static void
-expandrow(unsigned char *optr, unsigned char *iptr, int chan_offset)
-{
- unsigned char pixel, count;
- optr += chan_offset;
-
- while (1) {
- pixel = *iptr++;
-
- if (!(count = (pixel & 0x7f))) {
- return;
- }
- if(pixel & 0x80) {
- while (count--) {
- *optr = *iptr;
- optr += OUT_PIXEL_STRIDE;
- iptr++;
- }
- } else {
- pixel = *iptr++;
-
- while (count--) {
- *optr = pixel;
- optr += OUT_PIXEL_STRIDE;
- }
- }
- }
-}
-
-
-/* expand an rle row into all 3 channels.
- a separate function for grayscale so we don't slow down the
- more common case rgb function with a bunch of ifs. */
-static void
-expandrow_gs(unsigned char *optr, unsigned char *iptr)
-{
- unsigned char pixel, count;
-
- while (1) {
- pixel = *iptr++;
-
- if (!(count = (pixel & 0x7f))) {
- return;
- }
- if(pixel & 0x80) {
- while (count--) {
- optr[0] = *iptr;
- optr[1] = *iptr;
- optr[2] = *iptr;
- optr += OUT_PIXEL_STRIDE;
- iptr++;
- }
- } else {
- pixel = *iptr++;
-
- while (count--) {
- optr[0] = pixel;
- optr[1] = pixel;
- optr[2] = pixel;
- optr += OUT_PIXEL_STRIDE;
- }
- }
- }
-}
-
-
-/* decode a run length encoded sgi image */
-static void
-decode_rle_sgi(SGIInfo *info, unsigned char *data, mp_image_t *mpi)
-{
- unsigned char *rle_data, *dest_row;
- uint32_t *starttab;
- int y, z, ysize, zsize, chan_offset;
- long start_offset;
-
- ysize = info->ysize;
- zsize = info->zsize;
-
- /* rle offset table is right after the header */
- starttab = (uint32_t*)(data + SGI_HEADER_LEN);
-
- for (z = 0; z < zsize; z++) {
-
- /* set chan_offset so RGB ends up BGR */
- chan_offset = (zsize - 1) - z;
-
- /* The origin for SGI images is the lower-left corner
- so read scan lines from bottom to top */
- for (y = ysize - 1; y >= 0; y--) {
- dest_row = mpi->planes[0] + mpi->stride[0] * (ysize - 1 - y);
-
- /* set start of next run (offsets are from start of header) */
- start_offset = AV_RB32(&starttab[y + z * ysize]);
-
- rle_data = &data[start_offset];
-
- if(info->zsize == SGI_GRAYSCALE_IMAGE) {
- expandrow_gs(dest_row, rle_data);
- } else {
- expandrow(dest_row, rle_data, chan_offset);
- }
- }
- }
-}
-
-
-/* decode an sgi image */
-static void
-decode_uncompressed_sgi(SGIInfo *info, unsigned char *data, mp_image_t *mpi)
-{
- unsigned char *src_row, *dest_row;
- int x, y, z, xsize, ysize, zsize, chan_offset;
-
- xsize = info->xsize;
- ysize = info->ysize;
- zsize = info->zsize;
-
- /* skip header */
- data += SGI_HEADER_LEN;
-
- for (z = 0; z < zsize; z++) {
-
- /* set row ptr to start of current plane */
- src_row = data + (xsize * ysize * z);
-
- /* set chan_offset for RGB -> BGR */
- chan_offset = (zsize - 1) - z;
-
- /* the origin for SGI images is the lower-left corner
- so read scan lines from bottom to top. */
- for (y = ysize - 1; y >= 0; y--) {
- dest_row = mpi->planes[0] + mpi->stride[0] * y;
- for (x = 0; x < xsize; x++) {
-
- /* we only do 24 bit output so promote 8 bit pixels to 24 */
- if (zsize == SGI_GRAYSCALE_IMAGE) {
- /* write greyscale value into all channels */
- dest_row[0] = src_row[x];
- dest_row[1] = src_row[x];
- dest_row[2] = src_row[x];
- } else {
- dest_row[chan_offset] = src_row[x];
- }
-
- dest_row += OUT_PIXEL_STRIDE;
- }
-
- /* move to next row of the current source plane */
- src_row += xsize;
- }
- }
-}
-
-
-/* read sgi header fields */
-static void
-read_sgi_header(unsigned char *buf, SGIInfo *info)
-{
- /* sgi data is always stored in big endian byte order */
- info->magic = AV_RB16(&buf[0]);
- info->rle = buf[2];
- info->bytes_per_channel = buf[3];
- info->dimension = AV_RB16(&buf[4]);
- info->xsize = AV_RB16(&buf[6]);
- info->ysize = AV_RB16(&buf[8]);
- info->zsize = AV_RB16(&buf[10]);
-}
-
-
-/* decode a frame */
-static
-mp_image_t *decode(sh_video_t *sh, void *raw, int len, int flags)
-{
- SGIInfo *info = sh->context;
- unsigned char *data = raw;
- mp_image_t *mpi;
-
- if (len <= 0) {
- return NULL; /* skip frame */
- }
-
- read_sgi_header(data, info);
-
- /* make sure this is an SGI image file */
- if (info->magic != SGI_MAGIC) {
- mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Bad magic number in image.\n");
- return NULL;
- }
-
- /* check image depth */
- if (info->bytes_per_channel != 1) {
- mp_msg(MSGT_DECVIDEO, MSGL_INFO,
- "Unsupported bytes per channel value %i.\n", info->bytes_per_channel);
- return NULL;
- }
-
- /* check image dimension */
- if (info->dimension != 2 && info->dimension != 3) {
- mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported image dimension %i.\n",
- info->dimension);
- return NULL;
- }
-
- /* change rgba images to rgb so alpha channel will be ignored */
- if (info->zsize == SGI_RGBA_IMAGE) {
- info->zsize = SGI_RGB_IMAGE;
- }
-
- /* check image depth */
- if (info->zsize != SGI_RGB_IMAGE && info->zsize != SGI_GRAYSCALE_IMAGE) {
- mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported image depth.\n");
- return NULL;
- }
-
- /* (re)init libvo if image size is changed */
- if (last_x != info->xsize || last_y != info->ysize)
- {
- last_x = info->xsize;
- last_y = info->ysize;
-
- if (!mpcodecs_config_vo(sh, info->xsize, info->ysize, outfmt)) {
- mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Config vo failed:\n");
- return NULL;
- }
- }
-
- if (!(mpi = mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
- info->xsize, info->ysize))) {
- return NULL;
- }
-
- if (info->rle) {
- decode_rle_sgi(info, data, mpi);
- } else {
- decode_uncompressed_sgi(info, data, mpi);
- }
-
- return mpi;
-}
diff --git a/libmpcodecs/vd_theora.c b/libmpcodecs/vd_theora.c
deleted file mode 100644
index ba3c0d5d86..0000000000
--- a/libmpcodecs/vd_theora.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <assert.h>
-
-#include <libavutil/intreadwrite.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "vd_internal.h"
-
-
-static const vd_info_t info = {
- "Theora/VP3",
- "theora",
- "David Kuehling",
- "www.theora.org",
- "Theora project's VP3 codec"
-};
-
-LIBVD_EXTERN(theora)
-
-#include <theora/theora.h>
-
-#define THEORA_NUM_HEADER_PACKETS 3
-
-typedef struct theora_struct_st {
- theora_state st;
- theora_comment cc;
- theora_info inf;
-} theora_struct_t;
-
-/** Convert Theora pixelformat to the corresponding IMGFMT_ */
-static uint32_t theora_pixelformat2imgfmt(theora_pixelformat fmt){
- switch(fmt) {
- case OC_PF_420: return IMGFMT_YV12;
- case OC_PF_422: return IMGFMT_422P;
- case OC_PF_444: return IMGFMT_444P;
- }
- return 0;
-}
-
-// to set/get/query special features/parameters
-static int control(sh_video_t *sh,int cmd,void* arg,...){
- theora_struct_t *context = sh->context;
- switch(cmd) {
- case VDCTRL_QUERY_FORMAT:
- if (*(int*)arg == theora_pixelformat2imgfmt(context->inf.pixelformat))
- return CONTROL_TRUE;
- return CONTROL_FALSE;
- }
-
- return CONTROL_UNKNOWN;
-}
-
-/*
- * init driver
- */
-static int init(sh_video_t *sh){
- theora_struct_t *context = NULL;
- uint8_t *extradata = (uint8_t *)(sh->bih + 1);
- int extradata_size = sh->bih->biSize - sizeof(*sh->bih);
- int errorCode = 0;
- ogg_packet op;
- int i;
-
- context = calloc (sizeof (theora_struct_t), 1);
- sh->context = context;
- if (!context)
- goto err_out;
-
- theora_info_init(&context->inf);
- theora_comment_init(&context->cc);
-
- /* Read all header packets, pass them to theora_decode_header. */
- for (i = 0; i < THEORA_NUM_HEADER_PACKETS; i++)
- {
- if (extradata_size > 2) {
- op.bytes = AV_RB16(extradata);
- op.packet = extradata + 2;
- op.b_o_s = 1;
- if (extradata_size < op.bytes + 2) {
- mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Theora header too small\n");
- goto err_out;
- }
- extradata += op.bytes + 2;
- extradata_size -= op.bytes + 2;
- } else {
- op.bytes = ds_get_packet (sh->ds, &op.packet);
- op.b_o_s = 1;
- }
-
- if ( (errorCode = theora_decode_header (&context->inf, &context->cc, &op)) )
- {
- mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Broken Theora header; errorCode=%i!\n", errorCode);
- goto err_out;
- }
- }
-
- /* now init codec */
- errorCode = theora_decode_init (&context->st, &context->inf);
- if (errorCode)
- {
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed: %i \n", errorCode);
- goto err_out;
- }
-
- if(sh->aspect==0.0 && context->inf.aspect_denominator!=0)
- {
- sh->aspect = ((double)context->inf.aspect_numerator * context->inf.width)/
- ((double)context->inf.aspect_denominator * context->inf.height);
- }
-
- mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Theora video init ok!\n");
- mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Frame: %dx%d, Picture %dx%d, Offset [%d,%d]\n", context->inf.width, context->inf.height, context->inf.frame_width, context->inf.frame_height, context->inf.offset_x, context->inf.offset_y);
-
- return mpcodecs_config_vo (sh,context->inf.width,context->inf.height,theora_pixelformat2imgfmt(context->inf.pixelformat));
-
-err_out:
- free(context);
- sh->context = NULL;
- return 0;
-}
-
-/*
- * uninit driver
- */
-static void uninit(sh_video_t *sh)
-{
- theora_struct_t *context = sh->context;
-
- if (context)
- {
- theora_info_clear(&context->inf);
- theora_comment_clear(&context->cc);
- theora_clear (&context->st);
- free (context);
- }
-}
-
-/*
- * decode frame
- */
-static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)
-{
- theora_struct_t *context = sh->context;
- int errorCode = 0;
- ogg_packet op;
- yuv_buffer yuv;
- mp_image_t* mpi;
-
- // no delayed frames
- if (!data || !len)
- return NULL;
-
- memset (&op, 0, sizeof (op));
- op.bytes = len;
- op.packet = data;
- op.granulepos = -1;
-
- errorCode = theora_decode_packetin (&context->st, &op);
- if (errorCode)
- {
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode packetin failed: %i \n",
- errorCode);
- return NULL;
- }
-
- errorCode = theora_decode_YUVout (&context->st, &yuv);
- if (errorCode)
- {
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode YUVout failed: %i \n",
- errorCode);
- return NULL;
- }
-
- mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, yuv.y_width, yuv.y_height);
- if(!mpi) return NULL;
-
- mpi->planes[0]=yuv.y;
- mpi->stride[0]=yuv.y_stride;
- mpi->planes[1]=yuv.u;
- mpi->stride[1]=yuv.uv_stride;
- mpi->planes[2]=yuv.v;
- mpi->stride[2]=yuv.uv_stride;
-
- return mpi;
-}
diff --git a/libmpcodecs/vd_xvid4.c b/libmpcodecs/vd_xvid4.c
deleted file mode 100644
index c5e25cd1d6..0000000000
--- a/libmpcodecs/vd_xvid4.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * - XviD 1.x decoder module for mplayer -
- *
- * Copyright(C) 2003 Marco Belli <elcabesa@inwind.it>
- * 2003-2004 Edouard Gomez <ed.gomez@free.fr>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/*****************************************************************************
- * Includes
- ****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "vd_internal.h"
-#include "m_option.h"
-
-#include <xvid.h>
-
-/*****************************************************************************
- * Configuration options
- ****************************************************************************/
-
-static int do_dr2 = 1;
-static int filmeffect = 0;
-static int lumadeblock = 0;
-static int chromadeblock = 0;
-static int lumadering = 0;
-static int chromadering = 0;
-
-const m_option_t xvid_dec_opts[] = {
- { "dr2", &do_dr2, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- { "nodr2", &do_dr2, CONF_TYPE_FLAG, 0, 1, 0, NULL},
- { "filmeffect", &filmeffect, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- { "deblock-luma", &lumadeblock, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- { "deblock-chroma", &chromadeblock, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- { "dering-luma", &lumadering, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- { "dering-chroma", &chromadering, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- {NULL, NULL, 0, 0, 0, 0, NULL}
-};
-
-/*****************************************************************************
- * Module private data
- ****************************************************************************/
-
-typedef struct {
- int cs;
- unsigned char img_type;
- void* hdl;
- mp_image_t* mpi;
- int vo_initialized;
-} priv_t;
-
-/*****************************************************************************
- * Module function helpers
- ****************************************************************************/
-
-static float stats2aspect(xvid_dec_stats_t *stats);
-
-/*****************************************************************************
- * Video decoder API function definitions
- ****************************************************************************/
-
-/*============================================================================
- * control - to set/get/query special features/parameters
- *==========================================================================*/
-
-static int control(sh_video_t *sh,int cmd,void* arg,...)
-{
- return CONTROL_UNKNOWN;
-}
-
-/*============================================================================
- * init - initialize the codec
- *==========================================================================*/
-
-static int init(sh_video_t *sh)
-{
- xvid_gbl_info_t xvid_gbl_info;
- xvid_gbl_init_t xvid_ini;
- xvid_dec_create_t dec_p;
- priv_t* p;
- int cs;
-
- memset(&xvid_gbl_info, 0, sizeof(xvid_gbl_info_t));
- xvid_gbl_info.version = XVID_VERSION;
-
- memset(&xvid_ini, 0, sizeof(xvid_gbl_init_t));
- xvid_ini.version = XVID_VERSION;
-
- memset(&dec_p, 0, sizeof(xvid_dec_create_t));
- dec_p.version = XVID_VERSION;
-
-
- switch(sh->codec->outfmt[sh->outfmtidx]){
- case IMGFMT_YV12:
- /* We will use our own buffers, this speeds decoding avoiding
- * frame memcpy's overhead */
- cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER;
- break;
- case IMGFMT_YUY2:
- cs = XVID_CSP_YUY2;
- break;
- case IMGFMT_UYVY:
- cs = XVID_CSP_UYVY;
- break;
- case IMGFMT_I420:
- case IMGFMT_IYUV:
- /* We will use our own buffers, this speeds decoding avoiding
- * frame memcpy's overhead */
- cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER;
- break;
- case IMGFMT_BGR15:
- cs = XVID_CSP_RGB555;
- break;
- case IMGFMT_BGR16:
- cs = XVID_CSP_RGB565;
- break;
- case IMGFMT_BGR32:
- cs = XVID_CSP_BGRA;
- break;
- case IMGFMT_YVYU:
- cs = XVID_CSP_YVYU;
- break;
- default:
- mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Unsupported out_fmt: 0x%X\n",
- sh->codec->outfmt[sh->outfmtidx]);
- return 0;
- }
-
- /* Gather some information about the host library */
- if(xvid_global(NULL, XVID_GBL_INFO, &xvid_gbl_info, NULL) < 0) {
- mp_msg(MSGT_DECVIDEO,MSGL_INFO, "xvid: could not get information about the library\n");
- } else {
- mp_msg(MSGT_DECVIDEO,MSGL_INFO, "xvid: using library version %d.%d.%d (build %s)\n",
- XVID_VERSION_MAJOR(xvid_gbl_info.actual_version),
- XVID_VERSION_MINOR(xvid_gbl_info.actual_version),
- XVID_VERSION_PATCH(xvid_gbl_info.actual_version),
- xvid_gbl_info.build);
- }
-
- /* Initialize the xvidcore library */
- if(xvid_global(NULL, XVID_GBL_INIT, &xvid_ini, NULL))
- return 0;
-
- /* We use 0 width and height so xvidcore will resize its buffers
- * if required. That allows this vd plugin to do resize on first
- * VOL encountered (don't trust containers' width and height) */
- dec_p.width = 0;
- dec_p.height = 0;
-
- /* Get a decoder instance */
- if(xvid_decore(0, XVID_DEC_CREATE, &dec_p, NULL)<0) {
- mp_msg(MSGT_DECVIDEO, MSGL_ERR, "XviD init failed\n");
- return 0;
- }
-
- p = malloc(sizeof(priv_t));
- p->cs = cs;
- p->hdl = dec_p.handle;
- p->vo_initialized = 0;
- sh->context = p;
-
- switch(cs) {
- case XVID_CSP_INTERNAL:
- p->img_type = MP_IMGTYPE_EXPORT;
- break;
- case XVID_CSP_USER:
- p->img_type = MP_IMGTYPE_STATIC;
- break;
- default:
- p->img_type = MP_IMGTYPE_TEMP;
- break;
- }
-
- return 1;
-}
-
-/*============================================================================
- * uninit - close the codec
- *==========================================================================*/
-
-static void uninit(sh_video_t *sh){
- priv_t* p = sh->context;
- if(!p)
- return;
- xvid_decore(p->hdl,XVID_DEC_DESTROY, NULL, NULL);
- free(p);
-}
-
-/*============================================================================
- * decode - decode a frame from stream
- *==========================================================================*/
-
-static mp_image_t* decode(sh_video_t *sh, void* data, int len, int flags)
-{
- xvid_dec_frame_t dec;
- xvid_dec_stats_t stats;
- mp_image_t* mpi = NULL;
-
- priv_t* p = sh->context;
-
-
- if(!data || len <= 0)
- return NULL;
-
- memset(&dec,0,sizeof(xvid_dec_frame_t));
- memset(&stats, 0, sizeof(xvid_dec_stats_t));
- dec.version = XVID_VERSION;
- stats.version = XVID_VERSION;
-
- dec.bitstream = data;
- dec.length = len;
-
- dec.general |= XVID_LOWDELAY
- /* XXX: if lowdelay is unset, and xvidcore internal buffers are
- * used => crash. MUST FIX */
- | (filmeffect ? XVID_FILMEFFECT : 0 )
- | (lumadeblock ? XVID_DEBLOCKY : 0 )
- | (chromadeblock ? XVID_DEBLOCKUV : 0 );
-#if XVID_API >= XVID_MAKE_API(4,1)
- dec.general |= (lumadering ? XVID_DEBLOCKY|XVID_DERINGY : 0 );
- dec.general |= (chromadering ? XVID_DEBLOCKUV|XVID_DERINGUV : 0 );
-#endif
- dec.output.csp = p->cs;
-
- /* Decoding loop because xvidcore may return VOL information for
- * on the fly buffer resizing. In that case we must decode VOL,
- * init VO, then decode the frame */
- do {
- int consumed;
-
- /* If we don't know frame size yet, don't even try to request
- * a buffer, we must loop until we find a VOL, so VO plugin
- * is initialized and we can obviously output something */
- if (p->vo_initialized) {
- mpi = mpcodecs_get_image(sh, p->img_type,
- MP_IMGFLAG_ACCEPT_STRIDE,
- sh->disp_w, sh->disp_h);
-
- if(p->cs != XVID_CSP_INTERNAL) {
- dec.output.plane[0] = mpi->planes[0];
- dec.output.plane[1] = mpi->planes[1];
- dec.output.plane[2] = mpi->planes[2];
-
- dec.output.stride[0] = mpi->stride[0];
- dec.output.stride[1] = mpi->stride[1];
- dec.output.stride[2] = mpi->stride[2];
- }
- }
-
- /* Decode data */
- consumed = xvid_decore(p->hdl, XVID_DEC_DECODE, &dec, &stats);
- if (consumed < 0) {
- mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Decoding error\n");
- return NULL;
- }
-
- /* Found a VOL information stats, if VO plugin is not initialized
- * yet then do it now */
- if (stats.type == XVID_TYPE_VOL && !p->vo_initialized) {
- sh->aspect = stats2aspect(&stats);
- if(!mpcodecs_config_vo(sh, stats.data.vol.width, stats.data.vol.height, IMGFMT_YV12))
- return NULL;
-
- /* Don't take this path twice */
- p->vo_initialized = !p->vo_initialized;
- }
-
- /* Don't forget to update buffer position and buffer length */
- dec.bitstream = (char *)dec.bitstream + consumed;
- dec.length -= consumed;
- } while ((stats.type == XVID_TYPE_VOL || stats.type == XVID_TYPE_NOTHING) && dec.length > 0);
-
- /* There are two ways to get out of the decoding loop:
- * - a frame has been returned
- * - no more data in buffer and no frames returned */
-
- /* If mpi is NULL, it proves nothing has been returned by the decoder
- * so don't try to display internal buffers. */
- if (mpi != NULL && p->cs == XVID_CSP_INTERNAL) {
- mpi->planes[0] = dec.output.plane[0];
- mpi->planes[1] = dec.output.plane[1];
- mpi->planes[2] = dec.output.plane[2];
-
- mpi->stride[0] = dec.output.stride[0];
- mpi->stride[1] = dec.output.stride[1];
- mpi->stride[2] = dec.output.stride[2];
- }
-
- /* If we got out the decoding loop because the buffer was empty and there was nothing
- * to output yet, then just return NULL */
- return (stats.type == XVID_TYPE_NOTHING) ? NULL : mpi;
-}
-
-/*****************************************************************************
- * Helper functions
- ****************************************************************************/
-
-/* Returns DAR value according to VOL's informations contained in stats
- * param */
-static float stats2aspect(xvid_dec_stats_t *stats)
-{
- if (stats->type == XVID_TYPE_VOL) {
- float wpar;
- float hpar;
- float dar;
-
- /* MPEG4 strem stores PAR (Pixel Aspect Ratio), mplayer uses
- * DAR (Display Aspect Ratio)
- *
- * Both are related thanks to the equation:
- * width
- * DAR = ----- x PAR
- * height
- *
- * As MPEG4 is so well designed (*cough*), VOL header carries
- * both informations together -- lucky eh ? */
-
- switch (stats->data.vol.par) {
- case XVID_PAR_11_VGA: /* 1:1 vga (square), default if supplied PAR is not a valid value */
- wpar = hpar = 1.0f;
- break;
- case XVID_PAR_43_PAL: /* 4:3 pal (12:11 625-line) */
- wpar = 12;
- hpar = 11;
- break;
- case XVID_PAR_43_NTSC: /* 4:3 ntsc (10:11 525-line) */
- wpar = 10;
- hpar = 11;
- break;
- case XVID_PAR_169_PAL: /* 16:9 pal (16:11 625-line) */
- wpar = 16;
- hpar = 11;
- break;
- case XVID_PAR_169_NTSC: /* 16:9 ntsc (40:33 525-line) */
- wpar = 40;
- hpar = 33;
- break;
- case XVID_PAR_EXT: /* extended par; use par_width, par_height */
- wpar = stats->data.vol.par_width;
- hpar = stats->data.vol.par_height;
- break;
- default:
- wpar = hpar = 1.0f;
- break;
- }
-
- dar = ((float)stats->data.vol.width*wpar);
- dar /= ((float)stats->data.vol.height*hpar);
-
- return dar;
- }
-
- return 0.0f;
-}
-
-/*****************************************************************************
- * Module structure definition
- ****************************************************************************/
-
-static const vd_info_t info =
-{
- "XviD 1.0 decoder",
- "xvid",
- "Marco Belli <elcabesa@inwind.it>, Edouard Gomez <ed.gomez@free.fr>",
- "Marco Belli <elcabesa@inwind.it>, Edouard Gomez <ed.gomez@free.fr>",
- "No Comment"
-};
-
-LIBVD_EXTERN(xvid)
-
-/* Please do not change that tag comment.
- * arch-tag: b7d654a5-76ea-4768-9713-2c791567fe7d mplayer xvid decoder module */
diff --git a/libmpdemux/aac_hdr.c b/libmpdemux/aac_hdr.c
deleted file mode 100644
index 36991e27a2..0000000000
--- a/libmpdemux/aac_hdr.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2005 Nico Sabbi
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdint.h>
-#include "aac_hdr.h"
-#include "libavutil/attributes.h"
-
-/// \param srate (out) sample rate
-/// \param num (out) number of audio frames in this ADTS frame
-/// \return size of the ADTS frame in bytes
-/// aac_parse_frames needs a buffer at least 8 bytes long
-int aac_parse_frame(uint8_t *buf, int *srate, int *num)
-{
- int i = 0, sr, fl = 0, id av_unused;
- static int srates[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0, 0, 0};
-
- if((buf[i] != 0xFF) || ((buf[i+1] & 0xF6) != 0xF0))
- return 0;
-
- id = (buf[i+1] >> 3) & 0x01; //id=1 mpeg2, 0: mpeg4
- sr = (buf[i+2] >> 2) & 0x0F;
- if(sr > 11)
- return 0;
- *srate = srates[sr];
-
- fl = ((buf[i+3] & 0x03) << 11) | (buf[i+4] << 3) | ((buf[i+5] >> 5) & 0x07);
- *num = (buf[i+6] & 0x02) + 1;
-
- return fl;
-}
diff --git a/libmpdemux/aac_hdr.h b/libmpdemux/aac_hdr.h
deleted file mode 100644
index be56368925..0000000000
--- a/libmpdemux/aac_hdr.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_AAC_HDR_H
-#define MPLAYER_AAC_HDR_H
-
-#include <stdint.h>
-
-int aac_parse_frame(uint8_t *buf, int *srate, int *num);
-
-#endif /* MPLAYER_AAC_HDR_H */
diff --git a/libmpdemux/demux_aac.c b/libmpdemux/demux_aac.c
deleted file mode 100644
index 9d37d75cf8..0000000000
--- a/libmpdemux/demux_aac.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "parse_es.h"
-#include "stheader.h"
-#include "aac_hdr.h"
-#include "ms_hdr.h"
-
-typedef struct {
- uint8_t *buf;
- uint64_t size; /// amount of time of data packets pushed to demuxer->audio (in bytes)
- float time; /// amount of time elapsed based upon samples_per_frame/sample_rate (in milliseconds)
- float last_pts; /// last pts seen
- int bitrate; /// bitrate computed as size/time
-} aac_priv_t;
-
-static int demux_aac_init(demuxer_t *demuxer)
-{
- aac_priv_t *priv;
-
- priv = calloc(1, sizeof(aac_priv_t));
- if(!priv)
- return 0;
-
- priv->buf = malloc(8);
- if(!priv->buf)
- {
- free(priv);
- return 0;
- }
-
- demuxer->priv = priv;
- return 1;
-}
-
-static void demux_close_aac(demuxer_t *demuxer)
-{
- aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
-
- if(!priv)
- return;
-
- free(priv->buf);
-
- free(demuxer->priv);
-
- return;
-}
-
-/// returns DEMUXER_TYPE_AAC if it finds 8 ADTS frames in 32768 bytes, 0 otherwise
-static int demux_aac_probe(demuxer_t *demuxer)
-{
- int cnt = 0, c, len, srate, num;
- off_t init, probed;
- aac_priv_t *priv;
-
- if(! demux_aac_init(demuxer))
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "COULDN'T INIT aac_demux, exit\n");
- return 0;
- }
-
- priv = (aac_priv_t *) demuxer->priv;
-
- init = probed = stream_tell(demuxer->stream);
- while(probed-init <= 32768 && cnt < 8)
- {
- c = 0;
- while(c != 0xFF)
- {
- c = stream_read_char(demuxer->stream);
- if(c < 0)
- goto fail;
- }
- priv->buf[0] = 0xFF;
- if(stream_read(demuxer->stream, &(priv->buf[1]), 7) < 7)
- goto fail;
-
- len = aac_parse_frame(priv->buf, &srate, &num);
- if(len > 0)
- {
- cnt++;
- stream_skip(demuxer->stream, len - 8);
- }
- probed = stream_tell(demuxer->stream);
- }
-
- stream_seek(demuxer->stream, init);
- if(cnt < 8)
- goto fail;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, INIT: %"PRIu64", PROBED: %"PRIu64", cnt: %d\n", init, probed, cnt);
- return DEMUXER_TYPE_AAC;
-
-fail:
- mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, failed to detect an AAC stream\n");
- return 0;
-}
-
-static demuxer_t* demux_aac_open(demuxer_t *demuxer)
-{
- sh_audio_t *sh;
-
- sh = new_sh_audio(demuxer, 0);
- sh->ds = demuxer->audio;
- sh->format = mmioFOURCC('M', 'P', '4', 'A');
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh;
-
- demuxer->filepos = stream_tell(demuxer->stream);
-
- return demuxer;
-}
-
-static int demux_aac_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
-{
- aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
- demux_packet_t *dp;
- int c1, c2, len, srate, num;
- float tm = 0;
-
- if(demuxer->stream->eof || (demuxer->movi_end && stream_tell(demuxer->stream) >= demuxer->movi_end))
- return 0;
-
- while(! demuxer->stream->eof)
- {
- c1 = c2 = 0;
- while(c1 != 0xFF)
- {
- c1 = stream_read_char(demuxer->stream);
- if(c1 < 0)
- return 0;
- }
- c2 = stream_read_char(demuxer->stream);
- if(c2 < 0)
- return 0;
- if((c2 & 0xF6) != 0xF0)
- continue;
-
- priv->buf[0] = (unsigned char) c1;
- priv->buf[1] = (unsigned char) c2;
- if(stream_read(demuxer->stream, &(priv->buf[2]), 6) < 6)
- return 0;
-
- len = aac_parse_frame(priv->buf, &srate, &num);
- if(len > 0)
- {
- dp = new_demux_packet(len);
- if(! dp)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", len);
- return 0;
- }
-
-
- memcpy(dp->buffer, priv->buf, 8);
- stream_read(demuxer->stream, &(dp->buffer[8]), len-8);
- if(srate)
- tm = (float) (num * 1024.0/srate);
- priv->last_pts += tm;
- dp->pts = priv->last_pts;
- //fprintf(stderr, "\nPTS: %.3f\n", dp->pts);
- ds_add_packet(demuxer->audio, dp);
- priv->size += len;
- priv->time += tm;
-
- priv->bitrate = (int) (priv->size / priv->time);
- demuxer->filepos = stream_tell(demuxer->stream);
-
- return len;
- }
- else
- stream_skip(demuxer->stream, -6);
- }
-
- return 0;
-}
-
-
-//This is an almost verbatim copy of high_res_mp3_seek(), from demux_audio.c
-static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
-{
- aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
- demux_stream_t *d_audio=demuxer->audio;
- sh_audio_t *sh_audio=d_audio->sh;
- float time;
-
- ds_free_packs(d_audio);
-
- time = (flags & SEEK_ABSOLUTE) ? rel_seek_secs - priv->last_pts : rel_seek_secs;
- if(time < 0)
- {
- stream_seek(demuxer->stream, demuxer->movi_start);
- time = priv->last_pts + time;
- priv->last_pts = 0;
- }
-
- if(time > 0)
- {
- int len, nf, srate, num;
-
- nf = time * sh_audio->samplerate/1024;
-
- while(nf > 0)
- {
- if(stream_read(demuxer->stream,priv->buf, 8) < 8)
- break;
- len = aac_parse_frame(priv->buf, &srate, &num);
- if(len <= 0)
- {
- stream_skip(demuxer->stream, -7);
- continue;
- }
- stream_skip(demuxer->stream, len - 8);
- priv->last_pts += (float) (num*1024.0/srate);
- nf -= num;
- }
- }
-}
-
-
-const demuxer_desc_t demuxer_desc_aac = {
- "AAC demuxer",
- "aac",
- "AAC",
- "Nico Sabbi",
- "Raw AAC files ",
- DEMUXER_TYPE_AAC,
- 0, // unsafe autodetect
- demux_aac_probe,
- demux_aac_fill_buffer,
- demux_aac_open,
- demux_close_aac,
- demux_aac_seek,
- NULL
-};
diff --git a/libmpdemux/demux_avi.c b/libmpdemux/demux_avi.c
index f73648166c..3841cf2736 100644
--- a/libmpdemux/demux_avi.c
+++ b/libmpdemux/demux_avi.c
@@ -29,7 +29,6 @@
#include "stream/stream.h"
#include "demuxer.h"
#include "stheader.h"
-#include "demux_ogg.h"
#include "aviheader.h"
extern const demuxer_desc_t demuxer_desc_avi_ni;
@@ -862,38 +861,6 @@ static int avi_check_file(demuxer_t *demuxer)
}
-static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer)
-{
- struct MPOpts *opts = demuxer->opts;
- sh_audio_t* sh_a;
-
- demuxer = demux_open_avi(demuxer);
- if(!demuxer) return NULL; // failed to open
- sh_a = demuxer->audio->sh;
- if(demuxer->audio->id != -2 && sh_a) {
-#ifdef CONFIG_OGGVORBIS
- // support for Ogg-in-AVI:
- if(sh_a->format == 0xFFFE)
- demuxer = init_avi_with_ogg(demuxer);
- else if(sh_a->format == 0x674F) {
- stream_t* s;
- demuxer_t *od;
- s = new_ds_stream(demuxer->audio);
- od = new_demuxer(opts, s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL);
- if(!demux_ogg_open(od)) {
- mp_tmsg( MSGT_DEMUXER,MSGL_ERR,"Unable to open the Ogg demuxer.\n");
- free_stream(s);
- demuxer->audio->id = -2;
- } else
- demuxer = new_demuxers_demuxer(demuxer,od,demuxer);
- }
-#endif
- }
-
- return demuxer;
-}
-
-
const demuxer_desc_t demuxer_desc_avi = {
"AVI demuxer",
"avi",
@@ -904,7 +871,7 @@ const demuxer_desc_t demuxer_desc_avi = {
1, // safe autodetect
avi_check_file,
demux_avi_fill_buffer,
- demux_open_hack_avi,
+ demux_open_avi,
demux_close_avi,
demux_seek_avi,
demux_avi_control
@@ -920,7 +887,7 @@ const demuxer_desc_t demuxer_desc_avi_ni = {
1, // safe autodetect
avi_check_file,
demux_avi_fill_buffer_ni,
- demux_open_hack_avi,
+ demux_open_avi,
demux_close_avi,
demux_seek_avi,
demux_avi_control
@@ -936,7 +903,7 @@ const demuxer_desc_t demuxer_desc_avi_nini = {
1, // safe autodetect
avi_check_file,
demux_avi_fill_buffer_nini,
- demux_open_hack_avi,
+ demux_open_avi,
demux_close_avi,
demux_seek_avi,
demux_avi_control
diff --git a/libmpdemux/demux_film.c b/libmpdemux/demux_film.c
deleted file mode 100644
index 713c9ea26e..0000000000
--- a/libmpdemux/demux_film.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * FILM file parser
- * Copyright (C) 2002 Mike Melanson
- *
- * This demuxer handles FILM (a.k.a. CPK) files commonly found on Sega
- * Saturn CD-ROM games. FILM files have also been found on 3DO games.
- *
- * details of the FILM file format can be found at:
- * http://www.pcisys.net/~melanson/codecs/
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-// chunk types found in a FILM file
-#define CHUNK_FILM mmioFOURCC('F', 'I', 'L', 'M')
-#define CHUNK_FDSC mmioFOURCC('F', 'D', 'S', 'C')
-#define CHUNK_STAB mmioFOURCC('S', 'T', 'A', 'B')
-
-typedef struct film_chunk_t
-{
- off_t chunk_offset;
- int chunk_size;
- unsigned int syncinfo1;
- unsigned int syncinfo2;
-
- float pts;
-} film_chunk_t;
-
-typedef struct film_data_t
-{
- unsigned int total_chunks;
- unsigned int current_chunk;
- film_chunk_t *chunks;
- unsigned int chunks_per_second;
- unsigned int film_version;
-} film_data_t;
-
-static void demux_seek_film(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
-{
- film_data_t *film_data = (film_data_t *)demuxer->priv;
- int new_current_chunk=(flags&SEEK_ABSOLUTE)?0:film_data->current_chunk;
-
- if(flags&SEEK_FACTOR)
- new_current_chunk += rel_seek_secs * film_data->total_chunks; // 0..1
- else
- new_current_chunk += rel_seek_secs * film_data->chunks_per_second; // secs
-
-
-mp_msg(MSGT_DECVIDEO, MSGL_INFO,"current, total chunks = %d, %d; seek %5.3f sec, new chunk guess = %d\n",
- film_data->current_chunk, film_data->total_chunks,
- rel_seek_secs, new_current_chunk);
-
- // check if the new chunk number is valid
- if (new_current_chunk < 0)
- new_current_chunk = 0;
- if ((unsigned int)new_current_chunk > film_data->total_chunks)
- new_current_chunk = film_data->total_chunks - 1;
-
- while (((film_data->chunks[new_current_chunk].syncinfo1 == 0xFFFFFFFF) ||
- (film_data->chunks[new_current_chunk].syncinfo1 & 0x80000000)) &&
- (new_current_chunk > 0))
- new_current_chunk--;
-
- film_data->current_chunk = new_current_chunk;
-
-mp_msg(MSGT_DECVIDEO, MSGL_INFO," (flags = %X) actual new chunk = %d (syncinfo1 = %08X)\n",
- flags, film_data->current_chunk, film_data->chunks[film_data->current_chunk].syncinfo1);
- demuxer->video->pts=film_data->chunks[film_data->current_chunk].pts;
-
-}
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_film_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
-{
- int i;
- unsigned char byte_swap;
- int cvid_size;
- sh_video_t *sh_video = demuxer->video->sh;
- sh_audio_t *sh_audio = demuxer->audio->sh;
- film_data_t *film_data = (film_data_t *)demuxer->priv;
- film_chunk_t film_chunk;
- int length_fix_bytes;
- demux_packet_t* dp;
-
- // see if the end has been reached
- if (film_data->current_chunk >= film_data->total_chunks)
- return 0;
-
- film_chunk = film_data->chunks[film_data->current_chunk];
-
- // position stream and fetch chunk
- stream_seek(demuxer->stream, film_chunk.chunk_offset);
-
- // load the chunks manually (instead of using ds_read_packet()), since
- // they require some adjustment
- // (all ones in syncinfo1 indicates an audio chunk)
- if (film_chunk.syncinfo1 == 0xFFFFFFFF)
- {
- if(demuxer->audio->id>=-1){ // audio not disabled
- dp = new_demux_packet(film_chunk.chunk_size);
- if (stream_read(demuxer->stream, dp->buffer, film_chunk.chunk_size) !=
- film_chunk.chunk_size)
- return 0;
- dp->pts = film_chunk.pts;
- dp->pos = film_chunk.chunk_offset;
-
- // adjust the data before queuing it:
- // 8-bit: signed -> unsigned
- // 16-bit: big-endian -> little-endian
- if (sh_audio->wf->wBitsPerSample == 8)
- for (i = 0; i < film_chunk.chunk_size; i++)
- dp->buffer[i] += 128;
- else
- for (i = 0; i < film_chunk.chunk_size; i += 2)
- {
- byte_swap = dp->buffer[i];
- dp->buffer[i] = dp->buffer[i + 1];
- dp->buffer[i + 1] = byte_swap;
- }
-
- /* for SegaSaturn .cpk file, translate audio data if stereo */
- if (sh_audio->wf->nChannels == 2) {
- if (sh_audio->wf->wBitsPerSample == 8) {
- unsigned char* tmp = dp->buffer;
- unsigned char buf[film_chunk.chunk_size];
- for(i = 0; i < film_chunk.chunk_size/2; i++) {
- buf[i*2] = tmp[i];
- buf[i*2+1] = tmp[film_chunk.chunk_size/2+i];
- }
- memcpy( tmp, buf, film_chunk.chunk_size );
- }
- else {/* for 16bit */
- unsigned short *tmp = (unsigned short *)dp->buffer;
- unsigned short buf[film_chunk.chunk_size/2];
- for(i = 0; i < film_chunk.chunk_size/4; i++) {
- buf[i*2] = tmp[i];
- buf[i*2+1] = tmp[film_chunk.chunk_size/4+i];
- }
- memcpy( tmp, buf, film_chunk.chunk_size );
- }
- }
-
- // append packet to DS stream
- ds_add_packet(demuxer->audio, dp);
- }
- }
- else
- {
- // if the demuxer is dealing with CVID data, deal with it a special way
- if (sh_video->format == mmioFOURCC('c', 'v', 'i', 'd'))
- {
- if (film_data->film_version)
- length_fix_bytes = 2;
- else
- length_fix_bytes = 6;
-
- // account for the fix bytes when allocating the buffer
- dp = new_demux_packet(film_chunk.chunk_size - length_fix_bytes);
-
- // these CVID data chunks have a few extra bytes; skip them
- if (stream_read(demuxer->stream, dp->buffer, 10) != 10)
- return 0;
- stream_skip(demuxer->stream, length_fix_bytes);
-
- if (stream_read(demuxer->stream, dp->buffer + 10,
- film_chunk.chunk_size - (10 + length_fix_bytes)) !=
- (film_chunk.chunk_size - (10 + length_fix_bytes)))
- return 0;
-
- dp->pts = film_chunk.pts;
- dp->pos = film_chunk.chunk_offset;
- dp->keyframe = film_chunk.syncinfo1 & 0x80000000;
-
- // fix the CVID chunk size
- cvid_size = film_chunk.chunk_size - length_fix_bytes;
- dp->buffer[1] = (cvid_size >> 16) & 0xFF;
- dp->buffer[2] = (cvid_size >> 8) & 0xFF;
- dp->buffer[3] = (cvid_size >> 0) & 0xFF;
-
- // append packet to DS stream
- ds_add_packet(demuxer->video, dp);
- }
- else
- {
- ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size,
- film_chunk.pts,
- film_chunk.chunk_offset, (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0);
- }
- }
- film_data->current_chunk++;
-
- return 1;
-}
-
-static demuxer_t* demux_open_film(demuxer_t* demuxer)
-{
- sh_video_t *sh_video = NULL;
- sh_audio_t *sh_audio = NULL;
- film_data_t *film_data;
- film_chunk_t film_chunk;
- int header_size;
- unsigned int chunk_type;
- unsigned int chunk_size;
- unsigned int i;
- unsigned int video_format;
- int audio_channels;
- int counting_chunks;
- unsigned int total_audio_bytes = 0;
-
- film_data = malloc(sizeof(film_data_t));
- film_data->total_chunks = 0;
- film_data->current_chunk = 0;
- film_data->chunks = NULL;
- film_data->chunks_per_second = 0;
-
- // go back to the beginning
- stream_reset(demuxer->stream);
- stream_seek(demuxer->stream, 0);
-
- // read the master chunk type
- chunk_type = stream_read_fourcc(demuxer->stream);
- // validate the chunk type
- if (chunk_type != CHUNK_FILM)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Not a FILM file\n");
- free(film_data);
- return NULL;
- }
-
- // get the header size, which implicitly points past the header and
- // to the start of the data
- header_size = stream_read_dword(demuxer->stream);
- film_data->film_version = stream_read_fourcc(demuxer->stream);
- demuxer->movi_start = header_size;
- demuxer->movi_end = demuxer->stream->end_pos;
- header_size -= 16;
-
- mp_msg(MSGT_DEMUX, MSGL_HINT, "FILM version %.4s\n",
- (char *)&film_data->film_version);
-
- // skip to where the next chunk should be
- stream_skip(demuxer->stream, 4);
-
- // traverse through the header
- while (header_size > 0)
- {
- // fetch the chunk type and size
- chunk_type = stream_read_fourcc(demuxer->stream);
- chunk_size = stream_read_dword(demuxer->stream);
- header_size -= chunk_size;
-
- switch (chunk_type)
- {
- case CHUNK_FDSC:
- mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing FDSC chunk\n");
-
- // fetch the video codec fourcc to see if there's any video
- video_format = stream_read_fourcc(demuxer->stream);
- if (video_format)
- {
- // create and initialize the video stream header
- sh_video = new_sh_video(demuxer, 0);
- demuxer->video->sh = sh_video;
- sh_video->ds = demuxer->video;
-
- sh_video->format = video_format;
- sh_video->disp_h = stream_read_dword(demuxer->stream);
- sh_video->disp_w = stream_read_dword(demuxer->stream);
- mp_msg(MSGT_DECVIDEO, MSGL_V,
- " FILM video: %d x %d\n", sh_video->disp_w,
- sh_video->disp_h);
- }
- else
- // skip height and width if no video
- stream_skip(demuxer->stream, 8);
-
- if(demuxer->audio->id<-1){
- mp_msg(MSGT_DECVIDEO, MSGL_INFO,"chunk size = 0x%X \n",chunk_size);
- stream_skip(demuxer->stream, chunk_size-12-8);
- break; // audio disabled (or no soundcard)
- }
-
- // skip over unknown byte, but only if file had non-NULL version
- if (film_data->film_version)
- stream_skip(demuxer->stream, 1);
-
- // fetch the audio channels to see if there's any audio
- // don't do this if the file is a quirky file with NULL version
- if (film_data->film_version)
- {
- audio_channels = stream_read_char(demuxer->stream);
- if (audio_channels > 0)
- {
- // create and initialize the audio stream header
- sh_audio = new_sh_audio(demuxer, 0);
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- sh_audio->ds = demuxer->audio;
-
- sh_audio->wf = malloc(sizeof(*sh_audio->wf));
-
- // uncompressed PCM format
- sh_audio->wf->wFormatTag = 1;
- sh_audio->format = 1;
- sh_audio->wf->nChannels = audio_channels;
- sh_audio->wf->wBitsPerSample = stream_read_char(demuxer->stream);
- stream_skip(demuxer->stream, 1); // skip unknown byte
- sh_audio->wf->nSamplesPerSec = stream_read_word(demuxer->stream);
- sh_audio->wf->nAvgBytesPerSec =
- sh_audio->wf->nSamplesPerSec * sh_audio->wf->wBitsPerSample
- * sh_audio->wf->nChannels / 8;
- stream_skip(demuxer->stream, 6); // skip the rest of the unknown
-
- mp_msg(MSGT_DECVIDEO, MSGL_V,
- " FILM audio: %d channels, %d bits, %d Hz\n",
- sh_audio->wf->nChannels, 8 * sh_audio->wf->wBitsPerSample,
- sh_audio->wf->nSamplesPerSec);
- }
- else
- stream_skip(demuxer->stream, 10);
- }
- else
- {
- // otherwise, make some assumptions about the audio
-
- // create and initialize the audio stream header
- sh_audio = new_sh_audio(demuxer, 0);
- demuxer->audio->sh = sh_audio;
- sh_audio->ds = demuxer->audio;
-
- sh_audio->wf = malloc(sizeof(*sh_audio->wf));
-
- // uncompressed PCM format
- sh_audio->wf->wFormatTag = 1;
- sh_audio->format = 1;
- sh_audio->wf->nChannels = 1;
- sh_audio->wf->wBitsPerSample = 8;
- sh_audio->wf->nSamplesPerSec = 22050;
- sh_audio->wf->nAvgBytesPerSec =
- sh_audio->wf->nSamplesPerSec * sh_audio->wf->wBitsPerSample
- * sh_audio->wf->nChannels / 8;
-
- mp_msg(MSGT_DECVIDEO, MSGL_V,
- " FILM audio: %d channels, %d bits, %d Hz\n",
- sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample,
- sh_audio->wf->nSamplesPerSec);
- }
- break;
-
- case CHUNK_STAB:
- mp_msg(MSGT_DECVIDEO, MSGL_V, "parsing STAB chunk\n");
-
- if (sh_video)
- {
- sh_video->fps = stream_read_dword(demuxer->stream);
- sh_video->frametime = 1.0 / sh_video->fps;
- }
-
- // fetch the number of chunks
- film_data->total_chunks = stream_read_dword(demuxer->stream);
- film_data->current_chunk = 0;
- mp_msg(MSGT_DECVIDEO, MSGL_V,
- " STAB chunk contains %d chunks\n", film_data->total_chunks);
-
- // allocate enough entries for the chunk
- film_data->chunks =
- calloc(film_data->total_chunks, sizeof(film_chunk_t));
-
- // build the chunk index
- counting_chunks = 1;
- for (i = 0; i < film_data->total_chunks; i++)
- {
- film_chunk = film_data->chunks[i];
- film_chunk.chunk_offset =
- demuxer->movi_start + stream_read_dword(demuxer->stream);
- film_chunk.chunk_size = stream_read_dword(demuxer->stream);
- film_chunk.syncinfo1 = stream_read_dword(demuxer->stream);
- film_chunk.syncinfo2 = stream_read_dword(demuxer->stream);
-
- // count chunks for the purposes of seeking
- if (counting_chunks)
- {
- // if we're counting chunks, always count an audio chunk
- if (film_chunk.syncinfo1 == 0xFFFFFFFF)
- film_data->chunks_per_second++;
- // if it's a video chunk, check if it's time to stop counting
- else if ((film_chunk.syncinfo1 & 0x7FFFFFFF) >= sh_video->fps)
- counting_chunks = 0;
- else
- film_data->chunks_per_second++;
- }
-
- // precalculate PTS
- if (film_chunk.syncinfo1 == 0xFFFFFFFF)
- {
- if(demuxer->audio->id>=-1)
- film_chunk.pts =
- (float)total_audio_bytes / (float)sh_audio->wf->nAvgBytesPerSec;
- total_audio_bytes += film_chunk.chunk_size;
- }
- else
- film_chunk.pts =
- (film_chunk.syncinfo1 & 0x7FFFFFFF) / sh_video->fps;
-
- film_data->chunks[i] = film_chunk;
- }
-
- // in some FILM files (notably '1.09'), the length of the FDSC chunk
- // follows different rules
- if (chunk_size == (film_data->total_chunks * 16))
- header_size -= 16;
- break;
-
- default:
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Unrecognized FILM header chunk: %08X\n",
- chunk_type);
- return NULL;
- break;
- }
- }
-
- demuxer->priv = film_data;
-
- return demuxer;
-}
-
-static void demux_close_film(demuxer_t* demuxer) {
- film_data_t *film_data = demuxer->priv;
-
- if(!film_data)
- return;
- free(film_data->chunks);
- free(film_data);
-
-}
-
-static int film_check_file(demuxer_t* demuxer)
-{
- int signature=stream_read_fourcc(demuxer->stream);
-
- // check for the FILM file magic number
- if(signature==mmioFOURCC('F', 'I', 'L', 'M'))
- return DEMUXER_TYPE_FILM;
-
- return 0;
-}
-
-
-const demuxer_desc_t demuxer_desc_film = {
- "FILM/CPK demuxer for Sega Saturn CD-ROM games",
- "film",
- "FILM",
- "Mike Melanson",
- "",
- DEMUXER_TYPE_FILM,
- 0, // unsafe autodetect (short signature)
- film_check_file,
- demux_film_fill_buffer,
- demux_open_film,
- demux_close_film,
- demux_seek_film,
- NULL
-};
diff --git a/libmpdemux/demux_fli.c b/libmpdemux/demux_fli.c
deleted file mode 100644
index e89fa75d97..0000000000
--- a/libmpdemux/demux_fli.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * FLI file parser
- * copyright (c) 2001 Mike Melanson
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-typedef struct {
- int num_frames;
- int current_frame;
- off_t *filepos;
- unsigned int *frame_size;
-} fli_frames_t;
-
-static void demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
- fli_frames_t *frames = (fli_frames_t *)demuxer->priv;
- sh_video_t *sh_video = demuxer->video->sh;
- int newpos=(flags&SEEK_ABSOLUTE)?0:frames->current_frame;
- if(flags&SEEK_FACTOR){
- // float 0..1
- newpos+=rel_seek_secs*frames->num_frames;
- } else {
- // secs
- newpos+=rel_seek_secs*sh_video->fps;
- }
- if(newpos<0) newpos=0; else
- if(newpos>frames->num_frames) newpos=frames->num_frames;
- frames->current_frame=newpos;
-}
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_fli_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
- fli_frames_t *frames = (fli_frames_t *)demuxer->priv;
- sh_video_t *sh_video = demuxer->video->sh;
-
- // see if the end has been reached
- if (frames->current_frame >= frames->num_frames)
- return 0;
-
- // fetch the frame from the file
- // first, position the file properly since ds_read_packet() doesn't
- // seem to do it, even though it takes a file offset as a parameter
- stream_seek(demuxer->stream, frames->filepos[frames->current_frame]);
- ds_read_packet(demuxer->video,
- demuxer->stream,
- frames->frame_size[frames->current_frame],
- frames->current_frame/sh_video->fps,
- frames->filepos[frames->current_frame],
- 0 /* what flags? -> demuxer.h (alex) */
- );
-
- // get the next frame ready
- frames->current_frame++;
-
- return 1;
-}
-
-static demuxer_t* demux_open_fli(demuxer_t* demuxer){
- sh_video_t *sh_video = NULL;
- fli_frames_t *frames = malloc(sizeof(fli_frames_t));
- int frame_number;
- int speed;
- unsigned int frame_size;
- int magic_number;
- unsigned char * header;
-
- // go back to the beginning
- stream_reset(demuxer->stream);
- stream_seek(demuxer->stream, 0);
-
- header = calloc(1, sizeof(BITMAPINFOHEADER) + 128);
- stream_read(demuxer->stream, header + sizeof(BITMAPINFOHEADER), 128);
- stream_seek(demuxer->stream, 0);
-
- demuxer->movi_start = 128;
- demuxer->movi_end = stream_read_dword_le(demuxer->stream);
-
- magic_number = stream_read_word_le(demuxer->stream);
-
- if ((magic_number != 0xAF11) && (magic_number != 0xAF12))
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Bad/unknown magic number (%04x)\n",
- magic_number);
- free(header);
- free(frames);
- return NULL;
- }
-
- // fetch the number of frames
- frames->num_frames = stream_read_word_le(demuxer->stream);
- frames->current_frame = 0;
-
- // allocate enough entries for the indices
- // audit: num_frames is 16bit so it is safe against overflow
- frames->filepos = malloc(frames->num_frames * sizeof(off_t));
- frames->frame_size = malloc(frames->num_frames * sizeof(int));
-
- // create a new video stream header
- sh_video = new_sh_video(demuxer, 0);
-
- // make sure the demuxer knows about the new video stream header
- // (even though new_sh_video() ought to take care of it)
- demuxer->video->sh = sh_video;
-
- // make sure that the video demuxer stream header knows about its
- // parent video demuxer stream (this is getting wacky), or else
- // video_read_properties() will choke
- sh_video->ds = demuxer->video;
-
- // custom fourcc for internal MPlayer use
- sh_video->format = mmioFOURCC('F', 'L', 'I', 'C');
-
- sh_video->disp_w = stream_read_word_le(demuxer->stream);
- sh_video->disp_h = stream_read_word_le(demuxer->stream);
-
- // pass extradata to codec
- sh_video->bih = (BITMAPINFOHEADER*)header;
- sh_video->bih->biSize = sizeof(BITMAPINFOHEADER) + 128;
- sh_video->bih->biWidth = sh_video->disp_w;
- sh_video->bih->biHeight = sh_video->disp_h;
-
- // skip the video depth and flags
- stream_skip(demuxer->stream, 4);
-
- // get the speed
- speed = stream_read_word_le(demuxer->stream);
- if (speed == 0)
- speed = 1;
- if (magic_number == 0xAF11)
- speed *= 1000/70;
- sh_video->fps = 1000 / speed;
- sh_video->frametime = 1/sh_video->fps;
-
- // build the frame index
- stream_seek(demuxer->stream, demuxer->movi_start);
- frame_number = 0;
- while ((!stream_eof(demuxer->stream)) && (frame_number < frames->num_frames))
- {
- frames->filepos[frame_number] = stream_tell(demuxer->stream);
- frame_size = stream_read_dword_le(demuxer->stream);
- magic_number = stream_read_word_le(demuxer->stream);
- stream_skip(demuxer->stream, frame_size - 6);
-
- // if this chunk has the right magic number, index it
- if ((magic_number == 0xF1FA) || (magic_number == 0xF5FA))
- {
- frames->frame_size[frame_number] = frame_size;
- frame_number++;
- }
- }
-
- // save the actual number of frames indexed
- frames->num_frames = frame_number;
-
- demuxer->priv = frames;
-
- return demuxer;
-}
-
-static void demux_close_fli(demuxer_t* demuxer) {
- fli_frames_t *frames = demuxer->priv;
-
- if(!frames)
- return;
-
- free(frames->filepos);
- free(frames->frame_size);
- free(frames);
-
-}
-
-
-static int fli_check_file(demuxer_t* demuxer)
-{
- int id;
-
- stream_seek(demuxer->stream, 4);
- id=stream_read_word_le(demuxer->stream);
- // check for the FLI file magic number
- if((id==0xAF11) || (id==0xAF12))
- return DEMUXER_TYPE_FLI;
-
- return 0;
-}
-
-
-const demuxer_desc_t demuxer_desc_fli = {
- "Autodesk FLIC demuxer",
- "fli",
- "FLI",
- "Mike Melanson",
- "Supports also some extensions",
- DEMUXER_TYPE_FLI,
- 0, // unsafe autodetect (short signature)
- fli_check_file,
- demux_fli_fill_buffer,
- demux_open_fli,
- demux_close_fli,
- demux_seek_fli,
- NULL
-};
diff --git a/libmpdemux/demux_lmlm4.c b/libmpdemux/demux_lmlm4.c
deleted file mode 100644
index 739343cdb4..0000000000
--- a/libmpdemux/demux_lmlm4.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * LMLM4 MPEG4 Compression Card stream & file parser
- * Copyright (C) 2003 Maxim Yevtyushkin <max@linuxmedialabs.com>
- * based on SMJPEG file parser by Alex Beregszaszi
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h> /* strtok */
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-typedef struct FrameInfo
-{
- ssize_t frameSize;
- ssize_t paddingSize;
- int frameType;
- int channelNo;
-} FrameInfo;
-
-#define FRAMETYPE_I 0
-#define FRAMETYPE_P 1
-#define FRAMETYPE_B 2
-#define FRAMETYPE_AUDIO_MPEG1L2 4
-#define FRAMETYPE_AUDIO_ULAW 5
-#define FRAMETYPE_AUDIO_ADPCM 6
-
-#define PACKET_BLOCK_SIZE 0x00000200
-#define PACKET_BLOCK_LAST 0x000001FF
-#define PACKET_BLOCK_MASK 0xFFFFFE00
-
-#define MAX_PACKET_SIZE 1048576 // 1 Mb
-
-#define STREAM_START_CODE_SIZE 4
-
-/*
-// codes in MSB first
-static unsigned int start_code [] =
-{
- 0xB0010000, // VISUAL_OBJECT_SEQUENCE_START_CODE
- 0xB6010000, // VOP_START_CODE
- 0x04C4FDFF, // MPEG1LAYERII_START_CODE
- 0x00000000 // end of start codes list
-};
-*/
-
-static int imeHeaderValid(FrameInfo *frame)
-{
- if ( frame->channelNo > 7 ||
- frame->frameSize > MAX_PACKET_SIZE || frame->frameSize <= 0)
- {
- mp_msg(MSGT_DEMUX, MSGL_V,
- "Invalid packet in LMLM4 stream: ch=%d size=%zd\n",
- frame->channelNo, frame->frameSize);
- return 0;
- }
- switch (frame->frameType) {
- case FRAMETYPE_I:
- case FRAMETYPE_P:
- case FRAMETYPE_B:
- case FRAMETYPE_AUDIO_MPEG1L2:
- case FRAMETYPE_AUDIO_ULAW:
- case FRAMETYPE_AUDIO_ADPCM:
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_V, "Invalid packet in LMLM4 stream (wrong packet type %d)\n", frame->frameType);
- return 0;
- }
- return 1;
-}
-
-/*
-int searchMPEG4Stream(demuxer_t* demuxer, IME6400Header *imeHeader)
-{
- void *data;
- ssize_t imeHeaderSize = sizeof(IME6400Header);
- ssize_t dataSize = sizeof(IME6400Header) * 3;
- ssize_t ptr = imeHeaderSize * 2;
- int errNo, startCodeNo;
- off_t pos;
-
- data = malloc(dataSize);
-
- imeHeaderSwap(imeHeader);
- memcpy(data + imeHeaderSize, imeHeader, imeHeaderSize);
-
-// printHex(data + imeHeaderSize, imeHeaderSize);
-
- while ((errNo = stream_read(demuxer->stream, data + imeHeaderSize * 2 , imeHeaderSize)) == imeHeaderSize)
- {
-// printHex(data + imeHeaderSize * 2, imeHeaderSize);
-
- pos = stream_tell(demuxer->stream);
- while (dataSize - ptr >= STREAM_START_CODE_SIZE) {
- startCodeNo = 0;
- while (start_code[startCodeNo])
- {
- if (memcmp(&start_code[startCodeNo], data + ptr, STREAM_START_CODE_SIZE) == 0) // start code match
- {
- memcpy(imeHeader, data + ptr - imeHeaderSize, imeHeaderSize);
- imeHeaderSwap(imeHeader);
- if (imeHeaderValid(imeHeader))
- {
- stream_seek(demuxer->stream, pos - (dataSize - ptr));
- free(data);
- return 0;
- }
- }
- startCodeNo++;
- }
- ptr++;
- }
- memcpy(data,data + imeHeaderSize, imeHeaderSize * 2);
- ptr -= imeHeaderSize;
- }
-
- free(data);
- return errNo;
-}
-*/
-
-static int getFrame(demuxer_t *demuxer, FrameInfo *frameInfo)
-{
- unsigned int packetSize;
-
- frameInfo->channelNo = stream_read_word(demuxer->stream);
- frameInfo->frameType = stream_read_word(demuxer->stream);
- packetSize=stream_read_dword(demuxer->stream);
-
- if(stream_eof(demuxer->stream)){
- frameInfo->frameSize = 0;
- return 0;
- }
-
- frameInfo->frameSize = packetSize - 8; //sizeof(IME6400Header);
- frameInfo->paddingSize = (packetSize & PACKET_BLOCK_LAST) ? PACKET_BLOCK_SIZE - (packetSize & PACKET_BLOCK_LAST) : 0;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "typ: %d chan: %d size: %zd pad: %zd\n",
- frameInfo->frameType,
- frameInfo->channelNo,
- frameInfo->frameSize,
- frameInfo->paddingSize);
-
- if(!imeHeaderValid(frameInfo)){
- // skip this packet
- stream_skip(demuxer->stream,PACKET_BLOCK_SIZE-8);
- frameInfo->frameSize = 0;
- return -1;
- }
-
- return 1;
-}
-
-static int lmlm4_check_file(demuxer_t* demuxer)
-{
- FrameInfo frameInfo;
- unsigned int first;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "Checking for LMLM4 Stream Format\n");
-
- if(getFrame(demuxer, &frameInfo)!=1){
- mp_msg(MSGT_DEMUX, MSGL_V, "LMLM4 Stream Format not found\n");
- return 0;
- }
- first=stream_read_dword(demuxer->stream);
- stream_skip(demuxer->stream,-12);
-
- mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: first=0x%08X\n",first);
-
- switch(frameInfo.frameType){
- case FRAMETYPE_AUDIO_MPEG1L2:
- if( (first & 0xffe00000) != 0xffe00000 ){
- mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: not mpeg audio\n");
- return 0;
- }
- if((4-((first>>17)&3))!=2){
- mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: not layer-2\n");
- return 0;
- }
- if(((first>>10)&0x3)==3){
- mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: invalid audio sampelrate\n");
- return 0;
- }
- mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: first packet is audio, header checks OK!\n");
- break;
- // TODO: add checks for video header too, for case of disabled audio
- }
-
-
-// stream_reset(demuxer->stream);
- mp_msg(MSGT_DEMUX, MSGL_V, "LMLM4 Stream Format found\n");
-
- return DEMUXER_TYPE_LMLM4;
-}
-
-static int video = 0;
-static int frames= 0;
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_lmlm4_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
-{
- FrameInfo frameInfo;
- double pts;
- int id=1;
- int ret;
-
-//hdr:
- demux->filepos = stream_tell(demux->stream);
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "fpos = %"PRId64"\n", (int64_t)demux->filepos);
-
- ret=getFrame(demux, &frameInfo);
- if(ret<=0) return ret; // EOF/error
-
- pts=demux->video->sh ? frames*((sh_video_t*)(demux->video->sh))->frametime : 0;
-
- switch(frameInfo.frameType){
- case FRAMETYPE_AUDIO_MPEG1L2:
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Audio Packet\n");
- if (!video)
- {
- stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize);
- mp_msg(MSGT_DEMUX, MSGL_V, "Skip Audio Packet\n");
- return -1; //goto hdr;
- }
- if(demux->audio->id==-1){
- if(!demux->a_streams[id]) new_sh_audio(demux,id);
- demux->audio->id=id;
- demux->audio->sh=demux->a_streams[id];
- ((sh_audio_t*)(demux->audio->sh))->format=0x50; // mpeg audio layer 1/2
- }
- if(demux->audio->id==id)
- ds_read_packet(demux->audio, demux->stream, frameInfo.frameSize,
- pts, demux->filepos, 0);
- else
- stream_skip(demux->stream,frameInfo.frameSize);
- break;
- case FRAMETYPE_I:
- if (!video) {
- video = 1;
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, "First Video Packet\n");
- }
- case FRAMETYPE_P:
- frames=(frames+1)&(1024*1024-1); // wrap around at 4 hrs to avoid inaccurate float calculations
- if (!video)
- {
- stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize);
- mp_msg(MSGT_DEMUX, MSGL_V, "Skip Video P Packet\n");
- return -1; //goto hdr;
- }
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Video Packet\n");
- if(demux->video->id==-1){
- if(!demux->v_streams[id]) new_sh_video(demux,id);
- demux->video->id=id;
- demux->video->sh=demux->v_streams[id];
- ((sh_video_t*)(demux->video->sh))->format=0x10000004; // mpeg4-ES
- }
- if(demux->video->id==id)
- ds_read_packet(demux->video, demux->stream, frameInfo.frameSize,
- pts, demux->filepos, 0);
- break;
- default:
- stream_skip(demux->stream,frameInfo.frameSize);
- }
-
- stream_skip(demux->stream, frameInfo.paddingSize);
-
- return 1;
-}
-
-static demuxer_t* demux_open_lmlm4(demuxer_t* demuxer){
- sh_audio_t *sh_audio=NULL;
- sh_video_t *sh_video=NULL;
-
-#if 0
- sh_video_t* sh_video;
- sh_audio_t* sh_audio;
- unsigned int htype = 0, hleng;
- int i = 0;
-
- sh_video = new_sh_video(demuxer, 0);
- demuxer->video->sh = sh_video;
- sh_video->ds = demuxer->video;
- sh_video->disp_w = 640;
- sh_video->disp_h = 480;
- sh_video->format = mmioFOURCC('D','I','V','X');
-
- sh_video->bih = calloc(1, sizeof(*sh_video->bih));
-
- /* these are false values */
- sh_video->bih->biSize = 40;
- sh_video->bih->biWidth = sh_video->disp_w;
- sh_video->bih->biHeight = sh_video->disp_h;
- sh_video->bih->biPlanes = 3;
- sh_video->bih->biBitCount = 16;
- sh_video->bih->biCompression = sh_video->format;
- sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h;
-
- sh_audio = new_sh_audio(demuxer, 0);
- demuxer->audio->sh = sh_audio;
- sh_audio->ds = demuxer->audio;
-
- sh_audio->wf = calloc(1, sizeof(*sh_audio->wf));
-
- sh_audio->samplerate = 48000;
- sh_audio->wf->wBitsPerSample = 16;
- sh_audio->channels = 2;
- sh_audio->format = 0x50;
- sh_audio->wf->wFormatTag = sh_audio->format;
- sh_audio->wf->nChannels = sh_audio->channels;
- sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
- sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels*
- sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8;
- sh_audio->wf->nBlockAlign = sh_audio->channels *2;
- sh_audio->wf->cbSize = 0;
-
-#endif
-
- demuxer->seekable = 0;
-
- if(!ds_fill_buffer(demuxer->video)){
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "LMLM4: %s",
- mp_gtext("No video stream found.\n"));
- demuxer->video->sh=NULL;
- } else {
- sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
- }
- if(demuxer->audio->id!=-2) {
- if(!ds_fill_buffer(demuxer->audio)){
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "LMLM4: %s",
- mp_gtext("No audio stream found -> no sound.\n"));
- demuxer->audio->sh=NULL;
- } else {
- sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
- }
- }
-
- return demuxer;
-}
-
-static void demux_close_lmlm4(demuxer_t *demuxer)
-{
-// printf("Close LMLM4 Stream\n");
- return;
-}
-
-
-const demuxer_desc_t demuxer_desc_lmlm4 = {
- "LMLM4 MPEG4 Compression Card stream demuxer",
- "lmlm4",
- "RAW LMLM4",
- "Maxim Yevtyushkin",
- "",
- DEMUXER_TYPE_LMLM4,
- 0, // unsafe autodetect
- lmlm4_check_file,
- demux_lmlm4_fill_buffer,
- demux_open_lmlm4,
- demux_close_lmlm4,
- NULL,
- NULL
-};
diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c
deleted file mode 100644
index 96fb1a2d86..0000000000
--- a/libmpdemux/demux_mov.c
+++ /dev/null
@@ -1,2350 +0,0 @@
-/*
- * QuickTime MOV file parser
- * copyright(c) 2001 A'rpi
- * additional work by Atmos
- * based on TOOLS/movinfo.c by A'rpi & Al3x
- * compressed header support from moov.c of the openquicktime lib.
- *
- * references: http://openquicktime.sf.net/, http://www.heroinewarrior.com/
- * http://www.geocities.com/SiliconValley/Lakes/2160/fformats/files/mov.pdf
- * (above URL no longer works, file mirrored somewhere? ::atmos)
- * The QuickTime File Format PDF from Apple:
- * http://developer.apple.com/techpubs/quicktime/qtdevdocs/PDF/QTFileFormat.pdf
- * (Complete list of documentation at http://developer.apple.com/quicktime/)
- * MP4-Lib sources from http://mpeg4ip.sf.net/ might be useful for .mp4
- * as well as .mov specific stuff.
- *
- * All sort of Stuff about MPEG4:
- * http://www.cmlab.csie.ntu.edu.tw/~pkhsiao/thesis.html
- * I really recommend N4270-1.doc and N4270-2.doc which are exact specs
- * of the MP4-File Format and the MPEG4 Specific extensions. ::atmos
- * TSGS#15(02)0088
- * http://www.3gpp.org/ftp/tsg_sa/TSG_SA/TSGS_15/Docs/pdf/SP-020088.pdf
- * http://www.3gpp2.org/Public_html/specs/C.S0050-0_v1.0_121503.pdf
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include <libavutil/common.h>
-#include <libavutil/intreadwrite.h>
-
-#include "config.h"
-
-#ifdef CONFIG_QUICKTIME
-#include <QuickTime/QuickTime.h>
-#include <QuickTime/ImageCompression.h>
-#include <QuickTime/ImageCodec.h>
-#else
-#include "loader/qtx/qtxsdk/components.h"
-#endif
-
-#if CONFIG_ZLIB
-#include <zlib.h>
-#endif
-
-#ifndef _FCNTL_H
-#include <fcntl.h>
-#endif
-
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-#include "libmpcodecs/img_format.h"
-
-#include "sub/sub.h"
-
-#include "demux_mov.h"
-#include "qtpalette.h"
-#include "parse_mp4.h" // .MP4 specific stuff
-
-#define char2short(x,y) AV_RB16(&(x)[(y)])
-#define char2int(x,y) AV_RB32(&(x)[(y)])
-
-typedef struct {
- unsigned int pts; // duration
- unsigned int size;
- off_t pos;
-} mov_sample_t;
-
-typedef struct {
- unsigned int sample; // number of the first sample in the chunk
- unsigned int size; // number of samples in the chunk
- int desc; // for multiple codecs mode - not used
- off_t pos;
-} mov_chunk_t;
-
-typedef struct {
- unsigned int first;
- unsigned int spc;
- unsigned int sdid;
-} mov_chunkmap_t;
-
-typedef struct {
- unsigned int num;
- unsigned int dur;
-} mov_durmap_t;
-
-typedef struct {
- unsigned int dur;
- unsigned int pos;
- int speed;
- //
- int frames;
- int start_sample;
- int start_frame;
- int pts_offset;
-} mov_editlist_t;
-
-#define MOV_TRAK_UNKNOWN 0
-#define MOV_TRAK_VIDEO 1
-#define MOV_TRAK_AUDIO 2
-#define MOV_TRAK_FLASH 3
-#define MOV_TRAK_GENERIC 4
-#define MOV_TRAK_CODE 5
-
-typedef struct {
- int id;
- int type;
- off_t pos;
- //
- unsigned int media_handler;
- unsigned int data_handler;
- //
- int timescale;
- unsigned int length;
- int samplesize; // 0 = variable
- int duration; // 0 = variable
- int width,height; // for video
- unsigned int fourcc;
- unsigned int nchannels;
- unsigned int samplebytes;
- //
- int tkdata_len; // track data
- unsigned char* tkdata;
- int stdata_len; // stream data
- unsigned char* stdata;
- //
- unsigned char* stream_header;
- int stream_header_len; // if >0, this header should be sent before the 1st frame
- //
- int samples_size;
- mov_sample_t* samples;
- int chunks_size;
- mov_chunk_t* chunks;
- int chunkmap_size;
- mov_chunkmap_t* chunkmap;
- int durmap_size;
- mov_durmap_t* durmap;
- int keyframes_size;
- unsigned int* keyframes;
- int editlist_size;
- mov_editlist_t* editlist;
- int editlist_pos;
- //
- void* desc; // image/sound/etc description (pointer to ImageDescription etc)
-} mov_track_t;
-
-static void mov_build_index(mov_track_t* trak,int timescale){
- int i,j,s;
- int last=trak->chunks_size;
- unsigned int pts=0;
-
-#if 0
- if (trak->chunks_size <= 0)
- {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "No chunk offset table, trying to build one!\n");
-
- trak->chunks_size = trak->samples_size; /* XXX: FIXME ! */
- // audit: this code will be vulnerable if it is reenabled (currently #if 0)
- trak->chunks = realloc(trak->chunks, sizeof(mov_chunk_t)*trak->chunks_size);
-
- for (i=0; i < trak->chunks_size; i++)
- trak->chunks[i].pos = -1;
- }
-#endif
-
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV track #%d: %d chunks, %d samples\n",trak->id,trak->chunks_size,trak->samples_size);
- mp_msg(MSGT_DEMUX, MSGL_V, "pts=%d scale=%d time=%5.3f\n",trak->length,trak->timescale,(float)trak->length/(float)trak->timescale);
-
- // process chunkmap:
- i=trak->chunkmap_size;
- while(i>0){
- --i;
- j=trak->chunkmap[i].first;
- for(;j>=0 && j<last;j++){
- trak->chunks[j].desc=trak->chunkmap[i].sdid;
- trak->chunks[j].size=trak->chunkmap[i].spc;
- }
- last=FFMIN(trak->chunkmap[i].first, trak->chunks_size);
- }
-
-#if 0
- for (i=0; i < trak->chunks_size; i++)
- {
- /* fixup position */
- if (trak->chunks[i].pos == -1)
- if (i > 0)
- trak->chunks[i].pos = trak->chunks[i-1].pos + trak->chunks[i-1].size;
- else
- trak->chunks[i].pos = 0; /* FIXME: set initial pos */
-#endif
-
- // calc pts of chunks:
- s=0;
- for(j=0;j<trak->chunks_size;j++){
- trak->chunks[j].sample=s;
- s+=trak->chunks[j].size;
- }
- i = 0;
- for (j = 0; j < trak->durmap_size; j++)
- i += trak->durmap[j].num;
- if (i != s) {
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "MOV: durmap and chunkmap sample count differ (%i vs %i)\n", i, s);
- if (i > s) s = i;
- }
-
- // workaround for fixed-size video frames (dv and uncompressed)
- if(!trak->samples_size && trak->type!=MOV_TRAK_AUDIO){
- trak->samples=calloc(s, sizeof(mov_sample_t));
- trak->samples_size=trak->samples ? s : 0;
- for(i=0;i<trak->samples_size;i++)
- trak->samples[i].size=trak->samplesize;
- trak->samplesize=0;
- }
-
- if(!trak->samples_size){
- // constant sampesize
- if(trak->durmap_size==1 || (trak->durmap_size==2 && trak->durmap[1].num==1)){
- trak->duration=trak->durmap[0].dur;
- } else mp_msg(MSGT_DEMUX, MSGL_ERR, "*** constant samplesize & variable duration not yet supported! ***\nContact the author if you have such sample file!\n");
- return;
- }
-
- if (trak->samples_size < s) {
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "MOV: durmap or chunkmap bigger than sample count (%i vs %i)\n",
- s, trak->samples_size);
- free(trak->samples);
- trak->samples = calloc(s, sizeof(mov_sample_t));
- trak->samples_size = trak->samples ? s : 0;
- }
-
- // calc pts:
- s=0;
- for(j=0;j<trak->durmap_size;j++){
- for(i=0;i<trak->durmap[j].num;i++){
- if (s >= trak->samples_size)
- break;
- trak->samples[s].pts=pts;
- ++s;
- pts+=trak->durmap[j].dur;
- }
- }
-
- // calc sample offsets
- s=0;
- for(j=0;j<trak->chunks_size;j++){
- off_t pos=trak->chunks[j].pos;
- for(i=0;i<trak->chunks[j].size;i++){
- if (s >= trak->samples_size)
- break;
- trak->samples[s].pos=pos;
- mp_msg(MSGT_DEMUX, MSGL_DBG3, "Sample %5d: pts=%8d off=0x%08X size=%d\n",s,
- trak->samples[s].pts,
- (int)trak->samples[s].pos,
- trak->samples[s].size);
- pos+=trak->samples[s].size;
- ++s;
- }
- }
-
- // precalc editlist entries
- if(trak->editlist_size>0){
- int frame=0;
- int e_pts=0;
- for(i=0;i<trak->editlist_size;i++){
- mov_editlist_t* el=&trak->editlist[i];
- int sample=0;
- int pts=el->pos;
- el->start_frame=frame;
- if(pts<0){
- // skip!
- el->frames=0; continue;
- }
- // find start sample
- for(;sample<trak->samples_size;sample++){
- if(pts<=trak->samples[sample].pts) break;
- }
- el->start_sample=sample;
- el->pts_offset=((long long)e_pts*(long long)trak->timescale)/(long long)timescale-trak->samples[sample].pts;
- pts+=((long long)el->dur*(long long)trak->timescale)/(long long)timescale;
- e_pts+=el->dur;
- // find end sample
- for(;sample<trak->samples_size;sample++){
- if(pts<trak->samples[sample].pts) break;
- }
- el->frames=sample-el->start_sample;
- frame+=el->frames;
- mp_msg(MSGT_DEMUX,MSGL_V,"EL#%d: pts=%d 1st_sample=%d frames=%d (%5.3fs) pts_offs=%d\n",i,
- el->pos,el->start_sample, el->frames,
- (float)(el->dur)/(float)timescale, el->pts_offset);
- }
- }
-
-}
-
-#define MOV_MAX_TRACKS 256
-#define MOV_MAX_SUBLEN 1024
-
-typedef struct {
- off_t moov_start;
- off_t moov_end;
- off_t mdat_start;
- off_t mdat_end;
- int track_db;
- mov_track_t* tracks[MOV_MAX_TRACKS];
- int timescale; // movie timescale
- int duration; // movie duration (in movie timescale units)
- subtitle subs;
- char subtext[MOV_MAX_SUBLEN + 1];
- int current_sub;
-} mov_priv_t;
-
-#define MOV_FOURCC(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d))
-
-static int mov_check_file(demuxer_t* demuxer){
- int flags=0;
- int no=0;
- mov_priv_t* priv=calloc(1, sizeof(mov_priv_t));
-
- mp_msg(MSGT_DEMUX,MSGL_V,"Checking for MOV\n");
-
- priv->current_sub = -1;
-
- while(1){
- int i;
- int skipped=8;
- off_t len=stream_read_dword(demuxer->stream);
- unsigned int id=stream_read_dword(demuxer->stream);
- if(stream_eof(demuxer->stream)) break; // EOF
- if (len == 1) /* real size is 64bits - cjb */
- {
-#ifndef _LARGEFILE_SOURCE
- if (stream_read_dword(demuxer->stream) != 0)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "64bit file, but you've compiled MPlayer without LARGEFILE support!\n");
- len = stream_read_dword(demuxer->stream);
-#else
- len = stream_read_qword(demuxer->stream);
-#endif
- skipped += 8;
- }
-#if 0
- else if (len == 0) /* deleted chunk */
- {
- /* XXX: CJB! is this right? - alex */
- goto skip_chunk;
- }
-#endif
- if(len<8) break; // invalid chunk
-
- switch(id){
- case MOV_FOURCC('f','t','y','p'): {
- unsigned int tmp;
- // File Type Box (ftyp):
- // char[4] major_brand (eg. 'isom')
- // int minor_version (eg. 0x00000000)
- // char[4] compatible_brands[] (eg. 'mp41')
- // compatible_brands list spans to the end of box
-#if 1
- tmp = stream_read_dword(demuxer->stream);
- switch(tmp) {
- case MOV_FOURCC('i','s','o','m'):
- mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Major Brand: ISO Base Media\n");
- break;
- case MOV_FOURCC('m','p','4','1'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: ISO/IEC 14496-1 (MPEG-4 system) v1\n");
- break;
- case MOV_FOURCC('m','p','4','2'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: ISO/IEC 14496-1 (MPEG-4 system) v2\n");
- break;
- case MOV_FOURCC('M','4','A',' '):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Apple iTunes AAC-LC Audio\n");
- break;
- case MOV_FOURCC('M','4','P',' '):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Apple iTunes AAC-LC Protected Audio\n");
- break;
- case MOV_FOURCC('q','t',' ',' '):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Original QuickTime\n");
- break;
- case MOV_FOURCC('3','g','p','1'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 1\n");
- break;
- case MOV_FOURCC('3','g','p','2'):
- case MOV_FOURCC('3','g','2','a'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 2\n");
- break;
- case MOV_FOURCC('3','g','p','3'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 3\n");
- break;
- case MOV_FOURCC('3','g','p','4'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 4\n");
- break;
- case MOV_FOURCC('3','g','p','5'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 5\n");
- break;
- case MOV_FOURCC('m','m','p','4'):
- mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Mobile ISO/IEC 14496-1 (MPEG-4 system)\n");
- break;
- default:
- tmp = be2me_32(tmp);
- mp_msg(MSGT_DEMUX,MSGL_WARN,"ISO: Unknown File Type Major Brand: %.4s\n",(char *)&tmp);
- }
- mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Minor Version: %d\n",
- stream_read_dword(demuxer->stream));
- skipped += 8;
- // List all compatible brands
- for(i = 0; i < ((len-16)/4); i++) {
- tmp = be2me_32(stream_read_dword(demuxer->stream));
- mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Compatible Brand #%d: %.4s\n",i,(char *)&tmp);
- skipped += 4;
- }
-#endif
- } break;
- case MOV_FOURCC('m','o','o','v'):
-// case MOV_FOURCC('c','m','o','v'):
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Movie header found!\n");
- priv->moov_start=(off_t)stream_tell(demuxer->stream);
- priv->moov_end=(off_t)priv->moov_start+len-skipped;
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"MOV: Movie header: start: %"PRIx64" end: %"PRIx64"\n",
- (int64_t)priv->moov_start, (int64_t)priv->moov_end);
- skipped+=8;
- i = stream_read_dword(demuxer->stream)-8;
- if(stream_read_dword(demuxer->stream)==MOV_FOURCC('r','m','r','a')){
- skipped+=i;
- mp_msg(MSGT_DEMUX,MSGL_INFO,"MOV: Reference Media file!!!\n");
- //set demuxer type to playlist ...
- demuxer->type=DEMUXER_TYPE_PLAYLIST;
- while(i>0){
- int len=stream_read_dword(demuxer->stream)-8;
- int fcc=stream_read_dword(demuxer->stream);
- if(len<0) break; // EOF!?
- i-=8;
-// printf("i=%d len=%d\n",i,len);
- switch(fcc){
- case MOV_FOURCC('r','m','d','a'):
- continue;
- case MOV_FOURCC('r','d','r','f'): {
- av_unused int tmp=stream_read_dword(demuxer->stream);
- av_unused int type=stream_read_dword_le(demuxer->stream);
- int slen=stream_read_dword(demuxer->stream);
- //char* s=malloc(slen+1);
- //stream_read(demuxer->stream,s,slen);
-
- //FIXME: also store type & data_rate ?
- ds_read_packet(demuxer->video,
- demuxer->stream,
- slen,
- 0,
- stream_tell(demuxer->stream),
- 0 // no flags
- );
- flags|=4;
- mp_msg(MSGT_DEMUX,MSGL_V,"Added reference to playlist\n");
- //s[slen]=0;
- //mp_msg(MSGT_DEMUX,MSGL_INFO,"REF: [%.4s] %s\n",&type,s);
- len-=12+slen;i-=12+slen; break;
- }
- case MOV_FOURCC('r','m','d','r'): {
- av_unused int flags=stream_read_dword(demuxer->stream);
- int rate=stream_read_dword(demuxer->stream);
- mp_msg(MSGT_DEMUX,MSGL_V," min. data rate: %d bits/sec\n",rate);
- len-=8; i-=8; break;
- }
- case MOV_FOURCC('r','m','q','u'): {
- int q=stream_read_dword(demuxer->stream);
- mp_msg(MSGT_DEMUX,MSGL_V," quality index: %d\n",q);
- len-=4; i-=4; break;
- }
- }
- i-=len;stream_skip(demuxer->stream,len);
- }
- }
- flags|=1;
- break;
- case MOV_FOURCC('w','i','d','e'):
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: 'WIDE' chunk found!\n");
- if(flags&2) break;
- case MOV_FOURCC('m','d','a','t'):
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Movie DATA found!\n");
- priv->mdat_start=stream_tell(demuxer->stream);
- priv->mdat_end=priv->mdat_start+len-skipped;
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"MOV: Movie data: start: %"PRIx64" end: %"PRIx64"\n",
- (int64_t)priv->mdat_start, (int64_t)priv->mdat_end);
- flags|=2;
- if(flags==3){
- // if we're over the headers, then we can stop parsing here!
- demuxer->priv=priv;
- return DEMUXER_TYPE_MOV;
- }
- break;
- case MOV_FOURCC('f','r','e','e'):
- case MOV_FOURCC('s','k','i','p'):
- case MOV_FOURCC('j','u','n','k'):
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"MOV: free space (len: %"PRId64")\n", (int64_t)len);
- /* unused, if you edit a mov, you can use space provided by free atoms (redefining it) */
- break;
- case MOV_FOURCC('p','n','o','t'):
- case MOV_FOURCC('P','I','C','T'):
- /* dunno what, but we shoudl ignore it */
- break;
- default:
- if(no==0){ free(priv); return 0;} // first chunk is bad!
- id = be2me_32(id);
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: unknown chunk: %.4s %d\n",(char *)&id,(int)len);
- }
-//skip_chunk:
- if(!stream_skip(demuxer->stream,len-skipped)) break;
- ++no;
- }
-
- if(flags==3){
- demuxer->priv=priv;
- return DEMUXER_TYPE_MOV;
- }
- free(priv);
-
- if ((flags==5) || (flags==7)) // reference & header sent
- return DEMUXER_TYPE_PLAYLIST;
-
- if(flags==1)
- mp_msg(MSGT_DEMUX,MSGL_WARN,"MOV: missing data (mdat) chunk! Maybe broken file...\n");
- else if(flags==2)
- mp_msg(MSGT_DEMUX,MSGL_WARN,"MOV: missing header (moov/cmov) chunk! Maybe broken file...\n");
-
- return 0;
-}
-
-static void demux_close_mov(demuxer_t *demuxer) {
- mov_priv_t* priv = demuxer->priv;
- int i;
- if (!priv)
- return;
- for (i = 0; i < MOV_MAX_TRACKS; i++) {
- mov_track_t *track = priv->tracks[i];
- if (track) {
- free(track->tkdata);
- free(track->stdata);
- free(track->stream_header);
- free(track->samples);
- free(track->chunks);
- free(track->chunkmap);
- free(track->durmap);
- free(track->keyframes);
- free(track->editlist);
- free(track->desc);
- free(track);
- }
- }
- free(priv);
-}
-
-unsigned int store_ughvlc(unsigned char *s, unsigned int v){
- unsigned int n = 0;
-
- while(v >= 0xff) {
- *s++ = 0xff;
- v -= 0xff;
- n++;
- }
- *s = v;
- n++;
-
- return n;
-}
-
-static void init_vobsub(sh_sub_t *sh, mov_track_t *trak) {
- sh->type = 'v';
- if (trak->stdata_len < 106)
- return;
- sh->extradata_len = 16*4;
- sh->extradata = malloc(sh->extradata_len);
- memcpy(sh->extradata, trak->stdata + 42, sh->extradata_len);
-}
-
-static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id,
- off_t pos, off_t len, mov_track_t* trak);
-
-static int gen_sh_audio(sh_audio_t* sh, mov_track_t* trak, int timescale) {
-#if 0
- struct {
- int16_t version; // 0 or 1 (version 1 is qt3.0+)
- int16_t revision; // 0
- int32_t vendor_id; // 0
- int16_t channels; // 1 or 2 (Mono/Stereo)
- int16_t samplesize; // 8 or 16 (8Bit/16Bit)
- int16_t compression_id; // if version 0 then 0
- // if version 1 and vbr then -2 else 0
- int16_t packet_size; // 0
- uint16_t sample_rate; // samplerate (Hz)
- // qt3.0+ (version == 1)
- uint32_t samples_per_packet; // 0 or num uncompressed samples in a packet
- // if 0 below three values are also 0
- uint32_t bytes_per_packet; // 0 or num compressed bytes for one channel
- uint32_t bytes_per_frame; // 0 or num compressed bytes for all channels
- // (channels * bytes_per_packet)
- uint32_t bytes_per_sample; // 0 or size of uncompressed sample
- // if samples_per_packet and bytes_per_packet are constant (CBR)
- // then bytes_per_frame and bytes_per_sample must be 0 (else is VBR)
- // ---
- // optional additional atom-based fields
- // ([int32_t size,int32_t type,some data ],repeat)
- } my_stdata;
-#endif
- int version = -1, adjust;
- int is_vorbis = 0;
- sh->format=trak->fourcc;
-
- // crude audio delay from editlist0 hack ::atm
- if(trak->editlist_size>=1) {
- if(trak->editlist[0].pos == -1) {
- sh->stream_delay = (float)trak->editlist[0].dur/(float)timescale;
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Audio-Delay: %.3f sec\n", sh->stream_delay);
- }
- }
-
-
- switch( sh->format ) {
- case 0x726D6173: /* samr */
- /* amr narrowband */
- trak->samplebytes=sh->samplesize=1;
- trak->nchannels=sh->channels=1;
- sh->samplerate=8000;
- break;
-
- case 0x62776173: /* sawb */
- /* amr wideband */
- trak->samplebytes=sh->samplesize=1;
- trak->nchannels=sh->channels=1;
- sh->samplerate=16000;
- break;
-
- default:
-
-// assumptions for below table: short is 16bit, int is 32bit, intfp is 16bit
-// XXX: 32bit fixed point numbers (intfp) are only 2 Byte!
-// short values are usually one byte leftpadded by zero
-// int values are usually two byte leftpadded by zero
-// stdata[]:
-// 8 short version
-// 10 short revision
-// 12 int vendor_id
-// 16 short channels
-// 18 short samplesize
-// 20 short compression_id
-// 22 short packet_size (==0)
-// 24 intfp sample_rate
-// (26 short) unknown (==0)
-// ---- qt3.0+ (version>=1)
-// 28 int samples_per_packet
-// 32 int bytes_per_packet
-// 36 int bytes_per_frame
-// 40 int bytes_per_sample
-// there may be additional atoms following at 28 (version 0)
-// or 44 (version 1), eg. esds atom of .MP4 files
-// esds atom:
-// 28 int atom size (bytes of int size, int type and data)
-// 32 char[4] atom type (fourc charater code -> esds)
-// 36 char[] atom data (len=size-8)
-
-// TODO: fix parsing for files using version 2.
- if (trak->stdata_len < 26) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: broken (too small) sound atom!\n");
- return 0;
- }
- version=char2short(trak->stdata,8);
- if (version > 1)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: version %d sound atom may not parse correctly!\n", version);
- trak->samplebytes=sh->samplesize=char2short(trak->stdata,18)/8;
-
- /* I can't find documentation, but so far this is the case. -Corey */
- switch (char2short(trak->stdata,16)) {
- case 1:
- trak->nchannels = 1; break;
- case 2:
- trak->nchannels = 2; break;
- case 3:
- trak->nchannels = 6; break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "MOV: unable to determine audio channels, assuming 2 (got %d)\n",
- char2short(trak->stdata,16));
- trak->nchannels = 2;
- }
- sh->channels = trak->nchannels;
-
- /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n",
- trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur,
- trak->durmap[0].num, trak->timescale/trak->durmap[0].dur,
- char2short(trak->stdata,24)/trak->durmap[0].dur);*/
- sh->samplerate=char2short(trak->stdata,24);
- if((sh->samplerate < 7000) && trak->durmap && trak->durmap[0].dur > 1) {
- switch(char2short(trak->stdata,24)/trak->durmap[0].dur) {
- // TODO: add more cases.
- case 31:
- sh->samplerate = 32000; break;
- case 43:
- sh->samplerate = 44100; break;
- case 47:
- sh->samplerate = 48000; break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "MOV: unable to determine audio samplerate, "
- "assuming 44.1kHz (got %d)\n",
- char2short(trak->stdata,24)/trak->durmap[0].dur);
- sh->samplerate = 44100;
- }
- }
- }
- mp_msg(MSGT_DEMUX, MSGL_V, "Audio bits: %d chans: %d rate: %d\n",
- sh->samplesize*8,sh->channels,sh->samplerate);
-
- if(trak->stdata_len >= 44 && trak->stdata[9]>=1){
- mp_msg(MSGT_DEMUX,MSGL_V,"Audio header: samp/pack=%d bytes/pack=%d bytes/frame=%d bytes/samp=%d \n",
- char2int(trak->stdata,28),
- char2int(trak->stdata,32),
- char2int(trak->stdata,36),
- char2int(trak->stdata,40));
- if(trak->stdata_len>=44+8){
- int len=char2int(trak->stdata,44);
- int fcc=char2int(trak->stdata,48);
- // we have extra audio headers!!!
- mp_msg(MSGT_DEMUX,MSGL_V,"Audio extra header: len=%d fcc=0x%X\n",len,fcc);
- if((len >= 4) &&
- (char2int(trak->stdata,52) >= 12) &&
- (char2int(trak->stdata,52+4) == MOV_FOURCC('f','r','m','a'))) {
- switch(char2int(trak->stdata,52+8)) {
- case MOV_FOURCC('a','l','a','c'):
- if (len >= 36 + char2int(trak->stdata,52)) {
- sh->codecdata_len = char2int(trak->stdata,52+char2int(trak->stdata,52));
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found alac atom (%d)!\n", sh->codecdata_len);
- sh->codecdata = malloc(sh->codecdata_len);
- memcpy(sh->codecdata, &trak->stdata[52+char2int(trak->stdata,52)], sh->codecdata_len);
- }
- break;
- case MOV_FOURCC('i','n','2','4'):
- case MOV_FOURCC('i','n','3','2'):
- case MOV_FOURCC('f','l','3','2'):
- case MOV_FOURCC('f','l','6','4'):
- if ((len >= 22) &&
- (char2int(trak->stdata,52+16)==MOV_FOURCC('e','n','d','a')) &&
- (char2short(trak->stdata,52+20))) {
- sh->format=char2int(trak->stdata,52+8);
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found little endian PCM data, reversed fourcc:%04x\n", sh->format);
- }
- break;
- default:
- if (len > 8 && len + 44 <= trak->stdata_len) {
- sh->codecdata_len = len-8;
- sh->codecdata = malloc(sh->codecdata_len);
- memcpy(sh->codecdata, trak->stdata+44+8, sh->codecdata_len);
- }
- }
- } else {
- if (len > 8 && len + 44 <= trak->stdata_len) {
- sh->codecdata_len = len-8;
- sh->codecdata = malloc(sh->codecdata_len);
- memcpy(sh->codecdata, trak->stdata+44+8, sh->codecdata_len);
- }
- }
- }
- }
-
- switch (version) {
- case 0:
- adjust = 0; break;
- case 1:
- adjust = 48; break;
- case 2:
- adjust = 68; break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: unknown sound atom version (%d); may not work!\n", version);
- adjust = 68;
- }
- if (trak->stdata_len >= 36 + adjust) {
- int atom_len = char2int(trak->stdata,28+adjust);
- if (atom_len < 0 || atom_len > trak->stdata_len - 28 - adjust) atom_len = trak->stdata_len - 28 - adjust;
- switch(char2int(trak->stdata,32+adjust)) { // atom type
- case MOV_FOURCC('e','s','d','s'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len);
- if(atom_len > 8) {
- esds_t esds;
- if(!mp4_parse_esds(&trak->stdata[36+adjust], atom_len-8, &esds)) {
- /* 0xdd is a "user private" id, not an official allocated id (see http://www.mp4ra.org/object.html),
- so perform some extra checks to be sure that this is really vorbis audio */
- if(esds.objectTypeId==0xdd && esds.streamType==0x15 && sh->format==0x6134706D && esds.decoderConfigLen > 8)
- {
- //vorbis audio
- unsigned char *buf[3];
- unsigned short sizes[3];
- int offset, len, k;
- unsigned char *ptr = esds.decoderConfig;
-
- if(ptr[0] != 0 || ptr[1] != 30) goto quit_vorbis_block; //wrong extradata layout
-
- offset = len = 0;
- for(k = 0; k < 3; k++)
- {
- sizes[k] = (ptr[offset]<<8) | ptr[offset+1];
- len += sizes[k];
- offset += 2;
- if(offset + sizes[k] > esds.decoderConfigLen)
- {
- mp_msg(MSGT_DEMUX, MSGL_FATAL, "MOV: ERROR!, not enough vorbis extradata to read: offset = %d, k=%d, size=%d, len: %d\n", offset, k, sizes[k], esds.decoderConfigLen);
- goto quit_vorbis_block;
- }
- buf[k] = malloc(sizes[k]);
- if(!buf[k]) goto quit_vorbis_block;
- memcpy(buf[k], &ptr[offset], sizes[k]);
- offset += sizes[k];
- }
-
- sh->codecdata_len = len + len/255 + 64;
- sh->codecdata = malloc(sh->codecdata_len);
- ptr = sh->codecdata;
-
- ptr[0] = 2;
- offset = 1;
- offset += store_ughvlc(&ptr[offset], sizes[0]);
- offset += store_ughvlc(&ptr[offset], sizes[1]);
- for(k = 0; k < 3; k++)
- {
- memcpy(&ptr[offset], buf[k], sizes[k]);
- offset += sizes[k];
- }
-
- sh->codecdata_len = offset;
- sh->codecdata = realloc(sh->codecdata, offset);
- mp_msg(MSGT_DEMUX,MSGL_V, "demux_mov, vorbis extradata size: %d\n", offset);
- is_vorbis = 1;
-quit_vorbis_block:
- sh->format = mmioFOURCC('v', 'r', 'b', 's');
- }
- sh->i_bps = esds.avgBitrate/8;
-
-// printf("######## audio format = %d ########\n",esds.objectTypeId);
- if(esds.objectTypeId==MP4OTI_MPEG1Audio || esds.objectTypeId==MP4OTI_MPEG2AudioPart3)
- sh->format=0x55; // .mp3
-
- if(esds.objectTypeId==MP4OTI_13kVoice) { // 13K Voice, defined by 3GPP2
- sh->format=mmioFOURCC('Q', 'c', 'l', 'p');
- trak->nchannels=sh->channels=1;
- trak->samplebytes=sh->samplesize=1;
- }
-
- // dump away the codec specific configuration for the AAC decoder
- if(esds.decoderConfigLen){
- if( (esds.decoderConfig[0]>>3) == 29 )
- sh->format = 0x1d61346d; // request multi-channel mp3 decoder
- if(!is_vorbis)
- {
- sh->codecdata_len = esds.decoderConfigLen;
- sh->codecdata = malloc(sh->codecdata_len);
- memcpy(sh->codecdata, esds.decoderConfig, sh->codecdata_len);
- }
- }
- }
- mp4_free_esds(&esds); // freeup esds mem
-#if 0
- { FILE* f=fopen("esds.dat","wb");
- fwrite(&trak->stdata[36],atom_len-8,1,f);
- fclose(f); }
-#endif
- }
- } break;
- case MOV_FOURCC('a','l','a','c'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found alac atom (%d)!\n", atom_len);
- if(atom_len > 8) {
- // copy all the atom (not only payload) for lavc alac decoder
- sh->codecdata_len = atom_len;
- sh->codecdata = malloc(sh->codecdata_len);
- memcpy(sh->codecdata, &trak->stdata[28], sh->codecdata_len);
- }
- } break;
- case MOV_FOURCC('d','a','m','r'):
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found AMR audio atom %c%c%c%c (%d)!\n", trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust], atom_len);
- if (atom_len>14) {
- mp_msg(MSGT_DEMUX, MSGL_V, "mov: vendor: %c%c%c%c Version: %d\n",trak->stdata[36+adjust],trak->stdata[37+adjust],trak->stdata[38+adjust], trak->stdata[39+adjust],trak->stdata[40+adjust]);
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Modes set: %02x%02x\n",trak->stdata[41+adjust],trak->stdata[42+adjust]);
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Mode change period: %d Frames per sample: %d\n",trak->stdata[43+adjust],trak->stdata[44+adjust]);
- }
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unknown audio atom %c%c%c%c (%d)!\n",
- trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust],
- atom_len);
- }
- }
- mp_msg(MSGT_DEMUX, MSGL_V, "Fourcc: %.4s\n",(char *)&trak->fourcc);
-#if 0
- { FILE* f=fopen("stdata.dat","wb");
- fwrite(trak->stdata,trak->stdata_len,1,f);
- fclose(f); }
- { FILE* f=fopen("tkdata.dat","wb");
- fwrite(trak->tkdata,trak->tkdata_len,1,f);
- fclose(f); }
-#endif
- // Emulate WAVEFORMATEX struct:
- sh->wf=calloc(1, sizeof(*sh->wf) + (is_vorbis ? sh->codecdata_len : 0));
- sh->wf->nChannels=sh->channels;
- sh->wf->wBitsPerSample=(trak->stdata[18]<<8)+trak->stdata[19];
- // sh->wf->nSamplesPerSec=trak->timescale;
- sh->wf->nSamplesPerSec=sh->samplerate;
- if(trak->stdata_len >= 44 && trak->stdata[9]>=1 && char2int(trak->stdata,28)>0){
- //Audio header: samp/pack=4096 bytes/pack=743 bytes/frame=1486 bytes/samp=2
- sh->wf->nAvgBytesPerSec=(sh->wf->nChannels*sh->wf->nSamplesPerSec*
- char2int(trak->stdata,32)+char2int(trak->stdata,28)/2)
- /char2int(trak->stdata,28);
- sh->wf->nBlockAlign=char2int(trak->stdata,36);
- } else {
- sh->wf->nAvgBytesPerSec=sh->wf->nChannels*sh->wf->wBitsPerSample*sh->wf->nSamplesPerSec/8;
- // workaround for ms11 ima4
- if (sh->format == 0x1100736d && trak->stdata_len >= 36)
- sh->wf->nBlockAlign=char2int(trak->stdata,36);
- }
-
- if(is_vorbis && sh->codecdata_len)
- {
- memcpy(sh->wf+1, sh->codecdata, sh->codecdata_len);
- sh->wf->cbSize = sh->codecdata_len;
- }
- // Selection:
-// if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){
-// // (auto)selected audio track:
-// demuxer->audio->id=priv->track_db;
-// demuxer->audio->sh=sh; sh->ds=demuxer->audio;
-// }
- return 1;
-}
-
-static int gen_sh_video(sh_video_t* sh, mov_track_t* trak, int timescale) {
- int depth, i, entry;
- int flag, start, count_flag, end, palette_count, gray;
- int hdr_ptr = 76; // the byte just after depth
- unsigned char *palette_map;
-
- sh->format=trak->fourcc;
-
- // crude video delay from editlist0 hack ::atm
- if(trak->editlist_size>=1) {
- if(trak->editlist[0].pos == -1) {
- sh->stream_delay = (float)trak->editlist[0].dur/(float)timescale;
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Video-Delay: %.3f sec\n", sh->stream_delay);
- }
- }
-
-
- if (trak->stdata_len < 78) {
- mp_msg(MSGT_DEMUXER, MSGL_WARN,
- "MOV: Invalid (%d bytes instead of >= 78) video trak desc\n",
- trak->stdata_len);
- return 0;
- }
-
- depth = trak->stdata[75] | (trak->stdata[74] << 8);
- if (trak->fourcc == mmioFOURCC('r', 'a', 'w', ' '))
- sh->format = IMGFMT_RGB | depth;
-
-// stdata[]:
-// 8 short version
-// 10 short revision
-// 12 int vendor_id
-// 16 int temporal_quality
-// 20 int spatial_quality
-// 24 short width
-// 26 short height
-// 28 int h_dpi
-// 32 int v_dpi
-// 36 int 0
-// 40 short frames_per_sample
-// 42 char[4] compressor_name
-// 74 short depth
-// 76 short color_table_id
-// additional atoms may follow,
-// eg esds atom from .MP4 files
-// 78 int atom size
-// 82 char[4] atom type
-// 86 ... atom data
-
- { ImageDescription* id=malloc(8+trak->stdata_len); // safe
- trak->desc=id;
- id->idSize=8+trak->stdata_len;
-// id->cType=bswap_32(trak->fourcc);
- id->cType=le2me_32(trak->fourcc);
- id->version=char2short(trak->stdata,8);
- id->revisionLevel=char2short(trak->stdata,10);
- id->vendor=char2int(trak->stdata,12);
- id->temporalQuality=char2int(trak->stdata,16);
- id->spatialQuality=char2int(trak->stdata,20);
- id->width=char2short(trak->stdata,24);
- id->height=char2short(trak->stdata,26);
- id->hRes=char2int(trak->stdata,28);
- id->vRes=char2int(trak->stdata,32);
- id->dataSize=char2int(trak->stdata,36);
- id->frameCount=char2short(trak->stdata,40);
- memcpy(&id->name,trak->stdata+42,32);
- id->depth=char2short(trak->stdata,74);
- id->clutID=char2short(trak->stdata,76);
- if(trak->stdata_len>78) memcpy(((char*)&id->clutID)+2,trak->stdata+78,trak->stdata_len-78);
- sh->ImageDesc=id;
-#if 0
- { FILE *f=fopen("ImageDescription","wb");
- fwrite(id,id->idSize,1,f);
- fclose(f);
- }
-#endif
- }
-
- if(trak->stdata_len >= 86) { // extra atoms found
- int pos=78;
- int atom_len;
- while(pos+8<=trak->stdata_len &&
- (pos+(atom_len=char2int(trak->stdata,pos)))<=trak->stdata_len){
- switch(char2int(trak->stdata,pos+4)) { // switch atom type
- case MOV_FOURCC('g','a','m','a'):
- // intfp with gamma value at which movie was captured
- // can be used to gamma correct movie display
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unsupported Gamma-Correction movie atom (%d)!\n",
- atom_len);
- break;
- case MOV_FOURCC('f','i','e','l'):
- // 2 char-values (8bit int) that specify field handling
- // see the Apple's QuickTime Fileformat PDF for more info
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unsupported Field-Handling movie atom (%d)!\n",
- atom_len);
- break;
- case MOV_FOURCC('m','j','q','t'):
- // Motion-JPEG default quantization table
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unsupported MJPEG-Quantization movie atom (%d)!\n",
- atom_len);
- break;
- case MOV_FOURCC('m','j','h','t'):
- // Motion-JPEG default huffman table
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unsupported MJPEG-Huffman movie atom (%d)!\n",
- atom_len);
- break;
- case MOV_FOURCC('e','s','d','s'):
- // MPEG4 Elementary Stream Descriptor header
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found MPEG4 movie Elementary Stream Descriptor atom (%d)!\n", atom_len);
- // add code here to save esds header of length atom_len-8
- // beginning at stdata[86] to some variable to pass it
- // on to the decoder ::atmos
- if(atom_len > 8) {
- esds_t esds;
- if(!mp4_parse_esds(trak->stdata+pos+8, atom_len-8, &esds)) {
-
- if(esds.objectTypeId==MP4OTI_MPEG2VisualSimple || esds.objectTypeId==MP4OTI_MPEG2VisualMain ||
- esds.objectTypeId==MP4OTI_MPEG2VisualSNR || esds.objectTypeId==MP4OTI_MPEG2VisualSpatial ||
- esds.objectTypeId==MP4OTI_MPEG2VisualHigh || esds.objectTypeId==MP4OTI_MPEG2Visual422)
- sh->format=mmioFOURCC('m', 'p', 'g', '2');
- else if(esds.objectTypeId==MP4OTI_MPEG1Visual)
- sh->format=mmioFOURCC('m', 'p', 'g', '1');
-
- // dump away the codec specific configuration for the AAC decoder
- trak->stream_header_len = esds.decoderConfigLen;
- trak->stream_header = malloc(trak->stream_header_len);
- memcpy(trak->stream_header, esds.decoderConfig, trak->stream_header_len);
- }
- mp4_free_esds(&esds); // freeup esds mem
- }
- break;
- case MOV_FOURCC('a','v','c','C'):
- // AVC decoder configuration record
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: AVC decoder configuration record atom (%d)!\n", atom_len);
- if(atom_len > 8) {
- int i, poffs, cnt;
- // Parse some parts of avcC, just for fun :)
- // real parsing is done by avc1 decoder
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC version: %d\n", *(trak->stdata+pos+8));
- if (*(trak->stdata+pos+8) != 1)
- mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: unknown avcC version (%d). Expexct problems.\n", *(trak->stdata+pos+9));
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC profile: %d\n", *(trak->stdata+pos+9));
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC profile compatibility: %d\n", *(trak->stdata+pos+10));
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC level: %d\n", *(trak->stdata+pos+11));
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC nal length size: %d\n", ((*(trak->stdata+pos+12))&0x03)+1);
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC number of sequence param sets: %d\n", cnt = (*(trak->stdata+pos+13) & 0x1f));
- poffs = pos + 14;
- for (i = 0; i < cnt; i++) {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC sps %d have length %d\n", i, AV_RB16(trak->stdata+poffs));
- poffs += AV_RB16(trak->stdata+poffs) + 2;
- }
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC number of picture param sets: %d\n", *(trak->stdata+poffs));
- poffs++;
- for (i = 0; i < cnt; i++) {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC pps %d have length %d\n", i, AV_RB16(trak->stdata+poffs));
- poffs += AV_RB16(trak->stdata+poffs) + 2;
- }
- // Copy avcC for the AVC decoder
- // This data will be put in extradata below, where BITMAPINFOHEADER is created
- trak->stream_header_len = atom_len-8;
- trak->stream_header = malloc(trak->stream_header_len);
- memcpy(trak->stream_header, trak->stdata+pos+8, trak->stream_header_len);
- }
- break;
- case MOV_FOURCC('d','2','6','3'):
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found H.263 decoder atom %c%c%c%c (%d)!\n", trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],atom_len);
- if (atom_len>10)
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Vendor: %c%c%c%c H.263 level: %d H.263 profile: %d \n", trak->stdata[pos+8],trak->stdata[pos+9],trak->stdata[pos+10],trak->stdata[pos+11],trak->stdata[pos+12],trak->stdata[pos+13]);
- break;
- case 0:
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unknown movie atom %c%c%c%c (%d)!\n",
- trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],
- atom_len);
- }
- if(atom_len<8) break;
- pos+=atom_len;
-// printf("pos=%d max=%d\n",pos,trak->stdata_len);
- }
- }
- sh->fps=trak->timescale/
- ((trak->durmap_size>=1)?(float)trak->durmap[0].dur:1);
- sh->frametime=1.0f/sh->fps;
-
- sh->disp_w=trak->stdata[25]|(trak->stdata[24]<<8);
- sh->disp_h=trak->stdata[27]|(trak->stdata[26]<<8);
- if(trak->tkdata_len>81) {
- // if image size is zero, fallback to display size
- if(!sh->disp_w && !sh->disp_h) {
- sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8);
- sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8);
- } else if(sh->disp_w!=(trak->tkdata[77]|(trak->tkdata[76]<<8))){
- // codec and display width differ... use display one for aspect
- sh->aspect=trak->tkdata[77]|(trak->tkdata[76]<<8);
- sh->aspect/=trak->tkdata[81]|(trak->tkdata[80]<<8);
- }
- }
-
- if(depth>32+8) mp_msg(MSGT_DEMUX, MSGL_INFO,"*** depth = 0x%X\n",depth);
-
- // palettized?
- gray = 0;
- if (depth > 32) { depth&=31; gray = 1; } // depth > 32 means grayscale
- if ((depth == 2) || (depth == 4) || (depth == 8))
- palette_count = (1 << depth);
- else
- palette_count = 0;
-
- // emulate BITMAPINFOHEADER:
- if (palette_count)
- {
- sh->bih=calloc(1, sizeof(*sh->bih) + palette_count * 4);
- sh->bih->biSize=40 + palette_count * 4;
- // fetch the relevant fields
- flag = AV_RB16(&trak->stdata[hdr_ptr]);
- hdr_ptr += 2;
- start = AV_RB32(&trak->stdata[hdr_ptr]);
- hdr_ptr += 4;
- count_flag = AV_RB16(&trak->stdata[hdr_ptr]);
- hdr_ptr += 2;
- end = AV_RB16(&trak->stdata[hdr_ptr]);
- hdr_ptr += 2;
- palette_map = (unsigned char *)sh->bih + 40;
- mp_msg(MSGT_DEMUX, MSGL_V, "Allocated %d entries for palette\n",
- palette_count);
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "QT palette: start: %x, end: %x, count flag: %d, flags: %x\n",
- start, end, count_flag, flag);
-
- /* XXX: problems with sample (statunit6.mov) with flag&0x4 set! - alex*/
-
- // load default palette
- if (flag & 0x08)
- {
- if (gray)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "Using default QT grayscale palette\n");
- if (palette_count == 16)
- memcpy(palette_map, qt_default_grayscale_palette_16, 16 * 4);
- else if (palette_count == 256) {
- memcpy(palette_map, qt_default_grayscale_palette_256, 256 * 4);
- if (trak->fourcc == mmioFOURCC('c','v','i','d')) {
- int i;
- // Hack for grayscale CVID, negative palette
- // If you have samples where this is not required contact me (rxt)
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: greyscale cvid with default palette,"
- " enabling negative palette hack.\n");
- for (i = 0; i < 256 * 4; i++)
- palette_map[i] = palette_map[i] ^ 0xff;
- }
- }
- }
- else
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "Using default QT colour palette\n");
- if (palette_count == 4)
- memcpy(palette_map, qt_default_palette_4, 4 * 4);
- else if (palette_count == 16)
- memcpy(palette_map, qt_default_palette_16, 16 * 4);
- else if (palette_count == 256)
- memcpy(palette_map, qt_default_palette_256, 256 * 4);
- }
- }
- // load palette from file
- else
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "Loading palette from file\n");
- for (i = start; i <= end; i++)
- {
- entry = AV_RB16(&trak->stdata[hdr_ptr]);
- hdr_ptr += 2;
- // apparently, if count_flag is set, entry is same as i
- if (count_flag & 0x8000)
- entry = i;
- // only care about top 8 bits of 16-bit R, G, or B value
- if (entry <= palette_count && entry >= 0)
- {
- palette_map[entry * 4 + 2] = trak->stdata[hdr_ptr + 0];
- palette_map[entry * 4 + 1] = trak->stdata[hdr_ptr + 2];
- palette_map[entry * 4 + 0] = trak->stdata[hdr_ptr + 4];
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, "QT palette: added entry: %d of %d (colors: R:%x G:%x B:%x)\n",
- entry, palette_count,
- palette_map[entry * 4 + 2],
- palette_map[entry * 4 + 1],
- palette_map[entry * 4 + 0]);
- }
- else
- mp_msg(MSGT_DEMUX, MSGL_V, "QT palette: skipped entry (out of count): %d of %d\n",
- entry, palette_count);
- hdr_ptr += 6;
- }
- }
- }
- else
- {
- if (trak->fourcc == mmioFOURCC('a','v','c','1')) {
- if (trak->stream_header_len > 0xffffffff - sizeof(*sh->bih)) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "Invalid extradata size %d, skipping\n",trak->stream_header_len);
- trak->stream_header_len = 0;
- }
- sh->bih=calloc(1, sizeof(*sh->bih) + trak->stream_header_len);
- sh->bih->biSize=40 + trak->stream_header_len;
- memcpy(((unsigned char *)sh->bih)+40, trak->stream_header, trak->stream_header_len);
- free (trak->stream_header);
- trak->stream_header_len = 0;
- trak->stream_header = NULL;
- } else {
- sh->bih=calloc(1, sizeof(*sh->bih));
- sh->bih->biSize=40;
- }
- }
- sh->bih->biWidth=sh->disp_w;
- sh->bih->biHeight=sh->disp_h;
- sh->bih->biPlanes=0;
- sh->bih->biBitCount=depth;
- sh->bih->biCompression=trak->fourcc;
- sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "Image size: %d x %d (%d bpp)\n",sh->disp_w,sh->disp_h,sh->bih->biBitCount);
- if(trak->tkdata_len>81)
- mp_msg(MSGT_DEMUX, MSGL_V, "Display size: %d x %d\n",
- trak->tkdata[77]|(trak->tkdata[76]<<8),
- trak->tkdata[81]|(trak->tkdata[80]<<8));
- mp_msg(MSGT_DEMUX, MSGL_V, "Fourcc: %.4s Codec: '%.*s'\n",(char *)&trak->fourcc,trak->stdata[42]&31,trak->stdata+43);
-
-// if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){
-// // (auto)selected video track:
-// demuxer->video->id=priv->track_db;
-// demuxer->video->sh=sh; sh->ds=demuxer->video;
-// }
- return 1;
-}
-
-static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak){
- mov_priv_t* priv=demuxer->priv;
-// printf("lschunks (level=%d,endpos=%x)\n", level, endpos);
- while(1){
- off_t pos;
- off_t len;
- unsigned int id;
- //
- pos=stream_tell(demuxer->stream);
-// printf("stream_tell==%d\n",pos);
- if(pos>=endpos) return; // END
- len=stream_read_dword(demuxer->stream);
-// printf("len==%d\n",len);
- if(len<8) return; // error
- len-=8;
- id=stream_read_dword(demuxer->stream);
- //
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"lschunks %.4s %d\n",(char *)&id,(int)len);
- //
- if(trak){
- if (lschunks_intrak(demuxer, level, id, pos, len, trak) < 0)
- return;
- } else { /* not in track */
- switch(id) {
- case MOV_FOURCC('m','v','h','d'): {
- int version = stream_read_char(demuxer->stream);
- stream_skip(demuxer->stream, (version == 1) ? 19 : 11);
- priv->timescale=stream_read_dword(demuxer->stream);
- if (version == 1)
- priv->duration=stream_read_qword(demuxer->stream);
- else
- priv->duration=stream_read_dword(demuxer->stream);
- mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sMovie header (%d bytes): tscale=%d dur=%d\n",level,"",(int)len,
- (int)priv->timescale,(int)priv->duration);
- break;
- }
- case MOV_FOURCC('t','r','a','k'): {
-// if(trak) printf("MOV: Warning! trak in trak?\n");
- if(priv->track_db>=MOV_MAX_TRACKS){
- mp_tmsg(MSGT_DEMUX,MSGL_WARN,"MOV: WARNING: too many tracks");
- return;
- }
- if(!priv->track_db) mp_msg(MSGT_DEMUX, MSGL_V, "--------------\n");
- trak=calloc(1, sizeof(mov_track_t));
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Track #%d:\n",priv->track_db);
- trak->id=priv->track_db;
- priv->tracks[priv->track_db]=trak;
- lschunks(demuxer,level+1,pos+len,trak);
- mov_build_index(trak,priv->timescale);
- switch(trak->type){
- case MOV_TRAK_AUDIO: {
- sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);
- mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "mov", priv->track_db);
- gen_sh_audio(sh, trak, priv->timescale);
- break;
- }
- case MOV_TRAK_VIDEO: {
- sh_video_t* sh=new_sh_video(demuxer,priv->track_db);
- mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Video stream found, -vid %d\n", "mov", priv->track_db);
- gen_sh_video(sh, trak, priv->timescale);
- break;
- }
- case MOV_TRAK_GENERIC:
- if (trak->fourcc == mmioFOURCC('m','p','4','s') ||
- trak->fourcc == mmioFOURCC('t','x','3','g') ||
- trak->fourcc == mmioFOURCC('t','e','x','t')) {
- sh_sub_t *sh = new_sh_sub(demuxer, priv->track_db);
- mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Subtitle stream found, -sid %d\n", "mov", priv->track_db);
- if (trak->fourcc == mmioFOURCC('m','p','4','s'))
- init_vobsub(sh, trak);
- else {
- sh->type = 'm';
- sub_utf8 = 1;
- }
- } else
- mp_msg(MSGT_DEMUX, MSGL_V, "Generic track - not completely understood! (id: %d)\n",
- trak->id);
- /* XXX: Also this contains the FLASH data */
-
-#if 0
- {
- int pos = stream_tell(demuxer->stream);
- int i;
- int fd;
- char name[20];
-
- for (i=0; i<trak->samples_size; i++)
- {
- char buf[trak->samples[i].size];
- stream_seek(demuxer->stream, trak->samples[i].pos);
- snprintf((char *)&name[0], 20, "samp%d", i);
- fd = open((char *)&name[0], O_CREAT|O_WRONLY);
- stream_read(demuxer->stream, &buf[0], trak->samples[i].size);
- write(fd, &buf[0], trak->samples[i].size);
- close(fd);
- }
- for (i=0; i<trak->chunks_size; i++)
- {
- char buf[trak->length];
- stream_seek(demuxer->stream, trak->chunks[i].pos);
- snprintf((char *)&name[0], 20, "chunk%d", i);
- fd = open((char *)&name[0], O_CREAT|O_WRONLY);
- stream_read(demuxer->stream, &buf[0], trak->length);
- write(fd, &buf[0], trak->length);
- close(fd);
- }
- if (trak->samplesize > 0)
- {
- char *buf;
-
- buf = malloc(trak->samplesize);
- stream_seek(demuxer->stream, trak->chunks[0].pos);
- snprintf((char *)&name[0], 20, "trak%d", trak->id);
- fd = open((char *)&name[0], O_CREAT|O_WRONLY);
- stream_read(demuxer->stream, buf, trak->samplesize);
- write(fd, buf, trak->samplesize);
- close(fd);
- }
- stream_seek(demuxer->stream, pos);
- }
-#endif
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_V, "Unknown track type found (type: %d)\n", trak->type);
- break;
- }
- mp_msg(MSGT_DEMUX, MSGL_V, "--------------\n");
- priv->track_db++;
- trak=NULL;
- break;
- }
-#if !CONFIG_ZLIB
- case MOV_FOURCC('c','m','o','v'): {
- mp_tmsg(MSGT_DEMUX,MSGL_ERR,"MOV: Compressed headers support requires ZLIB!\n");
- return;
- }
-#else
- case MOV_FOURCC('m','o','o','v'):
- case MOV_FOURCC('c','m','o','v'): {
-// mp_tmsg(MSGT_DEMUX,MSGL_ERR,"MOV: Compressed headers support requires ZLIB!\n");
- lschunks(demuxer,level+1,pos+len,NULL);
- break;
- }
- case MOV_FOURCC('d','c','o','m'): {
-// int temp=stream_read_dword(demuxer->stream);
- unsigned int algo=be2me_32(stream_read_dword(demuxer->stream));
- mp_msg(MSGT_DEMUX, MSGL_V, "Compressed header uses %.4s algo!\n",(char *)&algo);
- break;
- }
- case MOV_FOURCC('c','m','v','d'): {
-// int temp=stream_read_dword(demuxer->stream);
- unsigned int moov_sz=stream_read_dword(demuxer->stream);
- unsigned int cmov_sz=len-4;
- unsigned char* cmov_buf;
- unsigned char* moov_buf;
- int zret;
- z_stream zstrm;
- stream_t* backup;
-
- if (moov_sz > UINT_MAX - 16) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid cmvd atom size %d\n", moov_sz);
- break;
- }
- cmov_buf=malloc(cmov_sz);
- moov_buf=malloc(moov_sz+16);
- mp_msg(MSGT_DEMUX, MSGL_V, "Compressed header size: %d / %d\n",cmov_sz,moov_sz);
-
- stream_read(demuxer->stream,cmov_buf,cmov_sz);
-
- zstrm.zalloc = (alloc_func)0;
- zstrm.zfree = (free_func)0;
- zstrm.opaque = (voidpf)0;
- zstrm.next_in = cmov_buf;
- zstrm.avail_in = cmov_sz;
- zstrm.next_out = moov_buf;
- zstrm.avail_out = moov_sz;
-
- zret = inflateInit(&zstrm);
- if (zret != Z_OK)
- { mp_msg(MSGT_DEMUX, MSGL_ERR, "QT cmov: inflateInit err %d\n",zret);
- return;
- }
- zret = inflate(&zstrm, Z_NO_FLUSH);
- if ((zret != Z_OK) && (zret != Z_STREAM_END))
- { mp_msg(MSGT_DEMUX, MSGL_ERR, "QT cmov inflate: ERR %d\n",zret);
- return;
- }
-#if 0
- else {
- FILE *DecOut;
- DecOut = fopen("Out.bin", "w");
- fwrite(moov_buf, 1, moov_sz, DecOut);
- fclose(DecOut);
- }
-#endif
- if(moov_sz != zstrm.total_out)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Warning! moov size differs cmov: %d zlib: %ld\n",moov_sz,zstrm.total_out);
- zret = inflateEnd(&zstrm);
-
- backup=demuxer->stream;
- demuxer->stream=new_memory_stream(moov_buf,moov_sz);
- stream_skip(demuxer->stream,8);
- lschunks(demuxer,level+1,moov_sz,NULL); // parse uncompr. 'moov'
- //free_stream(demuxer->stream);
- demuxer->stream=backup;
- free(cmov_buf);
- free(moov_buf);
- break;
- }
-#endif
- case MOV_FOURCC('u','d','t','a'):
- {
- unsigned int udta_id;
- off_t udta_len;
- off_t udta_size = len;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "mov: user data record found\n");
- mp_msg(MSGT_DEMUX, MSGL_V, "Quicktime Clip Info:\n");
-
- while((len > 8) && (udta_size > 8))
- {
- udta_len = stream_read_dword(demuxer->stream);
- udta_id = stream_read_dword(demuxer->stream);
- udta_size -= 8;
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "udta_id: %.4s (len: %"PRId64")\n", (char *)&udta_id, (int64_t)udta_len);
- switch (udta_id)
- {
- case MOV_FOURCC(0xa9,'c','p','y'):
- case MOV_FOURCC(0xa9,'d','a','y'):
- case MOV_FOURCC(0xa9,'d','i','r'):
- /* 0xa9,'e','d','1' - '9' : edit timestamps */
- case MOV_FOURCC(0xa9,'f','m','t'):
- case MOV_FOURCC(0xa9,'i','n','f'):
- case MOV_FOURCC(0xa9,'p','r','d'):
- case MOV_FOURCC(0xa9,'p','r','f'):
- case MOV_FOURCC(0xa9,'r','e','q'):
- case MOV_FOURCC(0xa9,'s','r','c'):
- case MOV_FOURCC('n','a','m','e'):
- case MOV_FOURCC(0xa9,'n','a','m'):
- case MOV_FOURCC(0xa9,'A','R','T'):
- case MOV_FOURCC(0xa9,'c','m','t'):
- case MOV_FOURCC(0xa9,'a','u','t'):
- case MOV_FOURCC(0xa9,'s','w','r'):
- {
- off_t text_len = stream_read_word(demuxer->stream);
- char text[text_len+2+1];
- stream_read(demuxer->stream, (char *)&text, text_len+2);
- text[text_len+2] = 0x0;
- switch(udta_id)
- {
- case MOV_FOURCC(0xa9,'a','u','t'):
- demux_info_add(demuxer, "author", &text[2]);
- mp_msg(MSGT_DEMUX, MSGL_V, " Author: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'c','p','y'):
- demux_info_add(demuxer, "copyright", &text[2]);
- mp_msg(MSGT_DEMUX, MSGL_V, " Copyright: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'i','n','f'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Info: %s\n", &text[2]);
- break;
- case MOV_FOURCC('n','a','m','e'):
- case MOV_FOURCC(0xa9,'n','a','m'):
- demux_info_add(demuxer, "title", &text[2]);
- mp_msg(MSGT_DEMUX, MSGL_V, " Name: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'A','R','T'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Artist: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'d','i','r'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Director: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'c','m','t'):
- demux_info_add(demuxer, "comments", &text[2]);
- mp_msg(MSGT_DEMUX, MSGL_V, " Comment: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'r','e','q'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Requirements: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'s','w','r'):
- demux_info_add(demuxer, "encoder", &text[2]);
- mp_msg(MSGT_DEMUX, MSGL_V, " Software: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'d','a','y'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Creation timestamp: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'f','m','t'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Format: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'p','r','d'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Producer: %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'p','r','f'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Performer(s): %s\n", &text[2]);
- break;
- case MOV_FOURCC(0xa9,'s','r','c'):
- mp_msg(MSGT_DEMUX, MSGL_V, " Source providers: %s\n", &text[2]);
- break;
- }
- udta_size -= 4+text_len;
- break;
- }
- /* some other shits: WLOC - window location,
- LOOP - looping style,
- SelO - play only selected frames
- AllF - play all frames
- */
- case MOV_FOURCC('W','L','O','C'):
- case MOV_FOURCC('L','O','O','P'):
- case MOV_FOURCC('S','e','l','O'):
- case MOV_FOURCC('A','l','l','F'):
- default:
- {
- if( udta_len>udta_size)
- udta_len=udta_size;
- {
- stream_skip(demuxer->stream, udta_len-4-4);
- udta_size -= udta_len;
- }
- }
- }
- }
- break;
- } /* eof udta */
- default:
- id = be2me_32(id);
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: unknown chunk: %.4s %d\n",(char *)&id,(int)len);
- } /* endof switch */
- } /* endof else */
-
- pos+=len+8;
- if(pos>=endpos) break;
- if(!stream_seek(demuxer->stream,pos)) break;
- }
-}
-
-static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id,
- off_t pos, off_t len, mov_track_t* trak)
-{
- switch(id) {
- case MOV_FOURCC('m','d','a','t'): {
- mp_msg(MSGT_DEMUX,MSGL_WARN,"Hmm, strange MOV, parsing mdat in lschunks?\n");
- return -1;
- }
- case MOV_FOURCC('f','r','e','e'):
- case MOV_FOURCC('u','d','t','a'):
- /* here not supported :p */
- break;
- case MOV_FOURCC('t','k','h','d'): {
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sTrack header!\n", level, "");
- // read codec data
- trak->tkdata_len = len;
- trak->tkdata = malloc(trak->tkdata_len);
- stream_read(demuxer->stream, trak->tkdata, trak->tkdata_len);
-/*
-0 1 Version
-1 3 Flags
-4 4 Creation time
-8 4 Modification time
-12 4 Track ID
-16 4 Reserved
-20 4 Duration
-24 8 Reserved
-32 2 Layer
-34 2 Alternate group
-36 2 Volume
-38 2 Reserved
-40 36 Matrix structure
-76 4 Track width
-80 4 Track height
-*/
- mp_msg(MSGT_DEMUX, MSGL_V,
- "tkhd len=%d ver=%d flags=0x%X id=%d dur=%d lay=%d vol=%d\n",
- trak->tkdata_len, trak->tkdata[0], trak->tkdata[1],
- char2int(trak->tkdata, 12), // id
- char2int(trak->tkdata, 20), // duration
- char2short(trak->tkdata, 32), // layer
- char2short(trak->tkdata, 36)); // volume
- break;
- }
- case MOV_FOURCC('m','d','h','d'): {
- int version = stream_read_char(demuxer->stream);
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sMedia header!\n", level, "");
- stream_skip(demuxer->stream, (version == 1) ? 19 : 11);
- // read timescale
- trak->timescale = stream_read_dword(demuxer->stream);
- // read length
- if (version == 1)
- trak->length = stream_read_qword(demuxer->stream);
- else
- trak->length = stream_read_dword(demuxer->stream);
- break;
- }
- case MOV_FOURCC('h','d','l','r'): {
- av_unused unsigned int tmp = stream_read_dword(demuxer->stream);
- unsigned int type = stream_read_dword_le(demuxer->stream);
- unsigned int subtype = stream_read_dword_le(demuxer->stream);
- unsigned int manufact = stream_read_dword_le(demuxer->stream);
- av_unused unsigned int comp_flags = stream_read_dword(demuxer->stream);
- av_unused unsigned int comp_mask = stream_read_dword(demuxer->stream);
- int len = stream_read_char(demuxer->stream);
- char* str = malloc(len + 1);
- stream_read(demuxer->stream, str, len);
- str[len] = 0;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sHandler header: %.4s/%.4s (%.4s) %s\n", level, "",
- (char *)&type, (char *)&subtype, (char *)&manufact, str);
- free(str);
- switch(bswap_32(type)) {
- case MOV_FOURCC('m','h','l','r'):
- trak->media_handler = bswap_32(subtype);
- break;
- case MOV_FOURCC('d','h','l','r'):
- trak->data_handler = bswap_32(subtype);
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: unknown handler class: 0x%X (%.4s)\n",
- bswap_32(type), (char *)&type);
- }
- break;
- }
- case MOV_FOURCC('v','m','h','d'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sVideo header!\n", level, "");
- trak->type = MOV_TRAK_VIDEO;
- // read video data
- break;
- }
- case MOV_FOURCC('s','m','h','d'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sSound header!\n", level, "");
- trak->type = MOV_TRAK_AUDIO;
- // read audio data
- break;
- }
- case MOV_FOURCC('g','m','h','d'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sGeneric header!\n", level, "");
- trak->type = MOV_TRAK_GENERIC;
- break;
- }
- case MOV_FOURCC('n','m','h','d'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sGeneric header!\n", level, "");
- trak->type = MOV_TRAK_GENERIC;
- break;
- }
- case MOV_FOURCC('s','t','s','d'): {
- int i = stream_read_dword(demuxer->stream); // temp!
- int count = stream_read_dword(demuxer->stream);
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sDescription list! (cnt:%d)\n",
- level, "", count);
- for (i = 0; i < count; i++) {
- off_t pos = stream_tell(demuxer->stream);
- off_t len = stream_read_dword(demuxer->stream);
- unsigned int fourcc = stream_read_dword_le(demuxer->stream);
- /* some files created with Broadcast 2000 (e.g. ilacetest.mov)
- contain raw I420 video but have a yv12 fourcc */
- if (fourcc == mmioFOURCC('y','v','1','2'))
- fourcc = mmioFOURCC('I','4','2','0');
- if (len < 8)
- break; // error
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*s desc #%d: %.4s (%"PRId64" bytes)\n", level, "",
- i, (char *)&fourcc, (int64_t)len - 16);
- if (fourcc != trak->fourcc && i)
- mp_tmsg(MSGT_DEMUX, MSGL_WARN, "MOV: WARNING: Variable FourCC detected!?\n");
-// if(!i)
- {
- trak->fourcc = fourcc;
- // read type specific (audio/video/time/text etc) header
- // NOTE: trak type is not yet known at this point :(((
- trak->stdata_len = len - 8;
- trak->stdata = malloc(trak->stdata_len);
- stream_read(demuxer->stream, trak->stdata, trak->stdata_len);
- }
- if (!stream_seek(demuxer->stream, pos + len))
- break;
- }
- break;
- }
- case MOV_FOURCC('s','t','t','s'): {
- av_unused int temp = stream_read_dword(demuxer->stream);
- int len = stream_read_dword(demuxer->stream);
- int i;
- unsigned int pts = 0;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sSample duration table! (%d blocks)\n", level, "",
- len);
- free(trak->durmap);
- trak->durmap = calloc(len, sizeof(mov_durmap_t));
- trak->durmap_size = trak->durmap ? len : 0;
- for (i = 0; i < trak->durmap_size; i++) {
- trak->durmap[i].num = stream_read_dword(demuxer->stream);
- trak->durmap[i].dur = stream_read_dword(demuxer->stream);
- pts += trak->durmap[i].num * trak->durmap[i].dur;
- }
- if (trak->length != pts)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Warning! pts=%d length=%d\n",
- pts, trak->length);
- break;
- }
- case MOV_FOURCC('s','t','s','c'): {
- int temp = stream_read_dword(demuxer->stream);
- int len = stream_read_dword(demuxer->stream);
- int ver = (temp << 24);
- int flags = (temp << 16) | (temp << 8) | temp;
- int i;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sSample->Chunk mapping table! (%d blocks) (ver:%d,flags:%d)\n", level, "",
- len, ver, flags);
- // read data:
- free(trak->chunkmap);
- trak->chunkmap = calloc(len, sizeof(mov_chunkmap_t));
- trak->chunkmap_size = trak->chunkmap ? len : 0;
- for (i = 0; i < trak->chunkmap_size; i++) {
- trak->chunkmap[i].first = stream_read_dword(demuxer->stream) - 1;
- trak->chunkmap[i].spc = stream_read_dword(demuxer->stream);
- trak->chunkmap[i].sdid = stream_read_dword(demuxer->stream);
- }
- break;
- }
- case MOV_FOURCC('s','t','s','z'): {
- int temp = stream_read_dword(demuxer->stream);
- int ss=stream_read_dword(demuxer->stream);
- int ver = (temp << 24);
- int flags = (temp << 16) | (temp << 8) | temp;
- int entries = stream_read_dword(demuxer->stream);
- int i;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sSample size table! (entries=%d ss=%d) (ver:%d,flags:%d)\n", level, "",
- entries, ss, ver, flags);
- trak->samplesize = ss;
- if (!ss) {
- // variable samplesize
- free(trak->samples);
- trak->samples = calloc(entries, sizeof(mov_sample_t));
- trak->samples_size = trak->samples ? entries : 0;
- for (i = 0; i < trak->samples_size; i++)
- trak->samples[i].size = stream_read_dword(demuxer->stream);
- }
- break;
- }
- case MOV_FOURCC('s','t','c','o'): {
- av_unused int temp = stream_read_dword(demuxer->stream);
- int len = stream_read_dword(demuxer->stream);
- int i;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sChunk offset table! (%d chunks)\n", level, "",
- len);
- // extend array if needed:
- if (len > trak->chunks_size) {
- free(trak->chunks);
- trak->chunks = calloc(len, sizeof(mov_chunk_t));
- trak->chunks_size = trak->chunks ? len : 0;
- }
- // read elements:
- for(i = 0; i < trak->chunks_size; i++)
- trak->chunks[i].pos = stream_read_dword(demuxer->stream);
- break;
- }
- case MOV_FOURCC('c','o','6','4'): {
- av_unused int temp = stream_read_dword(demuxer->stream);
- int len = stream_read_dword(demuxer->stream);
- int i;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*s64bit chunk offset table! (%d chunks)\n", level, "",
- len);
- // extend array if needed:
- if (len > trak->chunks_size) {
- free(trak->chunks);
- trak->chunks = calloc(len, sizeof(mov_chunk_t));
- trak->chunks_size = trak->chunks ? len : 0;
- }
- // read elements:
- for (i = 0; i < trak->chunks_size; i++) {
-#ifndef _LARGEFILE_SOURCE
- if (stream_read_dword(demuxer->stream) != 0)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Chunk %d has got 64bit address, but you've MPlayer compiled without LARGEFILE support!\n", i);
- trak->chunks[i].pos = stream_read_dword(demuxer->stream);
-#else
- trak->chunks[i].pos = stream_read_qword(demuxer->stream);
-#endif
- }
- break;
- }
- case MOV_FOURCC('s','t','s','s'): {
- int temp = stream_read_dword(demuxer->stream);
- int entries = stream_read_dword(demuxer->stream);
- int ver = (temp << 24);
- int flags = (temp << 16) | (temp<<8) | temp;
- int i;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sSyncing samples (keyframes) table! (%d entries) (ver:%d,flags:%d)\n", level, "",
- entries, ver, flags);
- free(trak->keyframes);
- trak->keyframes = calloc(entries, sizeof(unsigned int));
- trak->keyframes_size = trak->keyframes ? entries : 0;
- for (i = 0; i < trak->keyframes_size; i++)
- trak->keyframes[i] = stream_read_dword(demuxer->stream) - 1;
- break;
- }
- case MOV_FOURCC('m','d','i','a'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sMedia stream!\n", level, "");
- lschunks(demuxer, level + 1, pos + len, trak);
- break;
- }
- case MOV_FOURCC('m','i','n','f'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sMedia info!\n", level, "");
- lschunks(demuxer, level + 1 ,pos + len, trak);
- break;
- }
- case MOV_FOURCC('s','t','b','l'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sSample info!\n", level, "");
- lschunks(demuxer, level + 1, pos + len, trak);
- break;
- }
- case MOV_FOURCC('e','d','t','s'): {
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sEdit atom!\n", level, "");
- lschunks(demuxer, level + 1, pos + len, trak);
- break;
- }
- case MOV_FOURCC('e','l','s','t'): {
- int temp = stream_read_dword(demuxer->stream);
- int entries = stream_read_dword(demuxer->stream);
- int ver = (temp << 24);
- int flags = (temp << 16) | (temp << 8) | temp;
- int i;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*sEdit list table (%d entries) (ver:%d,flags:%d)\n", level, "",
- entries, ver, flags);
-#if 1
- free(trak->editlist);
- trak->editlist = calloc(entries, sizeof(mov_editlist_t));
- trak->editlist_size = trak->editlist ? entries : 0;
- for (i = 0; i < trak->editlist_size; i++) {
- int dur = stream_read_dword(demuxer->stream);
- int mt = stream_read_dword(demuxer->stream);
- int mr = stream_read_dword(demuxer->stream); // 16.16fp
- trak->editlist[i].dur = dur;
- trak->editlist[i].pos = mt;
- trak->editlist[i].speed = mr;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "MOV: %*s entry#%d: duration: %d start time: %d speed: %3.1fx\n", level, "",
- i, dur, mt, (float)mr/65536.0f);
- }
-#endif
- break;
- }
- case MOV_FOURCC('c','o','d','e'): {
- /* XXX: Implement atom 'code' for FLASH support */
- break;
- }
- default:
- id = be2me_32(id);
- mp_msg(MSGT_DEMUX,MSGL_V,"MOV: unknown chunk: %.4s %d\n",(char *)&id,(int)len);
- break;
- }//switch(id)
- return 0;
-}
-
-static demuxer_t* mov_read_header(demuxer_t* demuxer){
- struct MPOpts *opts = demuxer->opts;
- mov_priv_t* priv=demuxer->priv;
- int t_no;
- int best_a_id=-1, best_a_len=0;
- int best_v_id=-1, best_v_len=0;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG3, "mov_read_header!\n");
-
- // Parse header:
- stream_reset(demuxer->stream);
- if(!stream_seek(demuxer->stream,priv->moov_start))
- {
- mp_msg(MSGT_DEMUX,MSGL_ERR,"MOV: Cannot seek to the beginning of the Movie header (0x%"PRIx64")\n",
- (int64_t)priv->moov_start);
- return 0;
- }
- lschunks(demuxer, 0, priv->moov_end, NULL);
- // just in case we have hit eof while parsing...
- demuxer->stream->eof = 0;
-// mp_msg(MSGT_DEMUX, MSGL_INFO, "--------------\n");
-
- // find the best (longest) streams:
- for(t_no=0;t_no<priv->track_db;t_no++){
- mov_track_t* trak=priv->tracks[t_no];
- int len=(trak->samplesize) ? trak->chunks_size : trak->samples_size;
- if(demuxer->a_streams[t_no]){ // need audio
- if(len>best_a_len){ best_a_len=len; best_a_id=t_no; }
- }
- if(demuxer->v_streams[t_no]){ // need video
- if(len>best_v_len){ best_v_len=len; best_v_id=t_no; }
- }
- }
- mp_msg(MSGT_DEMUX, MSGL_V, "MOV: longest streams: A: #%d (%d samples) V: #%d (%d samples)\n",
- best_a_id,best_a_len,best_v_id,best_v_len);
- if(demuxer->audio->id==-1 && best_a_id>=0) demuxer->audio->id=best_a_id;
- if(demuxer->video->id==-1 && best_v_id>=0) demuxer->video->id=best_v_id;
-
- // setup sh pointers:
- if(demuxer->audio->id>=0){
- sh_audio_t* sh=demuxer->a_streams[demuxer->audio->id];
- if(sh){
- demuxer->audio->sh=sh; sh->ds=demuxer->audio;
- } else {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: selected audio stream (%d) does not exist\n",demuxer->audio->id);
- demuxer->audio->id=-2;
- }
- }
- if(demuxer->video->id>=0){
- sh_video_t* sh=demuxer->v_streams[demuxer->video->id];
- if(sh){
- demuxer->video->sh=sh; sh->ds=demuxer->video;
- } else {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: selected video stream (%d) does not exist\n",demuxer->video->id);
- demuxer->video->id=-2;
- }
- }
- if(demuxer->sub->id>=0){
- sh_sub_t* sh=demuxer->s_streams[demuxer->sub->id];
- if(sh){
- demuxer->sub->sh=sh;
- } else {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: selected subtitle stream (%d) does not exist\n",demuxer->sub->id);
- demuxer->sub->id=-2;
- }
- }
-
- if(demuxer->video->id<0 && demuxer->audio->id<0) {
- /* No AV streams found. Try to find an MPEG stream. */
- for(t_no=0;t_no<priv->track_db;t_no++){
- mov_track_t* trak=priv->tracks[t_no];
- if(trak->media_handler == MOV_FOURCC('M','P','E','G')) {
- stream_t *s;
- demuxer_t *od;
-
- demuxer->video->id = t_no;
- s = new_ds_stream(demuxer->video);
- od = demux_open(opts, s, DEMUXER_TYPE_MPEG_PS, -1, -1, -1, NULL);
- if(od) return new_demuxers_demuxer(od, od, od);
- demuxer->video->id = -2; //new linked demuxer couldn't be allocated
- break;
- }
- }
- }
-
-#if 0
- if( mp_msg_test(MSGT_DEMUX,MSGL_DBG3) ){
- for(t_no=0;t_no<priv->track_db;t_no++){
- mov_track_t* trak=priv->tracks[t_no];
- if(trak->type==MOV_TRAK_GENERIC){
- int i;
- int fd;
- char name[20];
- mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Track #%d: Extracting %d data chunks to files\n",t_no,trak->samples_size);
- for (i=0; i<trak->samples_size; i++)
- {
- int len=trak->samples[i].size;
- char buf[len];
- stream_seek(demuxer->stream, trak->samples[i].pos);
- snprintf(name, 20, "t%02d-s%03d.%s", t_no,i,
- (trak->media_handler==MOV_FOURCC('f','l','s','h')) ?
- "swf":"dump");
- fd = open(name, O_CREAT|O_WRONLY);
-// { int j;
-// for(j=0;j<trak->stdata_len-3; j++)
-// printf("stdata[%d]=0x%X ize=0x%X\n",j,char2int(trak->stdata,j),MOV_FOURCC('z','l','i','b'));
-// }
- if( //trak->media_handler==MOV_FOURCC('s','p','r','t') &&
- trak->stdata_len>=16 &&
- char2int(trak->stdata,12)==MOV_FOURCC('z','l','i','b')
- ){
- int newlen=stream_read_dword(demuxer->stream);
-#if CONFIG_ZLIB
- // unzip:
- z_stream zstrm;
- int zret;
- char buf2[newlen];
-
- len-=4;
- stream_read(demuxer->stream, buf, len);
-
- zstrm.zalloc = (alloc_func)0;
- zstrm.zfree = (free_func)0;
- zstrm.opaque = (voidpf)0;
- zstrm.next_in = buf;
- zstrm.avail_in = len;
- zstrm.next_out = buf2;
- zstrm.avail_out = newlen;
-
- zret = inflateInit(&zstrm);
- zret = inflate(&zstrm, Z_NO_FLUSH);
- if(newlen != zstrm.total_out)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Warning! unzipped frame size differs hdr: %d zlib: %ld\n",newlen,zstrm.total_out);
-
- write(fd, buf2, newlen);
- } else {
-#else
- len-=4;
- mp_msg(MSGT_DEMUX, MSGL_INFO, "******* ZLIB COMPRESSED SAMPLE!!!!! (%d->%d bytes) *******\n",len,newlen);
- }
- {
-#endif
- stream_read(demuxer->stream, buf, len);
- write(fd, buf, len);
- }
- close(fd);
- }
- }
- }
- }
- demuxer->stream->eof = 0;
-#endif
-
- return demuxer;
-}
-
-/**
- * \brief return the mov track that belongs to a demuxer stream
- * \param ds the demuxer stream, may be NULL
- * \return the mov track info structure belonging to the stream,
- * NULL if not found
- */
-static mov_track_t *stream_track(mov_priv_t *priv, demux_stream_t *ds) {
- if (ds && (ds->id >= 0) && (ds->id < priv->track_db))
- return priv->tracks[ds->id];
- return NULL;
-}
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_mov_fill_buffer(demuxer_t *demuxer,demux_stream_t* ds){
- mov_priv_t* priv=demuxer->priv;
- mov_track_t* trak=NULL;
- float pts;
- int x;
- off_t pos;
-
- if (ds->eof) return 0;
- trak = stream_track(priv, ds);
- if (!trak) return 0;
-
-if(trak->samplesize){
- // read chunk:
- if(trak->pos>=trak->chunks_size) return 0; // EOF
- stream_seek(demuxer->stream,trak->chunks[trak->pos].pos);
- pts=(float)(trak->chunks[trak->pos].sample*trak->duration)/(float)trak->timescale;
- if(trak->samplesize!=1)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "WARNING! Samplesize(%d) != 1\n",
- trak->samplesize);
- if((trak->fourcc != MOV_FOURCC('t','w','o','s')) && (trak->fourcc != MOV_FOURCC('s','o','w','t')))
- x=trak->chunks[trak->pos].size*trak->samplesize;
- else
- x=trak->chunks[trak->pos].size;
- }
- else
- x=trak->chunks[trak->pos].size;
-// printf("X = %d\n", x);
- /* the following stuff is audio related */
- if (trak->type == MOV_TRAK_AUDIO){
- if(trak->stdata_len>=44 && trak->stdata[9]>=1 && char2int(trak->stdata,28)>0){
- // stsd version 1 - we have audio compression ratio info:
- x/=char2int(trak->stdata,28); // samples/packet
-// x*=char2int(trak->stdata,32); // bytes/packet
- x*=char2int(trak->stdata,36); // bytes/frame
- } else {
- if(ds->ss_div && ds->ss_mul){
- // workaround for buggy files like 7up-high-traffic-areas.mov,
- // with missing stsd v1 header containing compression rate
- x/=ds->ss_div; x*=ds->ss_mul; // compression ratio fix ! HACK !
- } else {
- x*=trak->nchannels;
- x*=trak->samplebytes;
- }
- }
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Audio sample %d bytes pts %5.3f\n",trak->chunks[trak->pos].size*trak->samplesize,pts);
- } /* MOV_TRAK_AUDIO */
- pos=trak->chunks[trak->pos].pos;
-} else {
- int frame=trak->pos;
- // editlist support:
- if(trak->type == MOV_TRAK_VIDEO && trak->editlist_size>=1){
- // find the right editlist entry:
- if(frame<trak->editlist[trak->editlist_pos].start_frame)
- trak->editlist_pos=0;
- while(trak->editlist_pos<trak->editlist_size-1 &&
- frame>=trak->editlist[trak->editlist_pos+1].start_frame)
- ++trak->editlist_pos;
- if(frame>=trak->editlist[trak->editlist_pos].start_frame+
- trak->editlist[trak->editlist_pos].frames) return 0; // EOF
- // calc real frame index:
- frame-=trak->editlist[trak->editlist_pos].start_frame;
- frame+=trak->editlist[trak->editlist_pos].start_sample;
- // calc pts:
- pts=(float)(trak->samples[frame].pts+
- trak->editlist[trak->editlist_pos].pts_offset)/(float)trak->timescale;
- } else {
- if(frame>=trak->samples_size) return 0; // EOF
- pts=(float)trak->samples[frame].pts/(float)trak->timescale;
- }
- // read sample:
- stream_seek(demuxer->stream,trak->samples[frame].pos);
- x=trak->samples[frame].size;
- pos=trak->samples[frame].pos;
-}
-if(trak->pos==0 && trak->stream_header_len>0){
- // we have to append the stream header...
- demux_packet_t* dp=new_demux_packet(x+trak->stream_header_len);
- memcpy(dp->buffer,trak->stream_header,trak->stream_header_len);
- stream_read(demuxer->stream,dp->buffer+trak->stream_header_len,x);
- free(trak->stream_header);
- trak->stream_header = NULL;
- trak->stream_header_len = 0;
- dp->pts=pts;
- dp->pos=pos; // FIXME?
- ds_add_packet(ds,dp);
-} else
- ds_read_packet(ds,demuxer->stream,x,pts,pos,0);
-
- ++trak->pos;
-
- trak = NULL;
- if (demuxer->sub->id >= 0 && demuxer->sub->id < priv->track_db)
- trak = priv->tracks[demuxer->sub->id];
- if (trak) {
- int samplenr = 0;
- while (samplenr < trak->samples_size) {
- double subpts = (double)trak->samples[samplenr].pts / (double)trak->timescale;
- if (subpts >= pts) break;
- samplenr++;
- }
- samplenr--;
- if (samplenr < 0)
- vo_sub = NULL;
- else if (samplenr != priv->current_sub) {
- off_t pos = trak->samples[samplenr].pos;
- int len = trak->samples[samplenr].size;
- double subpts = (double)trak->samples[samplenr].pts / (double)trak->timescale;
- stream_seek(demuxer->stream, pos);
- ds_read_packet(demuxer->sub, demuxer->stream, len, subpts, pos, 0);
- priv->current_sub = samplenr;
- }
- }
-
- return 1;
-
-}
-
-static float mov_seek_track(mov_track_t* trak,float pts,int flags){
-
-// printf("MOV track seek called %5.3f \n",pts);
- if(flags&SEEK_FACTOR) pts*=trak->length; else pts*=(float)trak->timescale;
-
-if(trak->samplesize){
- int sample=pts/trak->duration;
-// printf("MOV track seek - chunk: %d (pts: %5.3f dur=%d) \n",sample,pts,trak->duration);
- if(!(flags&SEEK_ABSOLUTE)) sample+=trak->chunks[trak->pos].sample; // relative
- trak->pos=0;
- while(trak->pos<trak->chunks_size && trak->chunks[trak->pos].sample<sample) ++trak->pos;
- if (trak->pos == trak->chunks_size) return -1;
- pts=(float)(trak->chunks[trak->pos].sample*trak->duration)/(float)trak->timescale;
-} else {
- unsigned int ipts;
- if(!(flags&SEEK_ABSOLUTE)) pts+=trak->samples[trak->pos].pts;
- if(pts<0) pts=0;
- ipts=pts;
- //printf("MOV track seek - sample: %d \n",ipts);
- for(trak->pos=0;trak->pos<trak->samples_size;++trak->pos){
- if(trak->samples[trak->pos].pts>=ipts) break; // found it!
- }
- if (trak->pos == trak->samples_size) return -1;
- if(trak->keyframes_size){
- // find nearest keyframe
- int i;
- for(i=0;i<trak->keyframes_size;i++){
- if(trak->keyframes[i]>=trak->pos) break;
- }
- if (i == trak->keyframes_size) return -1;
- if(i>0 && (trak->keyframes[i]-trak->pos) > (trak->pos-trak->keyframes[i-1]))
- --i;
- trak->pos=trak->keyframes[i];
-// printf("nearest keyframe: %d \n",trak->pos);
- }
- pts=(float)trak->samples[trak->pos].pts/(float)trak->timescale;
-}
-
-// printf("MOV track seek done: %5.3f \n",pts);
-
-return pts;
-}
-
-static void demux_seek_mov(demuxer_t *demuxer,float pts,float audio_delay,int flags){
- mov_priv_t* priv=demuxer->priv;
- demux_stream_t* ds;
- mov_track_t* trak;
-
-// printf("MOV seek called %5.3f flag=%d \n",pts,flags);
-
- ds=demuxer->video;
- trak = stream_track(priv, ds);
- if (trak) {
- //if(flags&2) pts*=(float)trak->length/(float)trak->timescale;
- //if(!(flags&1)) pts+=ds->pts;
- ds->pts=mov_seek_track(trak,pts,flags);
- if (ds->pts < 0) ds->eof = 1;
- else pts = ds->pts;
- flags=1; // absolute seconds
- }
-
- ds=demuxer->audio;
- trak = stream_track(priv, ds);
- if (trak) {
- //if(flags&2) pts*=(float)trak->length/(float)trak->timescale;
- //if(!(flags&1)) pts+=ds->pts;
- ds->pts=mov_seek_track(trak,pts,flags);
- if (ds->pts < 0) ds->eof = 1;
- }
-
-}
-
-static int demux_mov_control(demuxer_t *demuxer, int cmd, void *arg){
- mov_track_t* track;
-
- // try the video track
- track = stream_track(demuxer->priv, demuxer->video);
- if (!track || !track->length)
- // otherwise try to get the info from the audio track
- track = stream_track(demuxer->priv, demuxer->audio);
-
- if (!track || !track->length)
- return DEMUXER_CTRL_DONTKNOW;
-
- switch(cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (!track->timescale)
- return DEMUXER_CTRL_DONTKNOW;
- *((double *)arg) = (double)track->length / track->timescale;
- return DEMUXER_CTRL_OK;
-
- case DEMUXER_CTRL_GET_PERCENT_POS:
- {
- off_t pos = track->pos;
- if (track->durmap_size >= 1)
- pos *= track->durmap[0].dur;
- *((int *)arg) = (int)(100 * pos / track->length);
- return DEMUXER_CTRL_OK;
- }
- }
- return DEMUXER_CTRL_NOTIMPL;
-}
-
-
-const demuxer_desc_t demuxer_desc_mov = {
- "Quicktime/MP4 demuxer",
- "mov",
- "Quicktime/MOV",
- "Arpi, Al3x, Atmos, others",
- "Handles Quicktime, MP4, 3GP",
- DEMUXER_TYPE_MOV,
- 0, // slow autodetect
- mov_check_file,
- demux_mov_fill_buffer,
- mov_read_header,
- demux_close_mov,
- demux_seek_mov,
- demux_mov_control
-};
diff --git a/libmpdemux/demux_mov.h b/libmpdemux/demux_mov.h
deleted file mode 100644
index 8aa515c349..0000000000
--- a/libmpdemux/demux_mov.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_DEMUX_MOV_H
-#define MPLAYER_DEMUX_MOV_H
-
-unsigned int store_ughvlc(unsigned char *s, unsigned int v);
-
-#endif /* MPLAYER_DEMUX_MOV_H */
diff --git a/libmpdemux/demux_mpc.c b/libmpdemux/demux_mpc.c
deleted file mode 100644
index 234eed45da..0000000000
--- a/libmpdemux/demux_mpc.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * demuxer for Musepack v7 bitstream
- * copyright (c) 2005 Reimar Doeffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>
- *
- * This code may be be relicensed under the terms of the GNU LGPL when it
- * becomes part of the FFmpeg project (ffmpeg.org)
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "mp_msg.h"
-#include "libavutil/common.h"
-#include "mpbswap.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-
-#define HDR_SIZE (6 * 4)
-
-typedef struct da_priv {
- float last_pts;
- float pts_per_packet;
- uint32_t dword;
- int pos;
- float length;
-} da_priv_t;
-
-static uint32_t get_bits(da_priv_t* priv, stream_t* s, int bits) {
- uint32_t out = priv->dword;
- uint32_t mask = (1 << bits) - 1;
- priv->pos += bits;
- if (priv->pos < 32) {
- out >>= (32 - priv->pos);
- }
- else {
- stream_read(s, (void *)&priv->dword, 4);
- priv->dword = le2me_32(priv->dword);
- priv->pos -= 32;
- if (priv->pos) {
- out <<= priv->pos;
- out |= priv->dword >> (32 - priv->pos);
- }
- }
- return out & mask;
-}
-
-static int demux_mpc_check(demuxer_t* demuxer) {
- stream_t *s = demuxer->stream;
- uint8_t hdr[HDR_SIZE];
- int i;
-
- if (stream_read(s, hdr, HDR_SIZE) != HDR_SIZE)
- return 0;
- for (i = 0; i < 30000 && !s->eof; i++) {
- if (hdr[0] == 'M' && hdr[1] == 'P' && hdr[2] == '+')
- break;
- memmove(hdr, &hdr[1], HDR_SIZE - 1);
- stream_read(s, &hdr[HDR_SIZE - 1], 1);
- }
-
- if (hdr[0] != 'M' || hdr[1] != 'P' || hdr[2] != '+')
- return 0;
- demuxer->movi_start = stream_tell(s) - HDR_SIZE;
- demuxer->movi_end = s->end_pos;
- demuxer->priv = malloc(HDR_SIZE);
- memcpy(demuxer->priv, hdr, HDR_SIZE);
- return DEMUXER_TYPE_MPC;
-}
-
-static demuxer_t *demux_mpc_open(demuxer_t* demuxer) {
- float seconds = 0;
- stream_t *s = demuxer->stream;
- sh_audio_t* sh_audio;
- da_priv_t* priv = demuxer->priv;
-
- sh_audio = new_sh_audio(demuxer,0);
-
- {
- char *wf = calloc(1, sizeof(WAVEFORMATEX) + HDR_SIZE);
- char *header = &wf[sizeof(WAVEFORMATEX)];
- const int freqs[4] = {44100, 48000, 37800, 32000};
- int frames;
- sh_audio->format = mmioFOURCC('M', 'P', 'C', ' ');
- memcpy(header, priv, HDR_SIZE);
- free(priv);
- frames = header[4] | header[5] << 8 | header[6] << 16 | header[7] << 24;
- sh_audio->wf = (WAVEFORMATEX *)wf;
- sh_audio->wf->wFormatTag = sh_audio->format;
- sh_audio->wf->nChannels = 2;
- sh_audio->wf->nSamplesPerSec = freqs[header[10] & 3];
- sh_audio->wf->nBlockAlign = 32 * 36;
- sh_audio->wf->wBitsPerSample = 16;
- seconds = 1152 * frames / (float)sh_audio->wf->nSamplesPerSec;
- if (demuxer->movi_end > demuxer->movi_start && seconds > 1)
- sh_audio->wf->nAvgBytesPerSec = (demuxer->movi_end - demuxer->movi_start) / seconds;
- else
- sh_audio->wf->nAvgBytesPerSec = 32 * 1024; // dummy to make mencoder not hang
- sh_audio->wf->cbSize = HDR_SIZE;
- demuxer->movi_start = stream_tell(s);
- demuxer->movi_end = s->end_pos;
- }
-
- priv = malloc(sizeof(da_priv_t));
- priv->last_pts = -1;
- priv->pts_per_packet = (32 * 36) / (float)sh_audio->wf->nSamplesPerSec;
- priv->length = seconds;
- priv->dword = 0;
- priv->pos = 32; // empty bit buffer
- get_bits(priv, s, 8); // discard first 8 bits
- demuxer->priv = priv;
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- sh_audio->ds = demuxer->audio;
- sh_audio->samplerate = sh_audio->wf->nSamplesPerSec;
- sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
- sh_audio->audio.dwSampleSize = 0;
- sh_audio->audio.dwScale = 32 * 36;
- sh_audio->audio.dwRate = sh_audio->samplerate;
-
- return demuxer;
-}
-
-static int demux_mpc_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
- int l;
- int bit_len;
- demux_packet_t* dp;
- sh_audio_t* sh_audio = ds->sh;
- da_priv_t* priv = demux->priv;
- stream_t* s = demux->stream;
- sh_audio = ds->sh;
-
- if (s->eof)
- return 0;
-
- bit_len = get_bits(priv, s, 20);
- dp = new_demux_packet((bit_len + 7) / 8);
- for (l = 0; l < (bit_len / 8); l++)
- dp->buffer[l] = get_bits(priv, s, 8);
- bit_len %= 8;
- if (bit_len)
- dp->buffer[l] = get_bits(priv, s, bit_len) << (8 - bit_len);
- if (priv->last_pts < 0)
- priv->last_pts = 0;
- else
- priv->last_pts += priv->pts_per_packet;
- dp->pts = priv->last_pts;
- ds_add_packet(ds, dp);
- return 1;
-}
-
-static void demux_mpc_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
- sh_audio_t* sh_audio = demuxer->audio->sh;
- da_priv_t* priv = demuxer->priv;
- stream_t* s = demuxer->stream;
- float target = rel_seek_secs;
- if (flags & SEEK_FACTOR)
- target *= priv->length;
- if (!(flags & SEEK_ABSOLUTE))
- target += priv->last_pts;
- if (target < priv->last_pts) {
- stream_seek(s, demuxer->movi_start);
- priv->pos = 32; // empty bit buffer
- get_bits(priv, s, 8); // discard first 8 bits
- priv->last_pts = 0;
- }
- while (target > priv->last_pts) {
- int bit_len = get_bits(priv, s, 20);
- if (bit_len > 32) {
- stream_skip(s, bit_len / 32 * 4 - 4);
- get_bits(priv, s, 32); // make sure dword is reloaded
- }
- get_bits(priv, s, bit_len % 32);
- priv->last_pts += priv->pts_per_packet;
- if (s->eof) break;
- }
- if (!sh_audio) return;
-}
-
-static void demux_close_mpc(demuxer_t* demuxer) {
- da_priv_t* priv = demuxer->priv;
-
- free(priv);
-}
-
-static int demux_mpc_control(demuxer_t *demuxer,int cmd, void *arg){
- da_priv_t* priv = demuxer->priv;
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (priv->length < 1) return DEMUXER_CTRL_DONTKNOW;
- *((double *)arg) = priv->length;
- return DEMUXER_CTRL_OK;
- case DEMUXER_CTRL_GET_PERCENT_POS:
- if (priv->length < 1) return DEMUXER_CTRL_DONTKNOW;
- *((int *)arg) = priv->last_pts * 100 / priv->length;
- return DEMUXER_CTRL_OK;
- }
- return DEMUXER_CTRL_NOTIMPL;
-}
-
-
-const demuxer_desc_t demuxer_desc_mpc = {
- "Musepack demuxer",
- "mpc",
- "MPC",
- "Reza Jelveh, Reimar Doeffinger",
- "supports v7 bitstream only",
- DEMUXER_TYPE_MPC,
- 0, // unsafe autodetect
- demux_mpc_check,
- demux_mpc_fill_buffer,
- demux_mpc_open,
- demux_close_mpc,
- demux_mpc_seek,
- demux_mpc_control
-};
diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c
deleted file mode 100644
index 44ec85d2db..0000000000
--- a/libmpdemux/demux_mpg.c
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * MPG/VOB file parser for DEMUXER v2.5
- * copyright (c) 2001 by A'rpi/ESP-team
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <math.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "options.h"
-
-#include "libavutil/attributes.h"
-#include "libmpcodecs/dec_audio.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "parse_es.h"
-#include "stheader.h"
-#include "mp3_hdr.h"
-
-//#define MAX_PS_PACKETSIZE 2048
-#define MAX_PS_PACKETSIZE (224*1024)
-
-#define UNKNOWN 0
-#define VIDEO_MPEG1 0x10000001
-#define VIDEO_MPEG2 0x10000002
-#define VIDEO_MPEG4 0x10000004
-#define VIDEO_H264 0x10000005
-#define AUDIO_MP2 0x50
-#define AUDIO_A52 0x2000
-#define AUDIO_LPCM_BE 0x10001
-#define AUDIO_AAC mmioFOURCC('M', 'P', '4', 'A')
-
-typedef struct mpg_demuxer {
- float last_pts;
- float first_pts; // first pts found in stream
- float first_to_final_pts_len; // difference between final pts and first pts
- int has_valid_timestamps; // !=0 iff time stamps look linear
- // (not necessarily starting with 0)
- unsigned int es_map[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef
- int num_a_streams;
- int a_stream_ids[MAX_A_STREAMS];
-} mpg_demuxer_t;
-
-static int mpeg_pts_error=0;
-off_t ps_probe = 0;
-
-static int parse_psm(demuxer_t *demux, int len) {
- unsigned char c, id, type;
- unsigned int plen, prog_len, es_map_len;
- mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
-
- mp_dbg(MSGT_DEMUX,MSGL_V, "PARSE_PSM, len=%d\n", len);
- if(! len || len > 1018)
- return 0;
-
- c = stream_read_char(demux->stream);
- if(! (c & 0x80)) {
- stream_skip(demux->stream, len - 1); //not yet valid, discard
- return 0;
- }
- stream_skip(demux->stream, 1);
- prog_len = stream_read_word(demux->stream); //length of program descriptors
- stream_skip(demux->stream, prog_len); //.. that we ignore
- es_map_len = stream_read_word(demux->stream); //length of elementary streams map
- es_map_len = FFMIN(es_map_len, len - prog_len - 8); //sanity check
- while(es_map_len > 0) {
- type = stream_read_char(demux->stream);
- id = stream_read_char(demux->stream);
- if(id >= 0xB0 && id <= 0xEF && priv) {
- int idoffset = id - 0xB0;
- switch(type) {
- case 0x1:
- priv->es_map[idoffset] = VIDEO_MPEG1;
- break;
- case 0x2:
- priv->es_map[idoffset] = VIDEO_MPEG2;
- break;
- case 0x3:
- case 0x4:
- priv->es_map[idoffset] = AUDIO_MP2;
- break;
- case 0x0f:
- case 0x11:
- priv->es_map[idoffset] = AUDIO_AAC;
- break;
- case 0x10:
- priv->es_map[idoffset] = VIDEO_MPEG4;
- break;
- case 0x1b:
- priv->es_map[idoffset] = VIDEO_H264;
- break;
- case 0x81:
- priv->es_map[idoffset] = AUDIO_A52;
- break;
- }
- mp_dbg(MSGT_DEMUX,MSGL_V, "PSM ES, id=0x%x, type=%x, stype: %x\n", id, type, priv->es_map[idoffset]);
- }
- plen = stream_read_word(demux->stream); //length of elementary stream descriptors
- plen = FFMIN(plen, es_map_len); //sanity check
- stream_skip(demux->stream, plen); //skip descriptors for now
- es_map_len -= 4 + plen;
- }
- stream_skip(demux->stream, 4); //skip crc32
- return 1;
-}
-
-// 500000 is a wild guess
-#define TIMESTAMP_PROBE_LEN 500000
-
-//MAX_PTS_DIFF_FOR_CONSECUTIVE denotes the maximum difference
-//between two pts to consider them consecutive
-//1.0 is a wild guess
-#define MAX_PTS_DIFF_FOR_CONSECUTIVE 1.0
-
-//returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
-//if no pts is found or an error occurs, -1.0 is returned.
-//Packs are freed.
-static float read_first_mpeg_pts_at_position(demuxer_t* demuxer, off_t stream_pos)
-{
- stream_t *s = demuxer->stream;
- mpg_demuxer_t *mpg_d = demuxer->priv;
- float pts = -1.0; //the pts to return;
- float found_pts1; //the most recently found pts
- float found_pts2; //the pts found before found_pts1
- float found_pts3; //the pts found before found_pts2
- int found = 0;
-
- if(!mpg_d || stream_pos < 0)
- return pts;
-
- found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts;
- stream_seek(s, stream_pos);
-
- //We look for pts.
- //However, we do not stop at the first found one, as timestamps may reset
- //Therefore, we seek until we found three consecutive
- //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.
-
- while(found<3 && !s->eof
- && (fabsf(found_pts2-found_pts1) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
- && (fabsf(found_pts3-found_pts2) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
- && (stream_tell(s) < stream_pos + TIMESTAMP_PROBE_LEN)
- && ds_fill_buffer(demuxer->video))
- {
- if(mpg_d->last_pts != found_pts1)
- {
- if(!found)
- found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts; //the most recently found pts
- else
- {
- found_pts3 = found_pts2;
- found_pts2 = found_pts1;
- found_pts1 = mpg_d->last_pts;
- }
- found++;
- }
- }
-
- if(found == 3) pts = found_pts3;
-
- //clean up from searching of first pts;
- demux_flush(demuxer);
-
- return pts;
-}
-
-/// Open an mpg physical stream
-static demuxer_t* demux_mpg_open(demuxer_t* demuxer) {
- stream_t *s = demuxer->stream;
- mpg_demuxer_t* mpg_d;
-
- if (!ds_fill_buffer(demuxer->video)) return 0;
- mpg_d = calloc(1,sizeof(mpg_demuxer_t));
- if(mpg_d)
- {
- demuxer->priv = mpg_d;
- mpg_d->last_pts = -1.0;
- mpg_d->first_pts = -1.0;
-
- //if seeking is allowed set has_valid_timestamps if appropriate
- if(demuxer->seekable
- && (demuxer->stream->type == STREAMTYPE_FILE
- || demuxer->stream->type == STREAMTYPE_VCD)
- && demuxer->movi_start != demuxer-> movi_end
- )
- {
- //We seek to the beginning of the stream, to somewhere in the
- //middle, and to the end of the stream, while remembering the pts
- //at each of the three positions. With these pts, we check whether
- //or not the pts are "linear enough" to justify seeking by the pts
- //of the stream
-
- //The position where the stream is now
- off_t pos = stream_tell(s);
- float first_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_start);
- if(first_pts != -1.0)
- {
- float middle_pts = read_first_mpeg_pts_at_position(demuxer, (demuxer->movi_end + demuxer->movi_start)/2);
- if(middle_pts != -1.0)
- {
- float final_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_end - TIMESTAMP_PROBE_LEN);
- if(final_pts != -1.0)
- {
- // found proper first, middle, and final pts.
- float proportion = (middle_pts-first_pts==0) ? -1 : (final_pts-middle_pts)/(middle_pts-first_pts);
- // if they are linear enough set has_valid_timestamps
- if((0.5 < proportion) && (proportion < 2))
- {
- mpg_d->first_pts = first_pts;
- mpg_d->first_to_final_pts_len = final_pts - first_pts;
- mpg_d->has_valid_timestamps = 1;
- }
- }
- }
- }
-
- //Cleaning up from seeking in stream
- demuxer->stream->eof=0;
- demuxer->video->eof=0;
- demuxer->audio->eof=0;
-
- stream_seek(s,pos);
- ds_fill_buffer(demuxer->video);
- } // if ( demuxer->seekable )
- } // if ( mpg_d )
- return demuxer;
-}
-
-static void demux_close_mpg(demuxer_t* demuxer) {
- mpg_demuxer_t* mpg_d = demuxer->priv;
- free(mpg_d);
-}
-
-
-static unsigned long long read_mpeg_timestamp(stream_t *s,int c){
- unsigned int d,e;
- unsigned long long pts;
- d=stream_read_word(s);
- e=stream_read_word(s);
- if( ((c&1)!=1) || ((d&1)!=1) || ((e&1)!=1) ){
- ++mpeg_pts_error;
- return 0; // invalid pts
- }
- pts=(((uint64_t)((c>>1)&7))<<30)|((d>>1)<<15)|(e>>1);
- mp_dbg(MSGT_DEMUX,MSGL_DBG3," pts {%llu}",pts);
- return pts;
-}
-
-static void new_audio_stream(demuxer_t *demux, int aid){
- if(!demux->a_streams[aid]){
- mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demux->priv;
- sh_audio_t* sh_a;
- new_sh_audio(demux,aid);
- sh_a = (sh_audio_t*)demux->a_streams[aid];
- sh_a->needs_parsing = 1;
- switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
- case 0x00: sh_a->format=0x50;break; // mpeg
- case 0xA0: sh_a->format=0x10001;break; // dvd pcm
- case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
- else sh_a->format=0x2000;break; // ac3
- }
- //evo files
- if((aid & 0xC0) == 0xC0) sh_a->format=0x2000;
- else if(aid >= 0x98 && aid <= 0x9f) sh_a->format=0x2001;
- if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid;
- }
- if(demux->audio->id==-1) demux->audio->id=aid;
-}
-
-static int demux_mpg_read_packet(demuxer_t *demux,int id){
- int d av_unused;
- int len;
- int set_pts=0; // !=0 iff pts has been set to a proper value
- unsigned char c=0;
- unsigned long long pts=0;
- unsigned long long dts av_unused = 0;
- int l;
- int pes_ext2_subid=-1;
- double stream_pts = MP_NOPTS_VALUE;
- demux_stream_t *ds=NULL;
- demux_packet_t* dp;
- mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
-
- mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id);
-
-// if(id==0x1F0){
-// demux->synced=0; // force resync after 0x1F0
-// return -1;
-//}
-
-// if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
- if((id<0x1BC || id>=0x1F0) && id != 0x1FD) return -1;
- if(id==0x1BE) return -1; // padding stream
- if(id==0x1BF) return -1; // private2
-
- len=stream_read_word(demux->stream);
- mp_dbg(MSGT_DEMUX,MSGL_DBG3,"PACKET len=%d",len);
-// if(len==62480){ demux->synced=0;return -1;} /* :) */
- if(len==0 || len>MAX_PS_PACKETSIZE){
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS packet len: %d\n",len);
- return -2; // invalid packet !!!!!!
- }
-
- mpeg_pts_error=0;
-
- if(id==0x1BC) {
- parse_psm(demux, len);
- return 0;
- }
-
- while(len>0){ // Skip stuFFing bytes
- c=stream_read_char(demux->stream);
- --len;
- if(c!=0xFF)break;
- }
- if((c>>6)==1){ // Read (skip) STD scale & size value
-// printf(" STD_scale=%d",(c>>5)&1);
- d=((c&0x1F)<<8)|stream_read_char(demux->stream);
- len-=2;
-// printf(" STD_size=%d",d);
- c=stream_read_char(demux->stream);
- }
- // Read System-1 stream timestamps:
- if((c>>4)==2){
- pts=read_mpeg_timestamp(demux->stream,c);
- set_pts=1;
- len-=4;
- } else
- if((c>>4)==3){
- pts=read_mpeg_timestamp(demux->stream,c);
- c=stream_read_char(demux->stream);
- if((c>>4)!=1) pts=0; //printf("{ERROR4}");
- else set_pts = 1;
- dts=read_mpeg_timestamp(demux->stream,c);
- len-=4+1+4;
- } else
- if((c>>6)==2){
- int pts_flags;
- int hdrlen;
- int parse_ext2;
- // System-2 (.VOB) stream:
- c=stream_read_char(demux->stream);
- pts_flags=c>>6;
- parse_ext2 = (id == 0x1FD) && ((c & 0x3F) == 1);
- c=stream_read_char(demux->stream);
- hdrlen=c;
- len-=2;
- mp_dbg(MSGT_DEMUX,MSGL_DBG3," hdrlen=%d (len=%d)",hdrlen,len);
- if(hdrlen>len){ mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: invalid header length \n"); return -1;}
- if(pts_flags==2 && hdrlen>=5){
- c=stream_read_char(demux->stream);
- pts=read_mpeg_timestamp(demux->stream,c);
- set_pts=1;
- len-=5;hdrlen-=5;
- } else
- if(pts_flags==3 && hdrlen>=10){
- c=stream_read_char(demux->stream);
- pts=read_mpeg_timestamp(demux->stream,c);
- set_pts=1;
- c=stream_read_char(demux->stream);
- dts=read_mpeg_timestamp(demux->stream,c);
- len-=10;hdrlen-=10;
- }
- len-=hdrlen;
- if(parse_ext2 && hdrlen>=3) {
- c=stream_read_char(demux->stream);
- hdrlen--;
-
- if((c & 0x0F) != 0x0F) {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
- return -1;
- }
- if(c & 0x80) { //pes_private_data_flag
- if(hdrlen<16) {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen);
- return -1;
- }
- stream_skip(demux->stream, 16);
- hdrlen-=16;
- }
- if(c & 0x40) { //pack_header_field_flag
- int l = stream_read_char(demux->stream);
- if(l < 0) //couldn't read from the stream?
- return -1;
- hdrlen--;
- if(l < 0 || hdrlen < l) {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
- hdrlen, l);
- return -1;
- }
- stream_skip(demux->stream, l);
- hdrlen-=l;
- }
- if(c & 0x20) { //program_packet_sequence_counter_flag
- if(hdrlen < 2) {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen);
- return -1;
- }
- stream_skip(demux->stream, 2);
- hdrlen-=2;
- }
- if(c & 0x10) {
- //STD
- stream_skip(demux->stream, 2);
- hdrlen-=2;
- }
- c=stream_read_char(demux->stream); //pes_extension2 flag
- hdrlen--;
- if(c!=0x81) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown pes_extension2 format, len is > 1 \n"); return -1;}
- c=stream_read_char(demux->stream); //pes_extension2 payload === substream id
- hdrlen--;
- if(c<0x55 || c>0x5F) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x \n", c); return -1;}
- pes_ext2_subid=c;
- }
- if(hdrlen>0)
- stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes
-
- if(id==0x1FD && pes_ext2_subid!=-1) {
- //==== EVO VC1 STREAMS ===//
- if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);
- if(demux->video->id==-1) demux->video->id=pes_ext2_subid;
- if(demux->video->id==pes_ext2_subid){
- ds=demux->video;
- if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];
- if(priv && ds->sh) {
- sh_video_t *sh = (sh_video_t *)ds->sh;
- sh->format = mmioFOURCC('W', 'V', 'C', '1');
- }
- }
- }
- //============== DVD Audio sub-stream ======================
- if(id==0x1BD){
- int aid, rawa52 = 0;
- off_t tmppos;
- unsigned int tmp;
-
- tmppos = stream_tell(demux->stream);
- tmp = stream_read_word(demux->stream);
- stream_seek(demux->stream, tmppos);
- /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
- if(tmp == 0x0B77) {
- aid = 128;
- rawa52 = 1;
- }
- else {
- aid=stream_read_char(demux->stream);--len;
- if(len<3) return -1; // invalid audio packet
- }
-
- // AID:
- // 0x20..0x3F subtitle
- // 0x80..0x87 and 0xC0..0xCF AC3 audio
- // 0x88..0x8F and 0x98..0x9F DTS audio
- // 0xA0..0xBF PCM audio
-
- if((aid & 0xE0) == 0x20){
- // subtitle:
- aid&=0x1F;
-
- if(!demux->s_streams[aid]){
- sh_sub_t *sh = new_sh_sub(demux, aid);
- if (sh) sh->type = 'v';
- mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);
- }
-
- if(demux->sub->id > -1)
- demux->sub->id &= 0x1F;
- if(!demux->opts->sub_lang && demux->sub->id == -1)
- demux->sub->id = aid;
- if(demux->sub->id==aid){
- ds=demux->sub;
- }
- } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {
-
-// aid=128+(aid&0x7F);
- // aid=0x80..0xBF
- new_audio_stream(demux, aid);
- if(demux->audio->id==aid){
- int type;
- ds=demux->audio;
- if(!ds->sh) ds->sh=demux->a_streams[aid];
- // READ Packet: Skip additional audio header data:
- if(!rawa52) {
- c=stream_read_char(demux->stream);//num of frames
- type=stream_read_char(demux->stream);//startpos hi
- type=(type<<8)|stream_read_char(demux->stream);//startpos lo
-// printf("\r[%02X][%04X]",c,type);
- len-=3;
- }
- if((aid&0xE0)==0xA0 && len>=3){
- unsigned char* hdr;
- // save audio header as codecdata!
- if(!((sh_audio_t*)(ds->sh))->codecdata_len){
- ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);
- ((sh_audio_t*)(ds->sh))->codecdata_len=3;
- }
- hdr=((sh_audio_t*)(ds->sh))->codecdata;
- // read LPCM header:
- // emphasis[1], mute[1], rvd[1], frame number[5]:
- hdr[0]=stream_read_char(demux->stream);
-// printf(" [%01X:%02d]",c>>5,c&31);
- // quantization[2],freq[2],rvd[1],channels[3]
- hdr[1]=stream_read_char(demux->stream);
-// printf("[%01X:%01X] ",c>>4,c&15);
- // dynamic range control (0x80=off):
- hdr[2]=stream_read_char(demux->stream);
-// printf("[%02X] ",c);
- len-=3;
- if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
- }
-// printf(" \n");
- } // if(demux->audio->id==aid)
-
- } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X \n",aid);
- } //if(id==0x1BD)
- } else {
- if(c!=0x0f){
- mp_msg(MSGT_DEMUX,MSGL_V," {ERROR5,c=%d} \n",c);
- return -1; // invalid packet !!!!!!
- }
- }
- if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V," {PTS_err:%d} \n",mpeg_pts_error);
- mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);
-
-// if(len<=0 || len>MAX_PS_PACKETSIZE) return -1; // Invalid packet size
- if(len<=0 || len>MAX_PS_PACKETSIZE){
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);
- return -1; // invalid packet !!!!!!
- }
-
- if(id>=0x1C0 && id<=0x1DF){
- // mpeg audio
- int aid=id-0x1C0;
- new_audio_stream(demux, aid);
- if(demux->audio->id==aid){
- ds=demux->audio;
- if(!ds->sh) ds->sh=demux->a_streams[aid];
- if(priv && ds->sh) {
- sh_audio_t *sh = (sh_audio_t *)ds->sh;
- if(priv->es_map[id - 0x1B0])
- sh->format = priv->es_map[id - 0x1B0];
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
- }
- }
- } else
- if(id>=0x1E0 && id<=0x1EF){
- // mpeg video
- int aid=id-0x1E0;
- if(!demux->v_streams[aid]) new_sh_video(demux,aid);
- if(demux->video->id==-1) demux->video->id=aid;
- if(demux->video->id==aid){
- ds=demux->video;
- if(!ds->sh) ds->sh=demux->v_streams[aid];
- if(priv && ds->sh) {
- sh_video_t *sh = (sh_video_t *)ds->sh;
- if(priv->es_map[id - 0x1B0]) {
- sh->format = priv->es_map[id - 0x1B0];
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
- }
- }
- }
- }
-
- if(ds){
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
-// printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
-
- dp=new_demux_packet(len);
- if(!dp) {
- mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);
- stream_skip(demux->stream,len);
- return 0;
- }
- l = stream_read(demux->stream,dp->buffer,len);
- if(l<len)
- resize_demux_packet(dp, l);
- len = l;
- if(set_pts)
- dp->pts=pts/90000.0f;
- dp->pos=demux->filepos;
- /*
- workaround:
- set dp->stream_pts only when feeding the video stream, or strangely interleaved files
- (such as SWIII) will show strange alternations in the stream time, wildly going
- back and forth
- */
- if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)
- dp->stream_pts = stream_pts;
- ds_add_packet(ds,dp);
- if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;
-// if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
- return 1;
- }
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
- if(len<=2356) stream_skip(demux->stream,len);
- return 0;
-}
-
-static int num_elementary_packets100=0;
-static int num_elementary_packets101=0;
-static int num_elementary_packets12x=0;
-static int num_elementary_packets1B6=0;
-static int num_elementary_packetsPES=0;
-static int num_mpeg12_startcode=0;
-static int num_h264_slice=0; //combined slice
-static int num_h264_dpa=0; //DPA Slice
-static int num_h264_dpb=0; //DPB Slice
-static int num_h264_dpc=0; //DPC Slice
-static int num_h264_idr=0; //IDR Slice
-static int num_h264_sps=0;
-static int num_h264_pps=0;
-
-static int num_mp3audio_packets=0;
-
-static void clear_stats(void)
-{
- num_elementary_packets100=0;
- num_elementary_packets101=0;
- num_elementary_packets1B6=0;
- num_elementary_packets12x=0;
- num_elementary_packetsPES=0;
- num_mpeg12_startcode=0;
- num_h264_slice=0; //combined slice
- num_h264_dpa=0; //DPA Slice
- num_h264_dpb=0; //DPB Slice
- num_h264_dpc=0; //DPC Slice
- num_h264_idr=0; //IDR Slice
- num_h264_sps=0;
- num_h264_pps=0;
- num_mp3audio_packets=0;
-}
-
-//assumes demuxer->synced < 2
-static inline void update_stats(int head)
-{
- if(head==0x1B6) ++num_elementary_packets1B6;
- else if(head==0x1B3 || head==0x1B8) ++num_mpeg12_startcode;
- else if(head==0x100) ++num_elementary_packets100;
- else if(head==0x101) ++num_elementary_packets101;
- else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))
- num_elementary_packetsPES++;
- else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;
- if(head>=0x100 && head<0x1B0)
- {
- if((head&~0x60) == 0x101) ++num_h264_slice;
- else if((head&~0x60) == 0x102) ++num_h264_dpa;
- else if((head&~0x60) == 0x103) ++num_h264_dpb;
- else if((head&~0x60) == 0x104) ++num_h264_dpc;
- else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;
- else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;
- else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;
- }
-}
-
-static int demux_mpg_probe(demuxer_t *demuxer) {
- int pes av_unused = 1;
- int tmp;
- off_t tmppos;
- int file_format = DEMUXER_TYPE_UNKNOWN;
-
- tmppos=stream_tell(demuxer->stream);
- tmp=stream_read_dword(demuxer->stream);
- if(tmp==0x1E0 || tmp==0x1C0) {
- tmp=stream_read_word(demuxer->stream);
- if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...
- }
- stream_seek(demuxer->stream,tmppos);
-
- clear_stats();
-
- if(demux_mpg_open(demuxer))
- file_format=DEMUXER_TYPE_MPEG_PS;
- else {
- mp_msg(MSGT_DEMUX,MSGL_V,"MPEG packet stats: p100: %d p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d PES: %d MP3: %d, synced: %d\n",
- num_elementary_packets100,num_elementary_packets101,
- num_elementary_packets1B6,num_elementary_packets12x,
- num_h264_slice, num_h264_dpa,
- num_h264_dpb, num_h264_dpc=0,
- num_h264_idr, num_h264_sps=0,
- num_h264_pps,
- num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);
-
- //MPEG packet stats: p100: 458 p101: 458 PES: 0 MP3: 1103 (.m2v)
- if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100
- && abs(num_elementary_packets100-num_elementary_packets101)>2)
- return file_format;
-
- // some hack to get meaningfull error messages to our unhappy users:
- if(num_mpeg12_startcode>=2 && num_elementary_packets100>=2 && num_elementary_packets101>=2 &&
- abs(num_elementary_packets101+8-num_elementary_packets100)<16) {
- if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {
- return file_format;
- }
- file_format=DEMUXER_TYPE_MPEG_ES; // <-- hack is here :)
- } else
- // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
- if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
- num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&
- demuxer->synced<2) {
- file_format=DEMUXER_TYPE_MPEG4_ES;
- } else
- // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
- if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
- /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&
- num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&
- demuxer->synced<2) {
- file_format=DEMUXER_TYPE_H264_ES;
- } else
- {
- if(demuxer->synced==2)
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "MPEG: %s",
- mp_gtext("Missing video stream!? Contact the author, it may be a bug :(\n"));
- else
- mp_tmsg(MSGT_DEMUXER,MSGL_V,"Not MPEG System Stream format... (maybe Transport Stream?)\n");
- }
- }
- //FIXME this shouldn't be necessary
- stream_seek(demuxer->stream,tmppos);
- return file_format;
-}
-
-static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
- // Elementary video stream
- if(demux->stream->eof) return 0;
- demux->filepos=stream_tell(demux->stream);
- ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);
- return 1;
-}
-
-/**
- * \brief discard until 0x100 header and return a filled buffer
- * \param b buffer-end pointer
- * \param pos current pos in stream, negative since b points to end of buffer
- * \param s stream to read from
- * \return new position, differs from original pos when eof hit and thus
- * b was modified to point to the new end of buffer
- */
-static int find_end(unsigned char **b, int pos, stream_t *s) {
- register int state = 0xffffffff;
- unsigned char *buf = *b;
- int start = pos;
- int read, unused;
- // search already read part
- while (state != 0x100 && pos) {
- state = state << 8 | buf[pos++];
- }
- // continue search in stream
- while (state != 0x100) {
- register int c = stream_read_char(s);
- if (c < 0) break;
- state = state << 8 | c;
- }
- // modify previous header (from 0x1bc or 0x1bf to 0x100)
- buf[start++] = 0;
- // copy remaining buffer part to current pos
- memmove(&buf[start], &buf[pos], -pos);
- unused = start + -pos; // -unused bytes in buffer
- read = stream_read(s, &buf[unused], -unused);
- unused += read;
- // fix buffer so it ends at pos == 0 (eof case)
- *b = &buf[unused];
- start -= unused;
- return start;
-}
-
-/**
- * This format usually uses an insane bitrate, which makes this function
- * performance-critical!
- * Be sure to benchmark any changes with different compiler versions.
- */
-static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
- demux_packet_t *pack;
- int len;
- demux->filepos = stream_tell(demux->stream);
- pack = new_demux_packet(STREAM_BUFFER_SIZE);
- len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
- if (len <= 0)
- {
- free_demux_packet(pack);
- return 0;
- }
- {
- register uint32_t state = (uint32_t)demux->priv;
- register int pos = -len;
- unsigned char *buf = &pack->buffer[len];
- do {
- state = state << 8 | buf[pos];
- if (unlikely((state | 3) == 0x1bf))
- pos = find_end(&buf, pos, demux->stream);
- } while (++pos < 0);
- demux->priv = (void *)state;
- len = buf - pack->buffer;
- }
- if (len < STREAM_BUFFER_SIZE)
- resize_demux_packet(pack, len);
- ds_add_packet(ds, pack);
- return 1;
-}
-
-static int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
-{
-unsigned int head=0;
-int skipped=0;
-int max_packs=256; // 512kbyte
-int ret=0;
-
-// System stream
-do{
- demux->filepos=stream_tell(demux->stream);
- //lame workaround: this is needed to show the progress bar when playing dvdnav://
- //(ths poor guy doesn't know teh length of the stream at startup)
- demux->movi_end = demux->stream->end_pos;
- head=stream_read_dword(demux->stream);
- if((head&0xFFFFFF00)!=0x100){
- // sync...
- demux->filepos-=skipped;
- while(1){
- int c=stream_read_char(demux->stream);
- if(c<0) break; //EOF
- head<<=8;
- if(head!=0x100){
- head|=c;
- if(mp_check_mp3_header(head)) ++num_mp3audio_packets;
- ++skipped; //++demux->filepos;
- continue;
- }
- head|=c;
- break;
- }
- demux->filepos+=skipped;
- }
- if(stream_eof(demux->stream)) break;
- // sure: head=0x000001XX
- mp_dbg(MSGT_DEMUX,MSGL_DBG4,"*** head=0x%X\n",head);
- if(demux->synced==0){
- if(head==0x1BA) demux->synced=1; //else
-// if(head==0x1BD || (head>=0x1C0 && head<=0x1EF)) demux->synced=3; // PES?
- } else
- if(demux->synced==1){
- if(head==0x1BB || head==0x1BD || (head>=0x1C0 && head<=0x1EF)){
- demux->synced=2;
- mp_msg(MSGT_DEMUX,MSGL_V,"system stream synced at 0x%"PRIX64" (%"PRId64")!\n",(int64_t)demux->filepos,(int64_t)demux->filepos);
- num_elementary_packets100=0; // requires for re-sync!
- num_elementary_packets101=0; // requires for re-sync!
- } else demux->synced=0;
- } // else
- if(demux->synced>=2){
- ret=demux_mpg_read_packet(demux,head);
- if(!ret)
- if(--max_packs==0){
- demux->stream->eof=1;
- mp_tmsg(MSGT_DEMUX,MSGL_ERR,"demux: File doesn't contain the selected audio or video stream.\n");
- return 0;
- }
- if(demux->synced==3) demux->synced=(ret==1)?2:0; // PES detect
- } else {
- update_stats(head);
- if(head>=0x100 && head<0x1B0)
- mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... elementary video packet found: %03X\n",head);
- else if((head>=0x1C0 && head<0x1F0) || head==0x1BD)
- mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... PES packet found: %03X\n",head);
-
- if(((num_elementary_packets100>50 && num_elementary_packets101>50) ||
- (num_elementary_packetsPES>50)) && skipped>4000000){
- mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be ES/PES stream...\n");
- demux->stream->eof=1;
- break;
- }
- if(num_mp3audio_packets>100 && num_elementary_packets100<10){
- mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be MP3 stream...\n");
- demux->stream->eof=1;
- break;
- }
- }
-} while(ret!=1);
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux: %d bad bytes skipped\n",skipped);
- if(demux->stream->eof){
- mp_msg(MSGT_DEMUX,MSGL_V,"MPEG Stream reached EOF\n");
- return 0;
- }
- return 1;
-}
-
-static void demux_seek_mpg(demuxer_t *demuxer, float rel_seek_secs,
- float audio_delay, int flags)
-{
- demux_stream_t *d_audio=demuxer->audio;
- demux_stream_t *d_video=demuxer->video;
- sh_audio_t *sh_audio=d_audio->sh;
- sh_video_t *sh_video=d_video->sh;
- mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
- int precision = 1;
- float oldpts = 0;
- off_t oldpos = demuxer->filepos;
- float newpts = 0;
- off_t newpos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : oldpos;
-
- if(mpg_d)
- oldpts = mpg_d->last_pts;
- newpts = (flags & SEEK_ABSOLUTE) ? 0.0 : oldpts;
- //================= seek in MPEG ==========================
- //calculate the pts to seek to
- if(flags & SEEK_FACTOR) {
- if (mpg_d && mpg_d->first_to_final_pts_len > 0.0)
- newpts += mpg_d->first_to_final_pts_len * rel_seek_secs;
- else
- newpts += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * oldpts / oldpos;
- } else
- newpts += rel_seek_secs;
- if (newpts < 0) newpts = 0;
-
- if(flags&SEEK_FACTOR){
- // float seek 0..1
- newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
- } else {
- // time seek (secs)
- if (mpg_d && mpg_d->has_valid_timestamps) {
- if (mpg_d->first_to_final_pts_len > 0.0)
- newpos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / mpg_d->first_to_final_pts_len;
- else if (oldpts > 0.0)
- newpos += rel_seek_secs * (oldpos - demuxer->movi_start) / oldpts;
- } else if(!sh_video || !sh_video->i_bps) // unspecified or VBR
- newpos+=2324*75*rel_seek_secs; // 174.3 kbyte/sec
- else
- newpos+=sh_video->i_bps*rel_seek_secs;
- }
-
- while (1) {
- if(newpos<demuxer->movi_start){
- if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD
- if(newpos<demuxer->movi_start) newpos=demuxer->movi_start;
- }
-
- stream_seek(demuxer->stream,newpos);
-
- // re-sync video:
- videobuf_code_len=0; // reset ES stream buffer
-
- ds_fill_buffer(d_video);
- if(sh_audio){
- ds_fill_buffer(d_audio);
- }
-
- while(1){
- int i;
- if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts){
- float a_pts=d_audio->pts;
- a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
- if(d_video->pts>a_pts){
- skip_audio_frame(sh_audio); // sync audio
- continue;
- }
- }
- if(!sh_video) break;
- i=sync_video_packet(d_video);
- if(sh_video->format == mmioFOURCC('W', 'V', 'C', '1')) {
- if(i==0x10E || i==0x10F) //entry point or sequence header
- break;
- } else
- if(sh_video->format == 0x10000004) { //mpeg4
- if(i==0x1B6) { //vop (frame) startcode
- int pos = videobuf_len;
- if(!read_video_packet(d_video)) break; // EOF
- if((videobuffer[pos+4] & 0x3F) == 0) break; //I-frame
- }
- } else if(sh_video->format == 0x10000005){ //h264
- if((i & ~0x60) == 0x105) break;
- } else { //default mpeg1/2
- if(i==0x1B3 || i==0x1B8) break; // found it!
- }
- if(!i || !skip_video_packet(d_video)) break; // EOF?
- }
- if(!mpg_d)
- break;
- if (!precision || abs(newpts - mpg_d->last_pts) < 0.5 || (mpg_d->last_pts == oldpts)) break;
- if ((newpos - oldpos) * (mpg_d->last_pts - oldpts) < 0) { // invalid timestamps
- mpg_d->has_valid_timestamps = 0;
- break;
- }
- precision--;
- //prepare another seek because we are off by more than 0.5s
- if(mpg_d) {
- newpos += (newpts - mpg_d->last_pts) * (newpos - oldpos) / (mpg_d->last_pts - oldpts);
- demux_flush(demuxer);
- demuxer->stream->eof=0; // clear eof flag
- d_video->eof=0;
- d_audio->eof=0;
- }
- }
-}
-
-static int demux_mpg_control(demuxer_t *demuxer, int cmd, void *arg)
-{
- mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
-
- switch(cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if(stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, arg) != STREAM_UNSUPPORTED) {
- mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\r\nDEMUX_MPG_CTRL, (%.3f)\r\n", *((double*)arg));
- return DEMUXER_CTRL_GUESS;
- }
- if (mpg_d && mpg_d->has_valid_timestamps) {
- *((double *)arg)=(double)mpg_d->first_to_final_pts_len;
- return DEMUXER_CTRL_OK;
- }
- return DEMUXER_CTRL_DONTKNOW;
-
- case DEMUXER_CTRL_GET_PERCENT_POS:
- if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
- *((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
- return DEMUXER_CTRL_OK;
- }
- return DEMUXER_CTRL_DONTKNOW;
-
- case DEMUXER_CTRL_SWITCH_AUDIO:
- if(! (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh))
- return DEMUXER_CTRL_NOTIMPL;
- else {
- demux_stream_t *d_audio = demuxer->audio;
- sh_audio_t *sh_audio = d_audio->sh;
- sh_audio_t *sh_a = sh_audio;
- int i;
- if(!sh_audio)
- return DEMUXER_CTRL_NOTIMPL;
- if (*((int*)arg) < 0)
- {
- for (i = 0; i < mpg_d->num_a_streams; i++) {
- if (d_audio->id == mpg_d->a_stream_ids[i]) break;
- }
- i = (i+1) % mpg_d->num_a_streams;
- sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]];
- }
- else {
- for (i = 0; i < mpg_d->num_a_streams; i++)
- if (*((int*)arg) == mpg_d->a_stream_ids[i]) break;
- if (i < mpg_d->num_a_streams)
- sh_a = (sh_audio_t*)demuxer->a_streams[*((int*)arg)];
- }
- if (i < mpg_d->num_a_streams && d_audio->id != mpg_d->a_stream_ids[i]) {
- d_audio->id = mpg_d->a_stream_ids[i];
- d_audio->sh = sh_a;
- ds_free_packs(d_audio);
- }
- }
- *((int*)arg) = demuxer->audio->id;
- return DEMUXER_CTRL_OK;
-
- default:
- return DEMUXER_CTRL_NOTIMPL;
- }
-}
-
-
-static int demux_mpg_pes_probe(demuxer_t *demuxer) {
- demuxer->synced = 3;
- return (demux_mpg_probe(demuxer) == DEMUXER_TYPE_MPEG_PS) ? DEMUXER_TYPE_MPEG_PES : 0;
-}
-
-
-static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
-{
- sh_video_t *sh_video=NULL;
-
- demuxer->audio->sh = NULL; // ES streams has no audio channel
- demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
- sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
-
- return demuxer;
-}
-
-static demuxer_t *demux_mpg_gxf_open(demuxer_t *demuxer) {
- demuxer->audio->sh = NULL;
- demuxer->video->sh = new_sh_video(demuxer,0);
- ((sh_video_t *)demuxer->video->sh)->ds = demuxer->video;
- demuxer->priv = (void *) 0xffffffff;
- return demuxer;
-}
-
-static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
-{
- sh_audio_t *sh_audio=NULL;
- sh_video_t *sh_video=NULL;
-
- sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
-
- if(demuxer->audio->id!=-2) {
- if(!ds_fill_buffer(demuxer->audio)){
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "MPEG: %s",
- mp_gtext("No audio stream found -> no sound.\n"));
- demuxer->audio->sh=NULL;
- } else {
- sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
- }
- }
-
- if(!sh_video->format && ps_probe > 0) {
- int head;
- off_t pos = stream_tell(demuxer->stream);
-
- clear_stats();
- do {
- head=sync_video_packet(demuxer->video);
- if(!head) break;
- update_stats(head);
- skip_video_packet(demuxer->video);
- } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
-
- ds_free_packs(demuxer->video);
- demuxer->stream->eof=0;
- stream_seek(demuxer->stream, pos);
- mp_msg(MSGT_DEMUX,MSGL_INFO,"MPEG packet stats: p100: %d p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d\n",
- num_elementary_packets100, num_elementary_packets101,
- num_elementary_packets1B6, num_elementary_packets12x,
- num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
- num_h264_idr, num_h264_sps, num_h264_pps);
-
- if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
- num_elementary_packets100<=num_elementary_packets12x)
- sh_video->format = 0x10000004;
- else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
- num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
- num_elementary_packets1B6==0)
- sh_video->format = 0x10000005;
- else sh_video->format = 0x10000002;
- }
-
- return demuxer;
-}
-
-
-const demuxer_desc_t demuxer_desc_mpeg_ps = {
- "MPEG PS demuxer",
- "mpegps",
- "MPEG-PS",
- "Arpi?",
- "Mpeg",
- DEMUXER_TYPE_MPEG_PS,
- 0, // unsafe autodetect
- demux_mpg_probe,
- demux_mpg_fill_buffer,
- demux_mpg_ps_open,
- demux_close_mpg,
- demux_seek_mpg,
- demux_mpg_control,
-};
-
-
-const demuxer_desc_t demuxer_desc_mpeg_pes = {
- "MPEG PES demuxer",
- "mpegpes",
- "MPEG-PES",
- "Arpi?",
- "Mpeg",
- DEMUXER_TYPE_MPEG_PES,
- 0, // unsafe autodetect
- demux_mpg_pes_probe,
- demux_mpg_fill_buffer,
- demux_mpg_ps_open,
- demux_close_mpg,
- demux_seek_mpg,
- demux_mpg_control,
-};
-
-
-const demuxer_desc_t demuxer_desc_mpeg_gxf = {
- "MPEG ES in GXF demuxer",
- "mpeggxf",
- "MPEG-ES in GXF",
- "Reimar Doeffinger",
- "Mpeg",
- DEMUXER_TYPE_MPEG_GXF,
- 0, // hack autodetection
- NULL,
- demux_mpg_gxf_fill_buffer,
- demux_mpg_gxf_open,
- NULL,
- NULL,
- NULL
-};
-
-const demuxer_desc_t demuxer_desc_mpeg_es = {
- "MPEG ES demuxer",
- "mpeges",
- "MPEG-ES",
- "Arpi?",
- "Mpeg",
- DEMUXER_TYPE_MPEG_ES,
- 0, // hack autodetection
- NULL,
- demux_mpg_es_fill_buffer,
- demux_mpg_es_open,
- demux_close_mpg,
- demux_seek_mpg,
- demux_mpg_control,
-};
-
-
-const demuxer_desc_t demuxer_desc_mpeg4_es = {
- "MPEG4 ES demuxer",
- "mpeg4es",
- "MPEG-ES",
- "Arpi?",
- "Mpeg",
- DEMUXER_TYPE_MPEG4_ES,
- 0, // hack autodetection
- NULL,
- demux_mpg_es_fill_buffer,
- demux_mpg_es_open,
- demux_close_mpg,
- demux_seek_mpg,
- demux_mpg_control,
-};
-
-
-const demuxer_desc_t demuxer_desc_h264_es = {
- "H.264 ES demuxer",
- "h264es",
- "H264-ES",
- "Arpi?",
- "Mpeg",
- DEMUXER_TYPE_H264_ES,
- 0, // hack autodetection
- NULL,
- demux_mpg_es_fill_buffer,
- demux_mpg_es_open,
- demux_close_mpg,
- demux_seek_mpg,
- demux_mpg_control,
-};
diff --git a/libmpdemux/demux_nsv.c b/libmpdemux/demux_nsv.c
deleted file mode 100644
index 9ab68dd894..0000000000
--- a/libmpdemux/demux_nsv.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Nullsoft Streaming Video demuxer
- * copyright (c) 2004 by Reza Jelveh <reza.jelveh@tuhh.de>
- * Based on A'rpis G2 work
- *
- * seeking and PCM audio not yet supported
- * PCM needs extra audio chunk "miniheader" parsing
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-typedef struct {
- float v_pts;
- int video_pack_no;
- unsigned int a_format;
- unsigned int v_format;
- unsigned char fps;
-} nsv_priv_t;
-
-#define HEADER_SEARCH_SIZE 256000
-
-
-/**
- * Seeking still to be implemented
- */
-static void demux_seek_nsv ( demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags )
-{
-// seeking is not yet implemented
-}
-
-
-static int demux_nsv_fill_buffer ( demuxer_t *demuxer, demux_stream_t *ds )
-{
- unsigned char hdr[17];
- // for the extra data
- unsigned char aux[6];
- int i_aux = 0;
- // videolen = audio chunk length, audiolen = video chunk length
- int videolen,audiolen;
-
- sh_video_t *sh_video = demuxer->video->sh;
- sh_audio_t *sh_audio = demuxer->audio->sh;
-
- nsv_priv_t * priv = demuxer->priv;
-
- // if the audio/video chunk has no new header the first 2 bytes will be discarded 0xBEEF
- // or rather 0xEF 0xBE
- stream_read(demuxer->stream,hdr,7);
- if(stream_eof(demuxer->stream)) return 0;
- // sometimes instead of 0xBEEF as described for the next audio/video chunk we get
- // a whole new header
-
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, "demux_nsv: %08X %08X\n",
- hdr[0]<<8|hdr[1], (unsigned int)stream_tell(demuxer->stream));
- switch(hdr[0]<<8|hdr[1]) {
- case 0x4E53:
- if(hdr[2]==0x56 && hdr[3]==0x73){
- // NSVs
- // get the header since there is no more metaheader after the first one
- // there is no more need to skip that
- stream_read(demuxer->stream,hdr+7,17-7);
- stream_read(demuxer->stream,hdr,7);
- }
- break;
-
- case 0xEFBE:
- break;
-
- default:
- mp_dbg(MSGT_DEMUX,MSGL_WARN,"demux_nsv: sync lost\n");
- break;
- }
-
- if (sh_video)
- priv->v_pts =demuxer->video->pts= priv->video_pack_no *
- (float)sh_video->frametime;
- else
- priv->v_pts = priv->video_pack_no;
-
- demuxer->filepos=stream_tell(demuxer->stream);
-
-
- mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %08X: %02X %02X | %02X %02X %02X | %02X %02X \n",
- (int)demuxer->filepos, hdr[0],hdr[1],hdr[2],hdr[3],hdr[4],hdr[5],hdr[6]);
-
- // read video:
- videolen=(hdr[2]>>4)|(hdr[3]<<4)|(hdr[4]<<0xC);
- //check if we got extra data like subtitles here
- if( (hdr[2]&0x0f) != 0x0 ) {
- stream_read( demuxer->stream, aux, 6);
-
- i_aux = aux[0]|aux[1]<<8;
- // We skip this extra data
- stream_skip( demuxer->stream, i_aux );
- i_aux+=6;
- videolen -= i_aux;
- }
-
-
- // we need to return an empty packet when the
- // video frame is empty otherwise the stream will fasten up
- if(sh_video) {
- if( (hdr[2]&0x0f) != 0x0 )
- ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos-i_aux,0);
- else
- ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos,0);
- }
- else
- stream_skip(demuxer->stream,videolen);
-
- // read audio:
- audiolen=(hdr[5])|(hdr[6]<<8);
- // we need to return an empty packet when the
- // audio frame is empty otherwise the stream will fasten up
- if(sh_audio) {
- ds_read_packet(demuxer->audio,demuxer->stream,audiolen,priv->v_pts,demuxer->filepos+videolen,0);
- }
- else
- stream_skip(demuxer->stream,audiolen);
-
- ++priv->video_pack_no;
-
- return 1;
-
-}
-
-
-static demuxer_t* demux_open_nsv ( demuxer_t* demuxer )
-{
- // last 2 bytes 17 and 18 are unknown but right after that comes the length
- unsigned char hdr[17];
- int videolen,audiolen;
- unsigned char buf[10];
- sh_video_t *sh_video = NULL;
- sh_audio_t *sh_audio = NULL;
-
-
- nsv_priv_t * priv = malloc(sizeof(nsv_priv_t));
- demuxer->priv=priv;
- priv->video_pack_no=0;
-
- /* disable seeking yet to be fixed*/
- demuxer->seekable = 0;
-
- stream_read(demuxer->stream,hdr,4);
- if(stream_eof(demuxer->stream)) return 0;
-
- if(hdr[0]==0x4E && hdr[1]==0x53 && hdr[2]==0x56){
- // NSV header!
- if(hdr[3]==0x73){
- // NSVs
- stream_read(demuxer->stream,hdr+4,17-4);
- }
-
- if(hdr[3]==0x66){
- // NSVf
- int len=stream_read_dword_le(demuxer->stream);
- // TODO: parse out metadata!!!!
- stream_skip(demuxer->stream,len-8);
-
- // NSVs
- stream_read(demuxer->stream,hdr,17);
- if (stream_eof(demuxer->stream) || strncmp(hdr, "NSVs", 4))
- return 0;
- }
-
- // dummy debug message
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_nsv: Header: %.12s\n",hdr);
-
- // bytes 8-11 audio codec fourcc
- // PCM fourcc needs extra parsing for every audio chunk, yet to implement
- if((demuxer->audio->id != -2) && strncmp(hdr+8,"NONE", 4)){//&&strncmp(hdr+8,"VLB ", 4)){
- sh_audio = new_sh_audio ( demuxer, 0 );
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- sh_audio->format=mmioFOURCC(hdr[8],hdr[9],hdr[10],hdr[11]);
- sh_audio->ds = demuxer->audio;
- priv->a_format=mmioFOURCC(hdr[8],hdr[9],hdr[10],hdr[11]);
- }
-
- // store hdr fps
- priv->fps=hdr[16];
-
- if ((demuxer->video->id != -2) && strncmp(hdr+4,"NONE", 4)) {
- /* Create a new video stream header */
- sh_video = new_sh_video ( demuxer, 0 );
-
- /* Make sure the demuxer knows about the new video stream header
- * (even though new_sh_video() ought to take care of it)
- */
- demuxer->video->sh = sh_video;
-
- /* Make sure that the video demuxer stream header knows about its
- * parent video demuxer stream (this is getting wacky), or else
- * video_read_properties() will choke
- */
- sh_video->ds = demuxer->video;
-
- // bytes 4-7 video codec fourcc
- priv->v_format = sh_video->format=mmioFOURCC(hdr[4],hdr[5],hdr[6],hdr[7]);
-
- // new video stream! parse header
- sh_video->disp_w=hdr[12]|(hdr[13]<<8);
- sh_video->disp_h=hdr[14]|(hdr[15]<<8);
- sh_video->bih=calloc(1,sizeof(*sh_video->bih));
- sh_video->bih->biSize=sizeof(*sh_video->bih);
- sh_video->bih->biPlanes=1;
- sh_video->bih->biBitCount=24;
- sh_video->bih->biWidth=hdr[12]|(hdr[13]<<8);
- sh_video->bih->biHeight=hdr[14]|(hdr[15]<<8);
- memcpy(&sh_video->bih->biCompression,hdr+4,4);
- sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;
-
- // here we search for the correct keyframe
- // vp6 keyframe is when the 2nd byte of the vp6 header is
- // 0x36 for VP61 and 0x46 for VP62
- if((priv->v_format==mmioFOURCC('V','P','6','1')) ||
- (priv->v_format==mmioFOURCC('V','P','6','2')) ||
- (priv->v_format==mmioFOURCC('V','P','3','1'))) {
- stream_read(demuxer->stream,buf,10);
- if (((((priv->v_format>>16) & 0xff) == '6') && ((buf[8]&0x0e)!=0x06)) ||
- ((((priv->v_format>>16) & 0xff) == '3') && (buf[8]!=0x00 || buf[9]!=0x08))) {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_nsv: searching %.4s keyframe...\n", (char*)&priv->v_format);
- while(((((priv->v_format>>16) & 0xff) == '6') && ((buf[8]&0x0e)!=0x06)) ||
- ((((priv->v_format>>16) & 0xff) == '3') && (buf[8]!=0x00 || buf[9]!=0x08))){
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %.4s block skip.\n", (char*)&priv->v_format);
- videolen=(buf[2]>>4)|(buf[3]<<4)|(buf[4]<<0xC);
- audiolen=(buf[5])|(buf[6]<<8);
- stream_skip(demuxer->stream, videolen+audiolen-3);
- stream_read(demuxer->stream,buf,10);
- if(stream_eof(demuxer->stream)) return 0;
- if(buf[0]==0x4E){
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: Got NSVs block.\n");
- stream_skip(demuxer->stream,7);
- stream_read(demuxer->stream,buf,10);
- }
- }
- }
-
- // data starts 10 bytes before current pos but later
- // we seek 17 backwards
- stream_skip(demuxer->stream,7);
- }
-
- switch(priv->fps){
- case 0x80:
- sh_video->fps=30;
- break;
- case 0x81:
- sh_video->fps=(float)30000.0/1001.0;
- break;
- case 0x82:
- sh_video->fps=25;
- break;
- case 0x83:
- sh_video->fps=(float)24000.0/1001.0;
- break;
- case 0x85:
- sh_video->fps=(float)15000.0/1001.0;
- break;
- case 0x89:
- sh_video->fps=(float)10000.0/1001.0;
- break;
- default:
- sh_video->fps = (float)priv->fps;
- }
- sh_video->frametime = (float)1.0 / (float)sh_video->fps;
- }
- }
-
- // seek to start of NSV header
- stream_seek(demuxer->stream,stream_tell(demuxer->stream)-17);
-
- return demuxer;
-}
-
-static int nsv_check_file ( demuxer_t* demuxer )
-{
- uint32_t hdr = 0;
- int i;
-
- mp_msg ( MSGT_DEMUX, MSGL_V, "Checking for Nullsoft Streaming Video\n" );
-
- for (i = 0; i < HEADER_SEARCH_SIZE; i++) {
- uint8_t c = stream_read_char(demuxer->stream);
- if (stream_eof(demuxer->stream))
- return 0;
- if (hdr == mmioFOURCC('s', 'V', 'S', 'N') ||
- (hdr == mmioFOURCC('f', 'V', 'S', 'N') && !c)) {
- stream_seek(demuxer->stream,stream_tell(demuxer->stream)-5);
- return DEMUXER_TYPE_NSV;
- }
- hdr = (hdr << 8) | c;
- }
-
- return 0;
-}
-
-static void demux_close_nsv(demuxer_t* demuxer) {
- nsv_priv_t* priv = demuxer->priv;
-
- free(priv);
-
-}
-
-
-const demuxer_desc_t demuxer_desc_nsv = {
- "NullsoftVideo demuxer",
- "nsv",
- "Nullsoft Streaming Video",
- "Reza Jelveh",
- "nsv and nsa streaming files",
- DEMUXER_TYPE_NSV,
- 0, // safe but expensive autodetect
- nsv_check_file,
- demux_nsv_fill_buffer,
- demux_open_nsv,
- demux_close_nsv,
- demux_seek_nsv,
- NULL
-};
diff --git a/libmpdemux/demux_nut.c b/libmpdemux/demux_nut.c
deleted file mode 100644
index e6602ef506..0000000000
--- a/libmpdemux/demux_nut.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-#include <libnut.h>
-
-typedef struct {
- int last_pts; // FIXME
- nut_context_tt * nut;
- nut_stream_header_tt * s;
-} nut_priv_tt;
-
-static size_t mp_read(void * h, size_t len, uint8_t * buf) {
- stream_t * stream = (stream_t*)h;
-
- if(stream_eof(stream)) return 0;
- //len = MIN(len, 5);
-
- return stream_read(stream, buf, len);
-}
-
-static int mp_eof(void * h) {
- stream_t * stream = (stream_t*)h;
- if(stream_eof(stream)) return 1;
- return 0;
-}
-
-static off_t mp_seek(void * h, long long pos, int whence) {
- stream_t * stream = (stream_t*)h;
-
- if (stream->end_pos < stream_tell(stream))
- stream->end_pos = stream_tell(stream);
-
- if (whence == SEEK_CUR) pos += stream_tell(stream);
- else if (whence == SEEK_END) pos += stream->end_pos;
- else if (whence != SEEK_SET) return -1;
-
- if (pos < stream->end_pos && stream->eof) stream_reset(stream);
- if (stream_seek(stream, pos) == 0) return -1;
-
- return pos;
-}
-
-#define ID_STRING "nut/multimedia container"
-#define ID_LENGTH (strlen(ID_STRING) + 1)
-
-static int nut_check_file(demuxer_t * demuxer) {
- uint8_t buf[ID_LENGTH];
-
- if (stream_read(demuxer->stream, buf, ID_LENGTH) != ID_LENGTH) return 0;
-
- if (memcmp(buf, ID_STRING, ID_LENGTH)) return 0;
-
- stream_seek(demuxer->stream, 0);
- return DEMUXER_TYPE_NUT;
-}
-
-static demuxer_t * demux_open_nut(demuxer_t * demuxer) {
- nut_demuxer_opts_tt dopts = {
- .input = {
- .priv = demuxer->stream,
- .seek = mp_seek,
- .read = mp_read,
- .eof = mp_eof,
- .file_pos = stream_tell(demuxer->stream),
- },
- .alloc = { .malloc = NULL },
- .read_index = index_mode,
- .cache_syncpoints = 1,
- };
- nut_priv_tt * priv = demuxer->priv = calloc(1, sizeof(nut_priv_tt));
- nut_context_tt * nut = priv->nut = nut_demuxer_init(&dopts);
- nut_stream_header_tt * s;
- int ret;
- int i;
-
- while ((ret = nut_read_headers(nut, &s, NULL)) == NUT_ERR_EAGAIN);
- if (ret) {
- mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", nut_error(ret));
- return NULL;
- }
-
- priv->s = s;
-
- for (i = 0; s[i].type != -1 && i < 2; i++) switch(s[i].type) {
- case NUT_AUDIO_CLASS: {
- WAVEFORMATEX *wf =
- calloc(sizeof(*wf) +
- s[i].codec_specific_len, 1);
- sh_audio_t* sh_audio = new_sh_audio(demuxer, i);
- int j;
- mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "nut", i);
-
- sh_audio->wf= wf; sh_audio->ds = demuxer->audio;
- sh_audio->audio.dwSampleSize = 0; // FIXME
- sh_audio->audio.dwScale = s[i].time_base.num;
- sh_audio->audio.dwRate = s[i].time_base.den;
- sh_audio->format = 0;
- for (j = 0; j < s[i].fourcc_len && j < 4; j++)
- sh_audio->format |= s[i].fourcc[j]<<(j*8);
- sh_audio->channels = s[i].channel_count;
- sh_audio->samplerate =
- s[i].samplerate_num / s[i].samplerate_denom;
- sh_audio->i_bps = 0; // FIXME
-
- wf->wFormatTag = sh_audio->format;
- wf->nChannels = s[i].channel_count;
- wf->nSamplesPerSec =
- s[i].samplerate_num / s[i].samplerate_denom;
- wf->nAvgBytesPerSec = 0; // FIXME
- wf->nBlockAlign = 0; // FIXME
- wf->wBitsPerSample = 0; // FIXME
- wf->cbSize = s[i].codec_specific_len;
- if (s[i].codec_specific_len)
- memcpy(wf + 1, s[i].codec_specific,
- s[i].codec_specific_len);
-
- demuxer->audio->id = i;
- demuxer->audio->sh= demuxer->a_streams[i];
- break;
- }
- case NUT_VIDEO_CLASS: {
- BITMAPINFOHEADER * bih =
- calloc(sizeof(*bih) +
- s[i].codec_specific_len, 1);
- sh_video_t * sh_video = new_sh_video(demuxer, i);
- int j;
- mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Video stream found, -vid %d\n", "nut", i);
-
- sh_video->bih = bih;
- sh_video->ds = demuxer->video;
- sh_video->disp_w = s[i].width;
- sh_video->disp_h = s[i].height;
- sh_video->video.dwScale = s[i].time_base.num;
- sh_video->video.dwRate = s[i].time_base.den;
-
- sh_video->fps = sh_video->video.dwRate/
- (float)sh_video->video.dwScale;
- sh_video->frametime = 1./sh_video->fps;
- sh_video->format = 0;
- for (j = 0; j < s[i].fourcc_len && j < 4; j++)
- sh_video->format |= s[i].fourcc[j]<<(j*8);
- if (!s[i].sample_height) sh_video->aspect = 0;
- else sh_video->aspect =
- s[i].sample_width / (float)s[i].sample_height;
- sh_video->i_bps = 0; // FIXME
-
- bih->biSize = sizeof(*bih) +
- s[i].codec_specific_len;
- bih->biWidth = s[i].width;
- bih->biHeight = s[i].height;
- bih->biBitCount = 0; // FIXME
- bih->biSizeImage = 0; // FIXME
- bih->biCompression = sh_video->format;
-
- if (s[i].codec_specific_len)
- memcpy(bih + 1, s[i].codec_specific,
- s[i].codec_specific_len);
-
- demuxer->video->id = i;
- demuxer->video->sh = demuxer->v_streams[i];
- break;
- }
- }
-
- return demuxer;
-}
-
-static int demux_nut_fill_buffer(demuxer_t * demuxer, demux_stream_t * dsds) {
- nut_priv_tt * priv = demuxer->priv;
- nut_context_tt * nut = priv->nut;
- demux_packet_t *dp;
- demux_stream_t *ds;
- nut_packet_tt pd;
- int ret;
- double pts;
-
- demuxer->filepos = stream_tell(demuxer->stream);
- if (stream_eof(demuxer->stream)) return 0;
-
- while ((ret = nut_read_next_packet(nut, &pd)) == NUT_ERR_EAGAIN);
- if (ret) {
- if (ret != NUT_ERR_EOF)
- mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n",
- nut_error(ret));
- return 0; // fatal error
- }
-
- pts = (double)pd.pts * priv->s[pd.stream].time_base.num /
- priv->s[pd.stream].time_base.den;
-
- if (pd.stream == demuxer->audio->id) {
- ds = demuxer->audio;
- }
- else if (pd.stream == demuxer->video->id) {
- ds = demuxer->video;
- }
- else {
- uint8_t buf[pd.len];
- while ((ret = nut_read_frame(nut, &pd.len, buf)) == NUT_ERR_EAGAIN);
- if (ret) {
- mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n",
- nut_error(ret));
- return 0; // fatal error
- }
- return 1;
- }
-
- if (pd.stream == 0) priv->last_pts = pd.pts;
-
- dp = new_demux_packet(pd.len);
-
- dp->pts = pts;
-
- dp->pos = demuxer->filepos;
- dp->keyframe = pd.flags & NUT_FLAG_KEY;
-
- {int len = pd.len;
- while ((ret = nut_read_frame(nut, &len, dp->buffer + pd.len-len)) == NUT_ERR_EAGAIN);
- }
- if (ret) {
- mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n",
- nut_error(ret));
- return 0; // fatal error
- }
-
- ds_add_packet(ds, dp); // append packet to DS stream
- return 1;
-}
-
-static void demux_seek_nut(demuxer_t * demuxer, float time_pos, float audio_delay, int flags) {
- nut_context_tt * nut = ((nut_priv_tt*)demuxer->priv)->nut;
- nut_priv_tt * priv = demuxer->priv;
- int nutflags = 0;
- int ret;
- const int tmp[] = { 0, -1 };
-
- if (!(flags & SEEK_ABSOLUTE)) {
- nutflags |= 1; // relative
- if (time_pos > 0) nutflags |= 2; // forwards
- }
-
- if (flags & SEEK_FACTOR)
- time_pos *= priv->s[0].max_pts *
- (double)priv->s[0].time_base.num /
- priv->s[0].time_base.den;
-
- while ((ret = nut_seek(nut, time_pos, nutflags, tmp)) == NUT_ERR_EAGAIN);
- priv->last_pts = -1;
- if (ret) mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", nut_error(ret));
- demuxer->filepos = stream_tell(demuxer->stream);
-}
-
-static int demux_control_nut(demuxer_t * demuxer, int cmd, void * arg) {
- nut_priv_tt * priv = demuxer->priv;
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- *((double *)arg) = priv->s[0].max_pts *
- (double)priv->s[0].time_base.num /
- priv->s[0].time_base.den;
- return DEMUXER_CTRL_OK;
- case DEMUXER_CTRL_GET_PERCENT_POS:
- if (priv->s[0].max_pts == 0 || priv->last_pts == -1)
- return DEMUXER_CTRL_DONTKNOW;
- *((int *)arg) = priv->last_pts * 100 /
- (double)priv->s[0].max_pts;
- return DEMUXER_CTRL_OK;
- default:
- return DEMUXER_CTRL_NOTIMPL;
- }
-}
-
-static void demux_close_nut(demuxer_t *demuxer) {
- nut_priv_tt * priv = demuxer->priv;
- if (!priv) return;
- nut_demuxer_uninit(priv->nut);
- free(demuxer->priv);
- demuxer->priv = NULL;
-}
-
-
-const demuxer_desc_t demuxer_desc_nut = {
- "NUT demuxer",
- "nut",
- "libnut",
- "Oded Shimon (ods15)",
- "NUT demuxer, requires libnut",
- DEMUXER_TYPE_NUT,
- 1, // safe check demuxer
- nut_check_file,
- demux_nut_fill_buffer,
- demux_open_nut,
- demux_close_nut,
- demux_seek_nut,
- demux_control_nut
-};
diff --git a/libmpdemux/demux_ogg.c b/libmpdemux/demux_ogg.c
deleted file mode 100644
index 9eea061106..0000000000
--- a/libmpdemux/demux_ogg.c
+++ /dev/null
@@ -1,1660 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <math.h>
-#include <inttypes.h>
-
-#include <libavutil/intreadwrite.h>
-
-#include "options.h"
-#include "mp_msg.h"
-#include "talloc.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-#include "aviprint.h"
-#include "demux_mov.h"
-#include "demux_ogg.h"
-
-#define FOURCC_VORBIS mmioFOURCC('v', 'r', 'b', 's')
-#define FOURCC_SPEEX mmioFOURCC('s', 'p', 'x', ' ')
-#define FOURCC_THEORA mmioFOURCC('t', 'h', 'e', 'o')
-
-#ifdef CONFIG_TREMOR
-#include <tremor/ogg.h>
-#include <tremor/ivorbiscodec.h>
-#else
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-#endif
-
-#ifdef CONFIG_OGGTHEORA
-#include <theora/theora.h>
-int _ilog (unsigned int); /* defined in many places in theora/lib/ */
-#endif
-
-#define BLOCK_SIZE 4096
-
-/* Theora decoder context : we won't be able to interpret granule positions
- * without using theora_granule_time with the theora_state of the stream.
- * This is duplicated in `vd_theora.c'; put this in a common header?
- */
-#ifdef CONFIG_OGGTHEORA
-typedef struct theora_struct_st {
- theora_state st;
- theora_comment cc;
- theora_info inf;
-} theora_struct_t;
-#endif
-
-//// OggDS headers
-// Header for the new header format
-typedef struct stream_header_video {
- ogg_int32_t width;
- ogg_int32_t height;
-} stream_header_video;
-
-typedef struct stream_header_audio {
- ogg_int16_t channels;
- ogg_int16_t blockalign;
- ogg_int32_t avgbytespersec;
-} stream_header_audio;
-
-typedef struct __attribute__((__packed__)) stream_header {
- char streamtype[8];
- char subtype[4];
-
- ogg_int32_t size; // size of the structure
-
- ogg_int64_t time_unit; // in reference time
- ogg_int64_t samples_per_unit;
- ogg_int32_t default_len; // in media time
-
- ogg_int32_t buffersize;
- ogg_int16_t bits_per_sample;
-
- ogg_int16_t padding;
-
- union {
- // Video specific
- stream_header_video video;
- // Audio specific
- stream_header_audio audio;
- } sh;
-} stream_header;
-
-/// Our private datas
-
-typedef struct ogg_syncpoint {
- int64_t granulepos;
- off_t page_pos;
-} ogg_syncpoint_t;
-
-/// A logical stream
-typedef struct ogg_stream {
- /// Timestamping stuff
- float samplerate; /// granulpos 2 time
- int64_t lastpos;
- int32_t lastsize;
- int keyframe_frequency_force;
-
- // Logical stream state
- ogg_stream_state stream;
- int hdr_packets;
- int vorbis;
- int speex;
- int theora;
- int flac;
- int text;
- int id;
-
- vorbis_info vi;
- int vi_initialized;
-
- void *ogg_d;
-} ogg_stream_t;
-
-typedef struct ogg_demuxer {
- /// Physical stream state
- ogg_sync_state sync;
- /// Current page
- ogg_page page;
- /// Logical streams
- ogg_stream_t *subs;
- int num_sub;
- ogg_syncpoint_t *syncpoints;
- int num_syncpoint;
- off_t pos, last_size;
- int64_t initial_granulepos;
- int64_t final_granulepos;
- int64_t duration;
-
- /* Used for subtitle switching. */
- int n_text;
- int *text_ids;
- char **text_langs;
-} ogg_demuxer_t;
-
-#define NUM_VORBIS_HDR_PACKETS 3
-
-/// Some defines from OggDS
-#define PACKET_TYPE_HEADER 0x01
-#define PACKET_TYPE_BITS 0x07
-#define PACKET_LEN_BITS01 0xc0
-#define PACKET_LEN_BITS2 0x02
-#define PACKET_IS_SYNCPOINT 0x08
-
-//-------- subtitle support - should be moved to decoder layer, and queue
-// - subtitles up in demuxer buffer...
-
-#include "sub/subreader.h"
-#include "sub/sub.h"
-#define OGG_SUB_MAX_LINE 128
-
-static subtitle ogg_sub;
-//FILE* subout;
-
-static void demux_ogg_add_sub(ogg_stream_t *os, ogg_packet *pack)
-{
- int lcv;
- char *packet = pack->packet;
-
- if (pack->bytes < 4)
- return;
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "\ndemux_ogg_add_sub %02X %02X %02X '%s'\n",
- (unsigned char)packet[0],
- (unsigned char)packet[1],
- (unsigned char)packet[2],
- &packet[3]);
-
- if (((unsigned char)packet[0]) == 0x88) { // some subtitle text
- // Find data start
- double endpts = MP_NOPTS_VALUE;
- int32_t duration = 0;
- int16_t hdrlen = (*packet & PACKET_LEN_BITS01) >> 6, i;
-
- hdrlen |= (*packet & PACKET_LEN_BITS2) << 1;
- lcv = 1 + hdrlen;
- if (pack->bytes < lcv)
- return;
- for (i = hdrlen; i > 0; i--) {
- duration <<= 8;
- duration |= (unsigned char)packet[i];
- }
- if (hdrlen > 0 && duration > 0) {
- float pts;
-
- if (pack->granulepos == -1)
- pack->granulepos = os->lastpos + os->lastsize;
- pts = (float)pack->granulepos / (float)os->samplerate;
- endpts = 1.0 + pts + (float)duration / 1000.0;
- }
- sub_clear_text(&ogg_sub, MP_NOPTS_VALUE);
- sub_add_text(&ogg_sub, &packet[lcv], pack->bytes - lcv, endpts);
- }
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Ogg sub lines: %d first: '%s'\n",
- ogg_sub.lines, ogg_sub.text[0]);
-#ifdef CONFIG_ICONV
- subcp_recode(&ogg_sub);
-#endif
- vo_sub = &ogg_sub;
- vo_osd_changed(OSDTYPE_SUBTITLE);
-}
-
-
-// get the logical stream of the current page
-// fill os if non NULL and return the stream id
-static int demux_ogg_get_page_stream(ogg_demuxer_t *ogg_d,
- ogg_stream_state **os)
-{
- int id, s_no;
- ogg_page *page = &ogg_d->page;
-
- s_no = ogg_page_serialno(page);
-
- for (id = 0; id < ogg_d->num_sub; id++)
- if (s_no == ogg_d->subs[id].stream.serialno)
- break;
-
- if (id == ogg_d->num_sub) {
- // If we have only one vorbis stream allow the stream id to change
- // it's normal on radio stream (each song have an different id).
- // But we (or the codec?) should check that the samplerate, etc
- // doesn't change (for radio stream it's ok)
- if (ogg_d->num_sub == 1 && ogg_d->subs[0].vorbis) {
- ogg_stream_reset(&ogg_d->subs[0].stream);
- ogg_stream_init(&ogg_d->subs[0].stream, s_no);
- id = 0;
- } else
- return -1;
- }
-
- if (os)
- *os = &ogg_d->subs[id].stream;
-
- return id;
-}
-
-static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
- float *pts, bool *keyframe,
- int samplesize)
-{
- unsigned char *data = pack->packet;
-
- *pts = MP_NOPTS_VALUE;
- *keyframe = false;
-
- if (os->vorbis) {
- if (*pack->packet & PACKET_TYPE_HEADER) {
- os->hdr_packets++;
- } else {
- vorbis_info *vi;
- int32_t blocksize = 0;
-
- // When we dump the audio, there is no vi, but we don't care of timestamp in this case
- vi = os->vi_initialized ? &os->vi : NULL;
- if (vi)
- blocksize = vorbis_packet_blocksize(vi, pack) / samplesize;
- // Calculate the timestamp if the packet don't have any
- if (pack->granulepos == -1) {
- pack->granulepos = os->lastpos;
- if (os->lastsize > 0)
- pack->granulepos += os->lastsize;
- } else
- *keyframe = true;
- if (vi)
- *pts = pack->granulepos / (float)vi->rate;
- os->lastsize = blocksize;
- os->lastpos = pack->granulepos;
- }
- } else if (os->speex) {
- // whole packet (default)
-# ifdef CONFIG_OGGTHEORA
- } else if (os->theora) {
- /* we pass complete packets to theora, mustn't strip the header! */
- os->lastsize = 1;
-
- /* header packets begin on 1-bit: thus check (*data&0x80). We don't
- have theora_state st, until all header packets were passed to the
- decoder. */
- if (!pack->bytes || !(*data&0x80)) {
- int keyframe_granule_shift = _ilog(os->keyframe_frequency_force - 1);
- int64_t iframemask = (1 << keyframe_granule_shift) - 1;
-
- if (pack->granulepos >= 0) {
- os->lastpos = pack->granulepos >> keyframe_granule_shift;
- os->lastpos += pack->granulepos & iframemask;
- *keyframe = (pack->granulepos & iframemask) == 0;
- } else {
- os->lastpos++;
- }
- pack->granulepos = os->lastpos;
- *pts = (double)os->lastpos / (double)os->samplerate;
- }
-#endif /* CONFIG_OGGTHEORA */
- } else if (os->flac) {
- /* we pass complete packets to flac, mustn't strip the header! */
- if (os->flac == 2 && pack->packet[0] != 0xff)
- return NULL;
- } else {
- if (*pack->packet & PACKET_TYPE_HEADER) {
- os->hdr_packets++;
- } else {
- // Find data start
- int16_t hdrlen = (*pack->packet & PACKET_LEN_BITS01) >> 6;
-
- hdrlen |= (*pack->packet & PACKET_LEN_BITS2) << 1;
- data = pack->packet + 1 + hdrlen;
- // Calculate the timestamp
- if (pack->granulepos == -1)
- pack->granulepos = os->lastpos + (os->lastsize ? os->lastsize : 1);
- // If we already have a timestamp it can be a syncpoint
- if (*pack->packet & PACKET_IS_SYNCPOINT)
- *keyframe = true;
- *pts = pack->granulepos / os->samplerate;
- // Save the packet length and timestamp
- os->lastsize = 0;
- while (hdrlen) {
- os->lastsize <<= 8;
- os->lastsize |= pack->packet[hdrlen];
- hdrlen--;
- }
- os->lastpos = pack->granulepos;
- }
- }
- return data;
-}
-
-// check if clang has substring from comma separated langlist
-static int demux_ogg_check_lang(const char *clang, char **langlist)
-{
- if (!langlist)
- return 0;
- for (int i = 0; langlist[i]; i++)
- if (!strncasecmp(clang, langlist[i], strlen(langlist[i])))
- return 1;
- return 0;
-}
-
-/** \brief Change the current subtitle stream and return its ID.
-
- \param demuxer The demuxer whose subtitle stream will be changed.
- \param new_num The number of the new subtitle track. The number must be
- between 0 and ogg_d->n_text - 1.
-
- \returns The Ogg stream number ( = page serial number) of the newly selected
- track.
- */
-static int demux_ogg_sub_id(demuxer_t *demuxer, int index)
-{
- ogg_demuxer_t *ogg_d = demuxer->priv;
- return (index < 0) ? index : (index >= ogg_d->n_text) ? -1 : ogg_d->text_ids[index];
-}
-
-/** \brief Translate the ogg track number into the subtitle number.
- * \param demuxer The demuxer about whose subtitles we are inquiring.
- * \param id The ogg track number of the subtitle track.
- */
-static int demux_ogg_sub_reverse_id(demuxer_t *demuxer, int id)
-{
- ogg_demuxer_t *ogg_d = demuxer->priv;
- int i;
-
- for (i = 0; i < ogg_d->n_text; i++)
- if (ogg_d->text_ids[i] == id)
- return i;
- return -1;
-}
-
-/// Try to print out comments and also check for LANGUAGE= tag
-static void demux_ogg_check_comments(demuxer_t *d, ogg_stream_t *os,
- int id, vorbis_comment *vc)
-{
- const char *hdr, *val;
- char **cmt = vc->user_comments;
- int index, i;
- ogg_demuxer_t *ogg_d = d->priv;
- static const struct table {
- const char *ogg;
- const char *mp;
- } table[] = {
- { "ENCODED_USING", "Software" },
- { "ENCODER_URL", "Encoder URL" },
- { "TITLE", "Title" },
- { "ARTIST", "Artist" },
- { "COMMENT", "Comments" },
- { "DATE", "Creation Date" },
- { "GENRE", "Genre" },
- { "ALBUM", "Album" },
- { "TRACKNUMBER", "Track" },
- { NULL, NULL },
- };
-
- while (*cmt) {
- hdr = val = NULL;
- if (!strncasecmp(*cmt, "LANGUAGE=", 9)) {
- val = *cmt + 9;
- if (ogg_d->subs[id].text)
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n",
- ogg_d->subs[id].id, val);
- else if (id != d->video->id)
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n",
- ogg_d->subs[id].id, val);
- if (ogg_d->subs[id].text)
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] Language for -sid %d is '-slang \"%s\"'\n",
- ogg_d->subs[id].id, val);
- // copy this language name into the array
- index = demux_ogg_sub_reverse_id(d, id);
- if (index >= 0) {
- sh_sub_t *sh;
-
- // in case of malicious files with more than one lang per track:
- free(ogg_d->text_langs[index]);
- ogg_d->text_langs[index] = strdup(val);
- sh = d->s_streams[index];
- if (sh) {
- talloc_free(sh->lang);
- sh->lang = talloc_strdup(sh, val);
- }
- }
- // check for -slang if subs are uninitialized yet
- if (os->text && d->sub->id < 0
- && demux_ogg_check_lang(val, d->opts->sub_lang)) {
- d->sub->id = index;
- d->opts->sub_id = index;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n",
- id, val);
- }
- else
- hdr = "Language";
- }
- else {
- for (i = 0; table[i].ogg; i++) {
- if (!strncasecmp(*cmt, table[i].ogg, strlen(table[i].ogg)) &&
- (*cmt)[strlen(table[i].ogg)] == '=') {
- hdr = table[i].mp;
- val = *cmt + strlen(table[i].ogg) + 1;
- }
- }
- }
- if (hdr)
- demux_info_add(d, hdr, val);
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, " %s: %s\n", hdr, val);
- cmt++;
- }
-}
-
-/// Calculate the timestamp and add the packet to the demux stream
-// return 1 if the packet was added, 0 otherwise
-static int demux_ogg_add_packet(demux_stream_t *ds, ogg_stream_t *os,
- int id, ogg_packet *pack)
-{
- demuxer_t *d = ds->demuxer;
- int samplesize = 1;
-
- // If packet is an comment header then we try to get comments at first
- if (pack->bytes >= 7 && !memcmp(pack->packet, "\003vorbis", 7)) {
- vorbis_info vi;
- vorbis_comment vc;
-
- vorbis_info_init(&vi);
- vorbis_comment_init(&vc);
- vi.rate = 1L; // it's checked by vorbis_synthesis_headerin()
- if (vorbis_synthesis_headerin(&vi, &vc, pack) == 0) // if no errors
- demux_ogg_check_comments(d, os, id, &vc);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
- }
- if (os->text) {
- if (id == demux_ogg_sub_id(d, d->sub->id)) // don't want to add subtitles to the demuxer for now
- demux_ogg_add_sub(os, pack);
- return 0;
- }
- if (os->speex) {
- // discard first two packets, they contain the header and comment
- if (os->hdr_packets < 2) {
- os->hdr_packets++;
- return 0;
- }
- } else {
- // If packet is an header we jump it except for vorbis and theora
- // (PACKET_TYPE_HEADER bit doesn't even exist for theora ?!)
- // We jump nothing for FLAC. Ain't this great? Packet contents have to be
- // handled differently for each and every stream type. The joy! The joy!
- if (!os->flac && (*pack->packet & PACKET_TYPE_HEADER) &&
- (ds != d->audio || ((sh_audio_t*)ds->sh)->format != FOURCC_VORBIS || os->hdr_packets >= NUM_VORBIS_HDR_PACKETS ) &&
- (ds != d->video || (((sh_video_t*)ds->sh)->format != FOURCC_THEORA)))
- return 0;
- }
-
- // For vorbis packet the packet is the data, for other codec we must jump
- // the header
- if (ds == d->audio && ((sh_audio_t*)ds->sh)->format == FOURCC_VORBIS) {
- samplesize = ((sh_audio_t *)ds->sh)->samplesize;
- }
- bool keyframe;
- float pts;
- unsigned char *data;
- data = demux_ogg_read_packet(os, pack, &pts, &keyframe, samplesize);
- if (!data)
- return 0;
-
- /// Clear subtitles if necessary (for broken files)
- if (sub_clear_text(&ogg_sub, pts)) {
- vo_sub = &ogg_sub;
- vo_osd_changed(OSDTYPE_SUBTITLE);
- }
- /// Send the packet
- struct demux_packet *dp;
- dp = new_demux_packet(pack->bytes - (data - pack->packet));
- memcpy(dp->buffer, data, pack->bytes - (data - pack->packet));
- dp->pts = pts;
- dp->keyframe = keyframe;
- ds_add_packet(ds, dp);
- mp_msg(MSGT_DEMUX, MSGL_DBG2,
- "New dp: %p ds=%p pts=%5.3f len=%d keyframe=%d \n",
- dp, ds, pts, dp->len, keyframe);
- return 1;
-}
-
-/// if -forceidx build a table of all syncpoints to make seeking easier
-/// otherwise try to get at least the final_granulepos
-static void demux_ogg_scan_stream(demuxer_t *demuxer)
-{
- ogg_demuxer_t *ogg_d = demuxer->priv;
- stream_t *s = demuxer->stream;
- ogg_sync_state *sync = &ogg_d->sync;
- ogg_page *page = &ogg_d->page;
- ogg_stream_state *oss;
- ogg_stream_t *os;
- ogg_packet op;
- int np, sid, p, samplesize = 1;
- off_t pos, last_pos;
-
- pos = last_pos = demuxer->movi_start;
-
- // Reset the stream
- stream_seek(s, demuxer->movi_start);
- ogg_sync_reset(sync);
-
- // Get the serial number of the stream we use
- if (demuxer->video->id >= 0) {
- sid = demuxer->video->id;
- } else if (demuxer->audio->id >= 0) {
- sid = demuxer->audio->id;
- if (((sh_audio_t*)demuxer->audio->sh)->format == FOURCC_VORBIS)
- samplesize = ((sh_audio_t*)demuxer->audio->sh)->samplesize;
- } else
- return;
- os = &ogg_d->subs[sid];
- oss = &os->stream;
-
- while (1) {
- np = ogg_sync_pageseek(sync, page);
- if (np < 0) { // We had to skip some bytes
- if (index_mode == 2)
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "Bad page sync while building syncpoints table (%d)\n",
- -np);
- pos += -np;
- continue;
- }
- if (np <= 0) { // We need more data
- char *buf = ogg_sync_buffer(sync, BLOCK_SIZE);
- int len = stream_read(s, buf, BLOCK_SIZE);
-
- if (len == 0 && s->eof)
- break;
- ogg_sync_wrote(sync, len);
- continue;
- }
- // The page is ready
- //ogg_sync_pageout(sync, page);
- if (ogg_page_serialno(page) != os->stream.serialno) { // It isn't a page from the stream we want
- pos += np;
- continue;
- }
- if (ogg_stream_pagein(oss, page) != 0) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Pagein error ????\n");
- pos += np;
- continue;
- }
- p = 0;
- while (ogg_stream_packetout(oss, &op) == 1) {
- float pts;
- bool keyframe;
-
- demux_ogg_read_packet(os, &op, &pts, &keyframe, samplesize);
- if (op.granulepos >= 0) {
- ogg_d->final_granulepos = op.granulepos;
- if (ogg_d->initial_granulepos == MP_NOPTS_VALUE && keyframe) {
- ogg_d->initial_granulepos = op.granulepos;
- if (index_mode != 2 && ogg_d->pos < demuxer->movi_end - 2 * 270000) {
- //the 270000 are just a wild guess
- stream_seek(s, FFMAX(ogg_d->pos, demuxer->movi_end - 270000));
- ogg_sync_reset(sync);
- continue;
- }
- }
- }
- if (index_mode == 2 && (keyframe || (os->vorbis && op.granulepos >= 0))) {
- if (ogg_d->num_syncpoint > SIZE_MAX / sizeof(ogg_syncpoint_t) - 1)
- break;
- ogg_d->syncpoints = realloc_struct(ogg_d->syncpoints, (ogg_d->num_syncpoint + 1), sizeof(ogg_syncpoint_t));
- ogg_d->syncpoints[ogg_d->num_syncpoint].granulepos = op.granulepos;
- ogg_d->syncpoints[ogg_d->num_syncpoint].page_pos = (ogg_page_continued(page) && p == 0) ? last_pos : pos;
- ogg_d->num_syncpoint++;
- }
- p++;
- }
- if (p > 1 || (p == 1 && !ogg_page_continued(page)))
- last_pos = pos;
- pos += np;
- if (index_mode == 2)
- mp_msg(MSGT_DEMUX, MSGL_INFO, "Building syncpoint table %d%%\r",
- (int)(pos * 100 / s->end_pos));
- }
-
- if (index_mode == 2) {
- mp_msg(MSGT_DEMUX, MSGL_INFO, "\n");
- mp_msg(MSGT_DEMUX, MSGL_V,
- "Ogg syncpoints table builed: %d syncpoints\n",
- ogg_d->num_syncpoint);
- }
-
- mp_msg(MSGT_DEMUX, MSGL_V, "Ogg stream length (granulepos): %"PRId64"\n",
- ogg_d->final_granulepos);
-
- stream_reset(s);
- stream_seek(s, demuxer->movi_start);
- ogg_sync_reset(sync);
- for (np = 0; np < ogg_d->num_sub; np++) {
- ogg_stream_reset(&ogg_d->subs[np].stream);
- ogg_d->subs[np].lastpos = ogg_d->subs[np].lastsize = ogg_d->subs[np].hdr_packets = 0;
- }
-
- // Get the first page
- while (1) {
- np = ogg_sync_pageout(sync, page);
- if (np <= 0) { // We need more data
- char *buf = ogg_sync_buffer(sync, BLOCK_SIZE);
- int len = stream_read(s, buf, BLOCK_SIZE);
-
- if (len == 0 && s->eof) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "EOF while trying to get the first page !!!!\n");
- break;
- }
- ogg_sync_wrote(sync, len);
- continue;
- }
- demux_ogg_get_page_stream(ogg_d, &oss);
- ogg_stream_pagein(oss, page);
- break;
- }
-}
-
-static void fixup_vorbis_wf(sh_audio_t *sh, ogg_demuxer_t *od)
-{
- int i, offset;
- int ris, init_error = 0;
- ogg_packet op[3];
- unsigned char *buf[3];
- unsigned char *ptr;
- unsigned int len;
- ogg_stream_t *os = &od->subs[sh->ds->id];
- vorbis_comment vc;
-
- vorbis_info_init(&os->vi);
- vorbis_comment_init(&vc);
- for (i = 0; i < 3; i++) {
- op[i].bytes = ds_get_packet(sh->ds, &(op[i].packet));
- mp_msg(MSGT_DEMUX, MSGL_V, "fixup_vorbis_wf: i=%d, size=%ld\n", i, op[i].bytes);
- if (op[i].bytes < 0) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i);
- return;
- }
- buf[i] = malloc(op[i].bytes);
- if (!buf[i])
- return;
- memcpy(buf[i], op[i].packet, op[i].bytes);
-
- op[i].b_o_s = (i == 0);
- ris = vorbis_synthesis_headerin(&os->vi, &vc, &op[i]);
- if (ris < 0) {
- init_error = 1;
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DEMUX_OGG: header n. %d broken! len=%ld, code: %d\n", i, op[i].bytes, ris);
- }
- }
- vorbis_comment_clear(&vc);
- if (!init_error)
- os->vi_initialized = 1;
-
- len = op[0].bytes + op[1].bytes + op[2].bytes;
- sh->wf = calloc(1, sizeof(*sh->wf) + len + len / 255 + 64);
- ptr = (unsigned char*)(sh->wf + 1);
-
- ptr[0] = 2;
- offset = 1;
- offset += store_ughvlc(&ptr[offset], op[0].bytes);
- mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, offset after 1st len = %u\n", offset);
- offset += store_ughvlc(&ptr[offset], op[1].bytes);
- mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, offset after 2nd len = %u\n", offset);
- for (i = 0; i < 3; i++) {
- mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, i=%d, bytes: %ld, offset: %u\n", i, op[i].bytes, offset);
- memcpy(&ptr[offset], buf[i], op[i].bytes);
- offset += op[i].bytes;
- }
- sh->wf->cbSize = offset;
- mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, extradata size: %d\n", sh->wf->cbSize);
- sh->wf = realloc(sh->wf, sizeof(*sh->wf) + sh->wf->cbSize);
-
- if (op[0].bytes >= 29) {
- unsigned int br;
- int nombr, minbr, maxbr;
-
- ptr = buf[0];
- sh->channels = ptr[11];
- sh->samplerate = sh->wf->nSamplesPerSec = AV_RL32(&ptr[12]);
- maxbr = AV_RL32(&ptr[16]); //max
- nombr = AV_RL32(&ptr[20]); //nominal
- minbr = AV_RL32(&ptr[24]); //minimum
-
- if (maxbr == -1)
- maxbr = 0;
- if (nombr == -1)
- nombr = 0;
- if (minbr == -1)
- minbr = 0;
-
- br = maxbr / 8;
- if (!br)
- br = nombr / 8;
- if (!br)
- br = minbr / 8;
- sh->wf->nAvgBytesPerSec = br;
- sh->wf->wBitsPerSample = 16;
- sh->samplesize = (sh->wf->wBitsPerSample + 7) / 8;
-
- mp_msg(MSGT_DEMUX, MSGL_V,
- "demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n",
- sh->channels, sh->samplerate, sh->wf->nAvgBytesPerSec,
- maxbr, nombr, minbr);
- }
- free(buf[2]);
- free(buf[1]);
- free(buf[0]);
-}
-
-/// Open an ogg physical stream
-// Not static because it's used also in demuxer_avi.c
-int demux_ogg_open(demuxer_t *demuxer)
-{
- ogg_demuxer_t *ogg_d;
- stream_t *s;
- char *buf;
- int np, s_no, n_audio = 0, n_video = 0;
- int audio_id = -1, video_id = -1, text_id = -1;
- ogg_sync_state *sync;
- ogg_page *page;
- ogg_packet pack;
- sh_audio_t *sh_a;
- sh_video_t *sh_v;
-
-#ifdef CONFIG_ICONV
- subcp_open(NULL);
-#endif
-
- s = demuxer->stream;
-
- demuxer->priv = ogg_d = calloc(1, sizeof(*ogg_d));
- sync = &ogg_d->sync;
- page = &ogg_d->page;
-
- ogg_sync_init(sync);
-
- while (1) {
- /// Try to get a page
- ogg_d->pos += ogg_d->last_size;
- np = ogg_sync_pageseek(sync, page);
- /// Error
- if (np < 0) {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Ogg demuxer : Bad page sync\n");
- goto err_out;
- }
- /// Need some more data
- if (np == 0) {
- int len;
-
- buf = ogg_sync_buffer(sync, BLOCK_SIZE);
- len = stream_read(s, buf, BLOCK_SIZE);
- if (len == 0 && s->eof) {
- goto err_out;
- }
- ogg_sync_wrote(sync, len);
- continue;
- }
- ogg_d->last_size = np;
- // We got one page now
-
- if (!ogg_page_bos(page)) { // It's not a beginning page
- // Header parsing end here, we need to get the page otherwise it will be lost
- int id = demux_ogg_get_page_stream(ogg_d, NULL);
- if (id >= 0)
- ogg_stream_pagein(&ogg_d->subs[id].stream, page);
- else
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "Ogg : Warning found none bos page from unknown stream %d\n",
- ogg_page_serialno(page));
- break;
- }
-
- /// Init the data structure needed for a logical stream
- ogg_d->subs = realloc_struct(ogg_d->subs, ogg_d->num_sub+1,
- sizeof(ogg_stream_t));
- memset(&ogg_d->subs[ogg_d->num_sub], 0, sizeof(ogg_stream_t));
- /// Get the stream serial number
- s_no = ogg_page_serialno(page);
- ogg_stream_init(&ogg_d->subs[ogg_d->num_sub].stream, s_no);
- mp_msg(MSGT_DEMUX, MSGL_DBG2,
- "Ogg : Found a stream with serial=%d\n", s_no);
- // Take the first page
- ogg_stream_pagein(&ogg_d->subs[ogg_d->num_sub].stream, page);
- // Get first packet of the page
- ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream, &pack);
-
- // Reset our vars
- sh_a = NULL;
- sh_v = NULL;
-
- ogg_d->subs[ogg_d->num_sub].ogg_d = ogg_d;
-
- // Check for Vorbis
- if (pack.bytes >= 7 && !strncmp(&pack.packet[1], "vorbis", 6)) {
- sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio);
- sh_a->format = FOURCC_VORBIS;
- ogg_d->subs[ogg_d->num_sub].vorbis = 1;
- ogg_d->subs[ogg_d->num_sub].id = n_audio;
- n_audio++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: audio (Vorbis), -aid %d\n",
- ogg_d->num_sub, n_audio - 1);
- } else if (pack.bytes >= 80 && !strncmp(pack.packet, "Speex", 5)) {
- sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio);
- sh_a->wf = calloc(1, sizeof(*sh_a->wf) + pack.bytes);
- sh_a->format = FOURCC_SPEEX;
- sh_a->samplerate = sh_a->wf->nSamplesPerSec = AV_RL32(&pack.packet[36]);
- sh_a->channels = sh_a->wf->nChannels = AV_RL32(&pack.packet[48]);
- sh_a->wf->wFormatTag = sh_a->format;
- sh_a->wf->nAvgBytesPerSec = AV_RL32(&pack.packet[52]);
- sh_a->wf->nBlockAlign = 0;
- sh_a->wf->wBitsPerSample = 16;
- sh_a->samplesize = 2;
- sh_a->wf->cbSize = pack.bytes;
- memcpy(&sh_a->wf[1], pack.packet, pack.bytes);
-
- ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate;
- ogg_d->subs[ogg_d->num_sub].speex = 1;
- ogg_d->subs[ogg_d->num_sub].id = n_audio;
- n_audio++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: audio (Speex), -aid %d\n",
- ogg_d->num_sub, n_audio - 1);
-
- // check for Theora
-#ifdef CONFIG_OGGTHEORA
- } else if (pack.bytes >= 7 && !strncmp (&pack.packet[1], "theora", 6)) {
- int errorCode = 0;
- theora_info inf;
- theora_comment cc;
-
- theora_info_init (&inf);
- theora_comment_init (&cc);
-
- errorCode = theora_decode_header (&inf, &cc, &pack);
- if (errorCode) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "Theora header parsing failed: %i \n", errorCode);
- } else {
- sh_v = new_sh_video_vid(demuxer, ogg_d->num_sub, n_video);
-
- sh_v->bih = calloc(1, sizeof(*sh_v->bih));
- sh_v->bih->biSize = sizeof(*sh_v->bih);
- sh_v->bih->biCompression = sh_v->format = FOURCC_THEORA;
- sh_v->fps = ((double)inf.fps_numerator) / (double)inf.fps_denominator;
- sh_v->frametime = ((double)inf.fps_denominator) / (double)inf.fps_numerator;
- sh_v->disp_w = sh_v->bih->biWidth = inf.frame_width;
- sh_v->disp_h = sh_v->bih->biHeight = inf.frame_height;
- sh_v->bih->biBitCount = 24;
- sh_v->bih->biPlanes = 3;
- sh_v->bih->biSizeImage = ((sh_v->bih->biBitCount / 8) * sh_v->bih->biWidth * sh_v->bih->biHeight);
- ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;
- ogg_d->subs[ogg_d->num_sub].theora = 1;
- ogg_d->subs[ogg_d->num_sub].keyframe_frequency_force = inf.keyframe_frequency_force;
- ogg_d->subs[ogg_d->num_sub].id = n_video;
- n_video++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
- ogg_d->num_sub,
- (int)inf.version_major,
- (int)inf.version_minor,
- (int)inf.version_subminor,
- n_video - 1);
- if (mp_msg_test(MSGT_HEADER, MSGL_V))
- print_video_header(sh_v->bih, MSGL_V);
- }
- theora_comment_clear(&cc);
- theora_info_clear(&inf);
-#endif /* CONFIG_OGGTHEORA */
- } else if (pack.bytes >= 4 && !strncmp (&pack.packet[0], "fLaC", 4)) {
- sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio);
- sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
- ogg_d->subs[ogg_d->num_sub].id = n_audio;
- n_audio++;
- ogg_d->subs[ogg_d->num_sub].flac = 1;
- sh_a->wf = NULL;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: audio (FLAC), -aid %d\n",
- ogg_d->num_sub, n_audio - 1);
- } else if (pack.bytes >= 51 && !strncmp(&pack.packet[1], "FLAC", 4)) {
- sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio);
- sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
- ogg_d->subs[ogg_d->num_sub].id = n_audio;
- n_audio++;
- ogg_d->subs[ogg_d->num_sub].flac = 2;
- sh_a->wf = calloc(1, sizeof(*sh_a->wf) + 34);
- sh_a->wf->wFormatTag = sh_a->format;
- sh_a->wf->cbSize = 34;
- memcpy(&sh_a->wf[1], &pack.packet[17], 34);
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: audio (FLAC, try 2), -aid %d\n",
- ogg_d->num_sub, n_audio - 1);
-
- /// Check for old header
- } else if (pack.bytes >= 142 &&
- !strncmp(&pack.packet[1], "Direct Show Samples embedded in Ogg", 35)) {
-
- // Old video header
- if (AV_RL32(pack.packet + 96) == 0x05589f80 && pack.bytes >= 184) {
- sh_v = new_sh_video_vid(demuxer, ogg_d->num_sub, n_video);
- sh_v->bih = calloc(1, sizeof(*sh_v->bih));
- sh_v->bih->biSize = sizeof(*sh_v->bih);
- sh_v->bih->biCompression = sh_v->format = mmioFOURCC(pack.packet[68], pack.packet[69],
- pack.packet[70], pack.packet[71]);
- sh_v->frametime = AV_RL64(pack.packet + 164) * 0.0000001;
- sh_v->fps = 1 / sh_v->frametime;
- sh_v->disp_w = sh_v->bih->biWidth = AV_RL32(pack.packet + 176);
- sh_v->disp_h = sh_v->bih->biHeight = AV_RL32(pack.packet + 180);
- sh_v->bih->biBitCount = AV_RL16(pack.packet + 182);
- if (!sh_v->bih->biBitCount)
- sh_v->bih->biBitCount = 24; // hack, FIXME
- sh_v->bih->biPlanes = 1;
- sh_v->bih->biSizeImage = (sh_v->bih->biBitCount >> 3) * sh_v->bih->biWidth * sh_v->bih->biHeight;
-
- ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;
- ogg_d->subs[ogg_d->num_sub].id = n_video;
- n_video++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
- ogg_d->num_sub, pack.packet[68], pack.packet[69],
- pack.packet[70], pack.packet[71], n_video - 1);
- if (mp_msg_test(MSGT_HEADER, MSGL_V))
- print_video_header(sh_v->bih, MSGL_V);
- // Old audio header
- } else if (AV_RL32(pack.packet + 96) == 0x05589F81) {
- unsigned int extra_size;
-
- sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio);
- extra_size = AV_RL16(pack.packet + 140);
- sh_a->wf = calloc(1, sizeof(*sh_a->wf) + extra_size);
- sh_a->format = sh_a->wf->wFormatTag = AV_RL16(pack.packet + 124);
- sh_a->channels = sh_a->wf->nChannels = AV_RL16(pack.packet + 126);
- sh_a->samplerate = sh_a->wf->nSamplesPerSec = AV_RL32(pack.packet + 128);
- sh_a->wf->nAvgBytesPerSec = AV_RL32(pack.packet + 132);
- sh_a->wf->nBlockAlign = AV_RL16(pack.packet + 136);
- sh_a->wf->wBitsPerSample = AV_RL16(pack.packet + 138);
- sh_a->samplesize = (sh_a->wf->wBitsPerSample + 7) / 8;
- sh_a->wf->cbSize = extra_size;
- if (extra_size > 0)
- memcpy(sh_a->wf + 1,
- pack.packet + 142, extra_size);
-
- ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels;
- ogg_d->subs[ogg_d->num_sub].id = n_audio;
- n_audio++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
- ogg_d->num_sub, sh_a->format, n_audio - 1);
- if (mp_msg_test(MSGT_HEADER, MSGL_V))
- print_wave_header(sh_a->wf, MSGL_V);
- } else
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "Ogg stream %d contains an old header but the header type is unknown\n",
- ogg_d->num_sub);
-
- // Check new header
- } else if ((*pack.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER &&
- pack.bytes >= (int)sizeof(stream_header) + 1) {
- stream_header *st = (stream_header*)(pack.packet + 1);
- /// New video header
- if (strncmp(st->streamtype, "video", 5) == 0) {
- sh_v = new_sh_video_vid(demuxer, ogg_d->num_sub, n_video);
- sh_v->bih = calloc(1, sizeof(*sh_v->bih));
- sh_v->bih->biSize = sizeof(*sh_v->bih);
- sh_v->bih->biCompression = sh_v->format = mmioFOURCC(st->subtype[0], st->subtype[1],
- st->subtype[2], st->subtype[3]);
- sh_v->frametime = AV_RL64(&st->time_unit) * 0.0000001;
- sh_v->fps = 1.0 / sh_v->frametime;
- sh_v->bih->biBitCount = AV_RL16(&st->bits_per_sample);
- sh_v->disp_w = sh_v->bih->biWidth = AV_RL32(&st->sh.video.width);
- sh_v->disp_h = sh_v->bih->biHeight = AV_RL32(&st->sh.video.height);
- if (!sh_v->bih->biBitCount)
- sh_v->bih->biBitCount = 24; // hack, FIXME
- sh_v->bih->biPlanes = 1;
- sh_v->bih->biSizeImage = (sh_v->bih->biBitCount >> 3) * sh_v->bih->biWidth * sh_v->bih->biHeight;
-
- ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;
- ogg_d->subs[ogg_d->num_sub].id = n_video;
- n_video++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
- ogg_d->num_sub, st->subtype[0], st->subtype[1],
- st->subtype[2], st->subtype[3], n_video - 1);
- if (mp_msg_test(MSGT_HEADER, MSGL_V))
- print_video_header(sh_v->bih, MSGL_V);
- /// New audio header
- } else if (strncmp(st->streamtype, "audio", 5) == 0) {
- char buffer[5];
- unsigned int extra_size = AV_RL32(&st->size) - sizeof(stream_header);
- unsigned int extra_offset = 0;
-
- memcpy(buffer, st->subtype, 4);
- buffer[4] = '\0';
-
- /* Nasty workaround. stream_header.size seems not to contain the real
- size in all cases. There are four extra bytes that are unaccounted
- for in front of the real codec initialization data _at least_ for
- AAC. So far I've only seen those bytes being all 0, so we can
- just skip them here. */
- if ((strtol(buffer, NULL, 16) == 0xff) && (extra_size >= 4)) {
- extra_size -= 4;
- extra_offset = 4;
- }
-
- sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio);
- sh_a->wf = calloc(1, sizeof(*sh_a->wf) + extra_size);
- sh_a->format = sh_a->wf->wFormatTag = strtol(buffer, NULL, 16);
- sh_a->channels = sh_a->wf->nChannels = AV_RL16(&st->sh.audio.channels);
- sh_a->samplerate = sh_a->wf->nSamplesPerSec = AV_RL64(&st->samples_per_unit);
- sh_a->wf->nAvgBytesPerSec = AV_RL32(&st->sh.audio.avgbytespersec);
- sh_a->wf->nBlockAlign = AV_RL16(&st->sh.audio.blockalign);
- sh_a->wf->wBitsPerSample = AV_RL16(&st->bits_per_sample);
- sh_a->samplesize = (sh_a->wf->wBitsPerSample + 7) / 8;
- sh_a->wf->cbSize = extra_size;
- if (extra_size)
- memcpy(sh_a->wf+1,
- ((char *)(st+1))+extra_offset, extra_size);
-
- ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels;
- ogg_d->subs[ogg_d->num_sub].id = n_audio;
- n_audio++;
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
- ogg_d->num_sub, sh_a->format, n_audio - 1);
- if (mp_msg_test(MSGT_HEADER, MSGL_V))
- print_wave_header(sh_a->wf, MSGL_V);
-
- /// Check for text (subtitles) header
- } else if (strncmp(st->streamtype, "text", 4) == 0) {
- mp_msg(MSGT_DEMUX, MSGL_INFO,
- "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n",
- ogg_d->num_sub, ogg_d->n_text);
- ogg_d->subs[ogg_d->num_sub].samplerate = AV_RL64(&st->time_unit) / 10;
- ogg_d->subs[ogg_d->num_sub].text = 1;
- ogg_d->subs[ogg_d->num_sub].id = ogg_d->n_text;
- if (demuxer->sub->id == ogg_d->n_text)
- text_id = ogg_d->num_sub;
- new_sh_sub(demuxer, ogg_d->n_text);
- ogg_d->n_text++;
- ogg_d->text_ids = realloc_struct(ogg_d->text_ids, ogg_d->n_text, sizeof(*ogg_d->text_ids));
- ogg_d->text_ids[ogg_d->n_text - 1] = ogg_d->num_sub;
- ogg_d->text_langs = realloc_struct(ogg_d->text_langs, ogg_d->n_text, sizeof(*ogg_d->text_langs));
- ogg_d->text_langs[ogg_d->n_text - 1] = NULL;
- //// Unknown header type
- } else
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "Ogg stream %d has a header marker but is of an unknown type\n",
- ogg_d->num_sub);
- /// Unknown (invalid ?) header
- } else
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "Ogg stream %d is of an unknown type\n",
- ogg_d->num_sub);
-
- if (sh_a || sh_v) {
- demux_stream_t *ds = NULL;
- if (sh_a) {
- // If the audio stream is not defined we took the first one
- if (demuxer->audio->id == -1) {
- demuxer->audio->id = n_audio - 1;
- //if (sh_a->wf) print_wave_header(sh_a->wf, MSGL_INFO);
- }
- /// Is it the stream we want
- if (demuxer->audio->id == n_audio - 1) {
- demuxer->audio->sh = sh_a;
- sh_a->ds = demuxer->audio;
- ds = demuxer->audio;
- audio_id = ogg_d->num_sub;
- }
- }
- if (sh_v) {
- /// Also for video
- if (demuxer->video->id == -1) {
- demuxer->video->id = n_video - 1;
- //if (sh_v->bih) print_video_header(sh_v->bih, MSGL_INFO);
- }
- if (demuxer->video->id == n_video - 1) {
- demuxer->video->sh = sh_v;
- sh_v->ds = demuxer->video;
- ds = demuxer->video;
- video_id = ogg_d->num_sub;
- }
- }
- /// Add the header packets if the stream isn't seekable
- if (ds && !s->end_pos) {
- /// Finish the page, otherwise packets will be lost
- do {
- demux_ogg_add_packet(ds, &ogg_d->subs[ogg_d->num_sub],
- ogg_d->num_sub, &pack);
- } while (ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream, &pack) == 1);
- }
- }
- ogg_d->num_sub++;
- }
-
- if (!n_video && !n_audio) {
- goto err_out;
- }
-
- if (!n_video || video_id < 0)
- demuxer->video->id = -2;
- else
- demuxer->video->id = video_id;
- if (!n_audio || audio_id < 0)
- demuxer->audio->id = -2;
- else
- demuxer->audio->id = audio_id;
- /* Disable the subs only if there are no text streams at all.
- Otherwise the stream to display might be chosen later when the comment
- packet is encountered and the user used -slang instead of -sid. */
- if (!ogg_d->n_text)
- demuxer->sub->id = -2;
- else if (text_id >= 0) {
- demuxer->sub->id = text_id;
- mp_msg(MSGT_DEMUX, MSGL_V,
- "Ogg demuxer: Displaying subtitle stream id %d\n", text_id);
- }
-
- ogg_d->final_granulepos = 0;
- ogg_d->initial_granulepos = MP_NOPTS_VALUE;
- if (!s->end_pos) {
- demuxer->seekable = 0;
- } else {
- demuxer->movi_start = s->start_pos; // Needed for XCD (Ogg written in MODE2)
- demuxer->movi_end = s->end_pos;
- demuxer->seekable = 1;
- demux_ogg_scan_stream(demuxer);
- }
- if (ogg_d->initial_granulepos == MP_NOPTS_VALUE)
- ogg_d->initial_granulepos = 0;
- ogg_d->duration = ogg_d->final_granulepos - ogg_d->initial_granulepos;
-
- mp_msg(MSGT_DEMUX, MSGL_V,
- "Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",
- n_audio, n_audio > 1 ? "s" : "",
- n_video, n_video > 1 ? "s" : "",
- ogg_d->n_text, ogg_d->n_text > 1 ? "s" : "");
-
- sh_a = demuxer->audio->sh;
- if (sh_a && sh_a->format == FOURCC_VORBIS)
- fixup_vorbis_wf(sh_a, ogg_d);
-
- return DEMUXER_TYPE_OGG;
-
-err_out:
- return 0;
-}
-
-static int demux_ogg_fill_buffer(demuxer_t *d, demux_stream_t *dsds)
-{
- ogg_demuxer_t *ogg_d;
- stream_t *s;
- demux_stream_t *ds;
- ogg_sync_state *sync;
- ogg_stream_state *os;
- ogg_page *page;
- ogg_packet pack;
- int np = 0, id=0;
-
- s = d->stream;
- ogg_d = d->priv;
- sync = &ogg_d->sync;
- page = &ogg_d->page;
-
- /// Find the stream we are working on
- if ((id = demux_ogg_get_page_stream(ogg_d, &os)) < 0) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Ogg demuxer : can't get current stream\n");
- return 0;
- }
-
- while (1) {
- np = 0;
- ds = NULL;
- /// Try to get some packet from the current page
- while ((np = ogg_stream_packetout(os, &pack)) != 1) {
- /// No packet we go the next page
- if (np == 0) {
- while (1) {
- int pa, len;
- char *buf;
-
- ogg_d->pos += ogg_d->last_size;
- /// Get the next page from the physical stream
- while ((pa = ogg_sync_pageseek(sync, page)) <= 0) {
- /// Error : we skip some bytes
- if (pa < 0) {
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "Ogg : Page out not synced, we skip some bytes\n");
- ogg_d->pos -= pa;
- continue;
- }
- /// We need more data
- buf = ogg_sync_buffer(sync, BLOCK_SIZE);
- len = stream_read(s, buf, BLOCK_SIZE);
- if (len == 0 && s->eof) {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Ogg : Stream EOF !!!!\n");
- return 0;
- }
- ogg_sync_wrote(sync, len);
- } /// Page loop
- ogg_d->last_size = pa;
- /// Find the page's logical stream
- if ((id = demux_ogg_get_page_stream(ogg_d, &os)) < 0) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "Ogg demuxer error : we met an unknown stream\n");
- return 0;
- }
- /// Take the page
- if (ogg_stream_pagein(os, page) == 0)
- break;
- /// Page was invalid => retry
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "Ogg demuxer : got invalid page !!!!!\n");
- ogg_d->pos += ogg_d->last_size;
- }
- } else /// Packet was corrupted
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- "Ogg : bad packet in stream %d\n", id);
- } /// Packet loop
-
- /// Is the actual logical stream in use ?
- if (id == d->audio->id)
- ds = d->audio;
- else if (id == d->video->id)
- ds = d->video;
- else if (ogg_d->subs[id].text)
- ds = d->sub;
-
- if (ds) {
- if (!demux_ogg_add_packet(ds, &ogg_d->subs[id], id, &pack))
- continue; /// Unuseful packet, get another
- d->filepos = ogg_d->pos;
- return 1;
- }
- } /// while (1)
-}
-
-/// For avi with Ogg audio stream we have to create an ogg demuxer for this
-// stream, then we join the avi and ogg demuxer with a demuxers demuxer
-demuxer_t *init_avi_with_ogg(demuxer_t *demuxer)
-{
- struct MPOpts *opts = demuxer->opts;
- demuxer_t *od;
- ogg_demuxer_t *ogg_d;
- stream_t *s;
- uint32_t hdrsizes[3];
- demux_packet_t *dp;
- sh_audio_t *sh_audio = demuxer->audio->sh;
- int np;
- uint8_t *extradata = (uint8_t *)(sh_audio->wf + 1);
- int i;
- unsigned char *p = NULL, *buf;
- int plen;
-
- /// Check that the cbSize is big enough for the following reads
- if (sh_audio->wf->cbSize < 22 + 3 * 4) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "AVI Ogg : Initial audio header is too small !!!!!\n");
- goto fallback;
- }
- /// Get the size of the 3 header packet
- extradata += 22;
- for (i = 0; i < 3; i++) {
- hdrsizes[i] = AV_RL32(extradata);
- extradata += 4;
- }
- // printf("\n!!!!!! hdr sizes: %d %d %d \n", hdrsizes[0], hdrsizes[1], hdrsizes[2]);
-
- /// Check the size
- if (sh_audio->wf->cbSize < 22 + 3 * 4 + hdrsizes[0] + hdrsizes[1] + hdrsizes[2]) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "AVI Ogg : Audio header is too small !!!!!\n");
- goto fallback;
- }
-
- // Build the ogg demuxer private datas
- ogg_d = calloc(1, sizeof(*ogg_d));
- ogg_d->num_sub = 1;
- ogg_d->subs = malloc(sizeof(*ogg_d->subs));
- ogg_d->subs[0].vorbis = 1;
-
- // Init the ogg physical stream
- ogg_sync_init(&ogg_d->sync);
-
- // Get the first page of the stream : we assume there only 1 logical stream
- while ((np = ogg_sync_pageout(&ogg_d->sync, &ogg_d->page)) <= 0 ) {
- if (np < 0) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "AVI Ogg error : Can't init using first stream packets\n");
- free(ogg_d);
- goto fallback;
- }
- // Add some data
- plen = ds_get_packet(demuxer->audio, &p);
- buf = ogg_sync_buffer(&ogg_d->sync, plen);
- memcpy(buf, p, plen);
- ogg_sync_wrote(&ogg_d->sync, plen);
- }
- // Init the logical stream
- mp_msg(MSGT_DEMUX, MSGL_DBG2,
- "AVI Ogg found page with serial %d\n",
- ogg_page_serialno(&ogg_d->page));
- ogg_stream_init(&ogg_d->subs[0].stream, ogg_page_serialno(&ogg_d->page));
- // Write the page
- ogg_stream_pagein(&ogg_d->subs[0].stream, &ogg_d->page);
-
- // Create the ds_stream and the ogg demuxer
- s = new_ds_stream(demuxer->audio);
- od = new_demuxer(opts, s, DEMUXER_TYPE_OGG, 0, -2, -2, NULL);
-
- /// Add the header packets in the ogg demuxer audio stream
- for (i = 0; i < 3; i++) {
- dp = new_demux_packet(hdrsizes[i]);
- memcpy(dp->buffer, extradata, hdrsizes[i]);
- ds_add_packet(od->audio, dp);
- extradata += hdrsizes[i];
- }
-
- // Finish setting up the ogg demuxer
- od->priv = ogg_d;
- sh_audio = new_sh_audio(od, 0);
- od->audio->id = 0;
- od->video->id = -2;
- od->audio->sh = sh_audio;
- sh_audio->ds = od->audio;
- sh_audio->format = FOURCC_VORBIS;
- fixup_vorbis_wf(sh_audio, ogg_d);
-
- /// Return the joined demuxers
- return new_demuxers_demuxer(demuxer, od, demuxer);
-
-fallback:
- demuxer->audio->id = -2;
- return demuxer;
-
-}
-
-static void demux_ogg_seek(demuxer_t *demuxer, float rel_seek_secs,
- float audio_delay, int flags)
-{
- ogg_demuxer_t *ogg_d = demuxer->priv;
- ogg_sync_state *sync = &ogg_d->sync;
- ogg_page* page= &ogg_d->page;
- ogg_stream_state *oss;
- ogg_stream_t *os;
- demux_stream_t *ds;
- ogg_packet op;
- float rate;
- int i, sp, first = 1, precision = 1, do_seek = 1;
- vorbis_info *vi = NULL;
- int64_t gp = 0, old_gp;
- off_t pos, old_pos;
- int np;
- int is_gp_valid;
- float pts;
- bool is_keyframe;
- int samplesize = 1;
- ogg_int64_t granulepos_orig;
-
- if (demuxer->video->id >= 0) {
- ds = demuxer->video;
- rate = ogg_d->subs[ds->id].samplerate;
- } else {
- ds = demuxer->audio;
- os = &ogg_d->subs[ds->id];
- vi = &(os->vi);
- rate = (float)vi->rate;
- samplesize = ((sh_audio_t*)ds->sh)->samplesize;
- }
-
- os = &ogg_d->subs[ds->id];
- oss = &os->stream;
-
- old_gp = os->lastpos;
- old_pos = ogg_d->pos;
-
- //calculate the granulepos to seek to
- gp = flags & SEEK_ABSOLUTE ? ogg_d->initial_granulepos : os->lastpos;
- if (flags & SEEK_FACTOR) {
- if (ogg_d->duration > 0)
- gp += ogg_d->duration * rel_seek_secs;
- else
- gp += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * os->lastpos / ogg_d->pos;
- } else
- gp += rel_seek_secs * rate;
- if (gp < 0)
- gp = 0;
-
- //calculate the filepos to seek to
- if (ogg_d->syncpoints) {
- for (sp = 0; sp < ogg_d->num_syncpoint; sp++)
- if (ogg_d->syncpoints[sp].granulepos >= gp)
- break;
-
- if (sp >= ogg_d->num_syncpoint)
- return;
- if (sp > 0 && ogg_d->syncpoints[sp].granulepos - gp > gp - ogg_d->syncpoints[sp - 1].granulepos)
- sp--;
- if (ogg_d->syncpoints[sp].granulepos == os->lastpos) {
- if (sp > 0 && gp < os->lastpos)
- sp--;
- if (sp < ogg_d->num_syncpoint - 1 && gp > os->lastpos)
- sp++;
- }
- pos = ogg_d->syncpoints[sp].page_pos;
- precision = 0;
- } else {
- pos = flags & SEEK_ABSOLUTE ? 0 : ogg_d->pos;
- if (flags & SEEK_FACTOR)
- pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs;
- else {
- if (ogg_d->duration > 0) {
- pos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / (ogg_d->duration / rate);
- } else if (os->lastpos > 0) {
- pos += rel_seek_secs * ogg_d->pos / (os->lastpos / rate);
- }
- }
- if (pos < 0)
- pos = 0;
- if (pos > (demuxer->movi_end - demuxer->movi_start))
- pos = demuxer->movi_end - demuxer->movi_start;
- } // if (ogg_d->syncpoints)
-
- while (1) {
- if (do_seek) {
- stream_seek(demuxer->stream, pos+demuxer->movi_start);
- ogg_sync_reset(sync);
- for (i = 0; i < ogg_d->num_sub; i++) {
- ogg_stream_reset(&ogg_d->subs[i].stream);
- ogg_d->subs[i].lastpos = ogg_d->subs[i].lastsize = 0;
- }
- ogg_d->pos = pos;
- ogg_d->last_size = 0;
- /* we just guess that we reached correct granulepos, in case a
- subsequent search occurs before we read a valid granulepos */
- os->lastpos = gp;
- first = !(ogg_d->syncpoints);
- do_seek=0;
- }
- ogg_d->pos += ogg_d->last_size;
- ogg_d->last_size = 0;
- np = ogg_sync_pageseek(sync, page);
-
- if (np < 0)
- ogg_d->pos -= np;
- if (np <= 0) { // We need more data
- char *buf = ogg_sync_buffer(sync, BLOCK_SIZE);
- int len = stream_read(demuxer->stream, buf, BLOCK_SIZE);
-
- if (len == 0 && demuxer->stream->eof) {
- mp_msg(MSGT_DEMUX, MSGL_V, "EOF while trying to seek !!!!\n");
- return;
- }
- ogg_sync_wrote(sync, len);
- continue;
- }
- ogg_d->last_size = np;
- if (ogg_page_serialno(page) != oss->serialno)
- continue;
-
- if (ogg_stream_pagein(oss, page) != 0)
- continue;
-
- while (1) {
- np = ogg_stream_packetout(oss, &op);
- if (np < 0)
- continue;
- else if (np == 0)
- break;
- if (first) { /* Discard the first packet as it's probably broken,
- and we don't have any other means to decide whether it is
- complete or not. */
- first = 0;
- break;
- }
- is_gp_valid = (op.granulepos >= 0);
- granulepos_orig=op.granulepos;
- demux_ogg_read_packet(os, &op, &pts, &is_keyframe, samplesize);
- if (precision && is_gp_valid) {
- precision--;
- if (abs(gp - op.granulepos) > rate && (op.granulepos != old_gp)) {
- //prepare another seek because we are off by more than 1s
- pos += (gp - op.granulepos) * (pos - old_pos) / (op.granulepos - old_gp);
- if (pos < 0)
- pos = 0;
- if (pos < demuxer->movi_end - demuxer->movi_start) {
- do_seek=1;
- break;
- }
- }
- }
- if (is_gp_valid && pos > 0 && old_gp > gp
- && 2 * (old_gp - op.granulepos) < old_gp - gp) {
- /* prepare another seek because looking for a syncpoint
- destroyed the backward search */
- pos = old_pos - 1.5 * (old_pos - pos);
- if (pos < 0)
- pos = 0;
- if (pos < demuxer->movi_end - demuxer->movi_start) {
- do_seek=1;
- break;
- }
- }
- if (!precision && (is_keyframe || os->vorbis || os->speex)) {
- if (sub_clear_text(&ogg_sub, MP_NOPTS_VALUE)) {
- vo_sub = &ogg_sub;
- vo_osd_changed(OSDTYPE_SUBTITLE);
- }
- op.granulepos=granulepos_orig;
- demux_ogg_add_packet(ds, os, ds->id, &op);
- return;
- }
- }
- }
-
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Can't find the good packet :(\n");
-}
-
-static void demux_close_ogg(demuxer_t *demuxer)
-{
- ogg_demuxer_t *ogg_d = demuxer->priv;
- ogg_stream_t *os = NULL;
- int i;
-
- if (!ogg_d)
- return;
-
-#ifdef CONFIG_ICONV
- subcp_close();
-#endif
-
- ogg_sync_clear(&ogg_d->sync);
- if (ogg_d->subs) {
- for (i = 0; i < ogg_d->num_sub; i++) {
- os = &ogg_d->subs[i];
- ogg_stream_clear(&os->stream);
- if (os->vi_initialized)
- vorbis_info_clear(&os->vi);
- }
- free(ogg_d->subs);
- }
- free(ogg_d->syncpoints);
- free(ogg_d->text_ids);
- if (ogg_d->text_langs) {
- for (i = 0; i < ogg_d->n_text; i++)
- free(ogg_d->text_langs[i]);
- free(ogg_d->text_langs);
- }
- free(ogg_d);
-}
-
-static int demux_ogg_control(demuxer_t *demuxer, int cmd, void *arg)
-{
- ogg_demuxer_t *ogg_d = demuxer->priv;
- ogg_stream_t *os;
- float rate;
-
- if (demuxer->video->id >= 0) {
- os = &ogg_d->subs[demuxer->video->id];
- rate = os->samplerate;
- } else {
- os = &ogg_d->subs[demuxer->audio->id];
- rate = os->vi.rate;
- }
-
- switch(cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (ogg_d->duration <= 0)
- return DEMUXER_CTRL_DONTKNOW;
- *(double *)arg = (double)(ogg_d->duration) / rate;
- return DEMUXER_CTRL_GUESS;
-
- case DEMUXER_CTRL_GET_PERCENT_POS:
- if (ogg_d->duration <= 0)
- return DEMUXER_CTRL_DONTKNOW;
- *(int *)arg = ((os->lastpos - ogg_d->initial_granulepos) * 100) / ogg_d->duration;
- return DEMUXER_CTRL_OK;
-
- default:
- return DEMUXER_CTRL_NOTIMPL;
- }
-}
-
-const demuxer_desc_t demuxer_desc_ogg = {
- "Ogg demuxer",
- "ogg",
- "Ogg",
- "?",
- "",
- DEMUXER_TYPE_OGG,
- 1, // safe autodetect
- demux_ogg_open,
- demux_ogg_fill_buffer,
- NULL,
- demux_close_ogg,
- demux_ogg_seek,
- demux_ogg_control
-};
diff --git a/libmpdemux/demux_ogg.h b/libmpdemux/demux_ogg.h
deleted file mode 100644
index 0bdc30b910..0000000000
--- a/libmpdemux/demux_ogg.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_DEMUX_OGG_H
-#define MPLAYER_DEMUX_OGG_H
-
-#include "demuxer.h"
-
-int demux_ogg_open(demuxer_t *demuxer);
-demuxer_t *init_avi_with_ogg(demuxer_t *demuxer);
-
-#endif /* MPLAYER_DEMUX_OGG_H */
diff --git a/libmpdemux/demux_pva.c b/libmpdemux/demux_pva.c
deleted file mode 100644
index 883641fbc8..0000000000
--- a/libmpdemux/demux_pva.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * demuxer for PVA files, such as the ones produced by software to manage
- * DVB boards like the Hauppauge WinTV DVBs
- * copyright (c) 2002 Matteo Giani
- *
- * Uses info from the PVA file specifications found at
- * http://www.technotrend.de/download/av_format_v1.pdf
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* WARNING: Quite a hack was required in order to get files by MultiDec
- * played back correctly. If it breaks anything else, just comment out
- * the #define below and it will not be compiled in. */
-#define DEMUX_PVA_MULTIDEC_HACK
-#define PVA_NEW_PREBYTES_CODE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-/*
- * #defines below taken from PVA spec (see URL above)
- */
-
-#define PVA_MAX_VIDEO_PACK_LEN 6*1024
-
-#define VIDEOSTREAM 0x01
-#define MAINAUDIOSTREAM 0x02
-
-typedef struct {
- off_t offset;
- long size;
- uint8_t type;
- uint8_t is_packet_start;
- float pts;
-} pva_payload_t;
-
-
-typedef struct {
- float last_audio_pts;
- float last_video_pts;
-#ifdef PVA_NEW_PREBYTES_CODE
- float video_pts_after_prebytes;
- long video_size_after_prebytes;
- uint8_t prebytes_delivered;
-#endif
- uint8_t just_synced;
- uint8_t synced_stream_id;
-} pva_priv_t;
-
-
-
-static int pva_sync(demuxer_t * demuxer)
-{
- uint8_t buffer[5]={0,0,0,0,0};
- int count;
- pva_priv_t * priv = (pva_priv_t *) demuxer->priv;
-
-
- /* This function is used to find the next nearest PVA packet start after a seek, since a PVA file
- * is not indexed.
- * The just_synced field is in the priv structure so that pva_get_payload knows pva_sync
- * has already read (part of) the PVA header. This way we can avoid to seek back and (hopefully)
- * be able to read from pipes and such.
- */
-
-
- for(count=0 ; count<PVA_MAX_VIDEO_PACK_LEN && !demuxer->stream->eof && !priv->just_synced ; count++)
- {
- buffer[0]=buffer[1];
- buffer[1]=buffer[2];
- buffer[2]=buffer[3];
- buffer[3]=buffer[4];
- buffer[4]=stream_read_char(demuxer->stream);
- /*
- * Check for a PVA packet beginning sequence: we check both the "AV" word at the
- * very beginning and the "0x55" reserved byte (which is unused and set to 0x55 by spec)
- */
- if(buffer[0]=='A' && buffer[1] == 'V' && buffer[4] == 0x55) priv->just_synced=1;
- //printf("demux_pva: pva_sync(): current offset= %ld\n",stream_tell(demuxer->stream));
- }
- if(priv->just_synced)
- {
- priv->synced_stream_id=buffer[2];
- return 1;
- }
- else
- {
- return 0;
- }
-}
-
-static int pva_check_file(demuxer_t * demuxer)
-{
- uint8_t buffer[5]={0,0,0,0,0};
- mp_msg(MSGT_DEMUX, MSGL_V, "Checking for PVA\n");
- stream_read(demuxer->stream,buffer,5);
- if(buffer[0]=='A' && buffer[1] == 'V' && buffer[4] == 0x55)
- {
- mp_msg(MSGT_DEMUX,MSGL_DBG2, "Success: PVA\n");
- return DEMUXER_TYPE_PVA;
- }
- else
- {
- mp_msg(MSGT_DEMUX,MSGL_DBG2, "Failed: PVA\n");
- return 0;
- }
-}
-
-static demuxer_t * demux_open_pva (demuxer_t * demuxer)
-{
- sh_video_t *sh_video = new_sh_video(demuxer,0);
- sh_audio_t *sh_audio = new_sh_audio(demuxer,0);
-
-
- pva_priv_t * priv;
-
- stream_reset(demuxer->stream);
- stream_seek(demuxer->stream,0);
-
-
-
- priv=malloc(sizeof(pva_priv_t));
-
- if(demuxer->stream->type!=STREAMTYPE_FILE) demuxer->seekable=0;
- else demuxer->seekable=1;
-
- demuxer->priv=priv;
- memset(demuxer->priv,0,sizeof(pva_priv_t));
-
- if(!pva_sync(demuxer))
- {
- mp_msg(MSGT_DEMUX,MSGL_ERR,"Not a PVA file.\n");
- return NULL;
- }
-
- //printf("priv->just_synced %s after initial sync!\n",priv->just_synced?"set":"UNSET");
-
- demuxer->video->sh=sh_video;
-
- //printf("demuxer->stream->end_pos= %d\n",demuxer->stream->end_pos);
-
-
- mp_msg(MSGT_DEMUXER,MSGL_INFO,"Opened PVA demuxer...\n");
-
- /*
- * Audio and Video codecs:
- * the PVA spec only allows MPEG2 video and MPEG layer II audio. No need to check the formats then.
- * Moreover, there would be no way to do that since the PVA stream format has no fields to describe
- * the used codecs.
- */
-
- sh_video->format=0x10000002;
- sh_video->ds=demuxer->video;
-
- /*
- printf("demuxer->video->id==%d\n",demuxer->video->id);
- printf("demuxer->audio->id==%d\n",demuxer->audio->id);
- */
-
- demuxer->audio->id = 0;
- demuxer->audio->sh=sh_audio;
- sh_audio->format=0x50;
- sh_audio->ds=demuxer->audio;
-
- demuxer->movi_start=0;
- demuxer->movi_end=demuxer->stream->end_pos;
-
- priv->last_video_pts=-1;
- priv->last_audio_pts=-1;
-
- return demuxer;
-}
-
-static int pva_get_payload(demuxer_t *d, pva_payload_t *payload)
-{
- uint8_t flags,pes_head_len;
- uint16_t pack_size;
- off_t pva_payload_start;
- unsigned char buffer[256];
-#ifndef PVA_NEW_PREBYTES_CODE
- demux_packet_t * dp; //hack to deliver the preBytes (see PVA doc)
-#endif
- pva_priv_t * priv;
-
-
- if(d==NULL)
- {
- mp_msg(MSGT_DEMUX,MSGL_ERR,"demux_pva: pva_get_payload got passed a NULL pointer!\n");
- return 0;
- }
-
- priv = (pva_priv_t *)d->priv;
- d->filepos=stream_tell(d->stream);
-
-
-
-
- if(d->stream->eof)
- {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: pva_get_payload() detected stream->eof!!!\n");
- return 0;
- }
-
- //printf("priv->just_synced %s\n",priv->just_synced?"SET":"UNSET");
-
-#ifdef PVA_NEW_PREBYTES_CODE
- if(priv->prebytes_delivered)
- /* The previous call to this fn has delivered the preBytes. Then we are already inside
- * the payload. Let's just deliver the video along with its right PTS, the one we stored
- * in the priv structure and was in the PVA header before the PreBytes.
- */
- {
- //printf("prebytes_delivered=1. Resetting.\n");
- payload->size = priv->video_size_after_prebytes;
- payload->pts = priv->video_pts_after_prebytes;
- payload->is_packet_start = 1;
- payload->offset = stream_tell(d->stream);
- payload->type = VIDEOSTREAM;
- priv->prebytes_delivered = 0;
- return 1;
- }
-#endif
- if(!priv->just_synced)
- {
- if(stream_read_word(d->stream) != (('A'<<8)|'V'))
- {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: pva_get_payload() missed a SyncWord at %"PRId64"!! Trying to sync...\n",(int64_t)stream_tell(d->stream));
- if(!pva_sync(d))
- {
- if (!d->stream->eof)
- {
- mp_msg(MSGT_DEMUX,MSGL_ERR,"demux_pva: couldn't sync! (broken file?)");
- }
- return 0;
- }
- }
- }
- if(priv->just_synced)
- {
- payload->type=priv->synced_stream_id;
- priv->just_synced=0;
- }
- else
- {
- payload->type=stream_read_char(d->stream);
- stream_skip(d->stream,2); //counter and reserved
- }
- flags=stream_read_char(d->stream);
- payload->is_packet_start=flags & 0x10;
- pack_size=stream_read_word(d->stream);
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_pva::pva_get_payload(): pack_size=%u field read at offset %"PRIu64"\n",pack_size,(int64_t)stream_tell(d->stream)-2);
- pva_payload_start=stream_tell(d->stream);
-
-
- /*
- * The code in the #ifdef directive below is a hack needed to get badly formatted PVA files
- * such as the ones written by MultiDec played back correctly.
- * Basically, it works like this: if the PVA packet does not signal a PES header, but the
- * payload looks like one, let's assume it IS one. It has worked for me up to now.
- * It can be disabled since it's quite an ugly hack and could potentially break things up
- * if the PVA audio payload happens to start with 0x000001 even without being a non signalled
- * PES header start.
- * Though it's quite unlikely, it potentially could (AFAIK).
- */
-#ifdef DEMUX_PVA_MULTIDEC_HACK
- if(payload->type==MAINAUDIOSTREAM)
- {
- stream_read(d->stream,buffer,3);
- if(buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x01 && !payload->is_packet_start)
- {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: suspecting non signaled audio PES packet start. Maybe file by MultiDec?\n");
- payload->is_packet_start=1;
- }
- stream_seek(d->stream,stream_tell(d->stream)-3);
- }
-#endif
-
-
- if(!payload->is_packet_start)
- {
- payload->offset=stream_tell(d->stream);
- payload->size=pack_size;
- }
- else
- { //here comes the good part...
- switch(payload->type)
- {
- case VIDEOSTREAM:
- payload->pts=(float)(stream_read_dword(d->stream))/90000;
- //printf("Video PTS: %f\n",payload->pts);
- if((flags&0x03)
-#ifdef PVA_NEW_PREBYTES_CODE
- && !priv->prebytes_delivered
-#endif
- )
- {
-#ifndef PVA_NEW_PREBYTES_CODE
- dp=new_demux_packet(flags&0x03);
- stream_read(d->stream,dp->buffer,flags & 0x03); //read PreBytes
- ds_add_packet(d->video,dp);
-#else
- //printf("Delivering prebytes. Setting prebytes_delivered.");
- payload->offset=stream_tell(d->stream);
- payload->size = flags & 0x03;
- priv->video_pts_after_prebytes = payload->pts;
- priv->video_size_after_prebytes = pack_size - 4 - (flags & 0x03);
- payload->pts=priv->last_video_pts;
- payload->is_packet_start=0;
- priv->prebytes_delivered=1;
- return 1;
-#endif
- }
-
-
- //now we are at real beginning of payload.
- payload->offset=stream_tell(d->stream);
- //size is pack_size minus PTS size minus PreBytes size.
- payload->size=pack_size - 4 - (flags & 0x03);
- break;
- case MAINAUDIOSTREAM:
- stream_skip(d->stream,3); //FIXME properly parse PES header.
- //printf("StreamID in audio PES header: 0x%2X\n",stream_read_char(d->stream));
- stream_skip(d->stream,4);
-
- buffer[255]=stream_read_char(d->stream);
- pes_head_len=stream_read_char(d->stream);
- stream_read(d->stream,buffer,pes_head_len);
- if(!(buffer[255]&0x80)) //PES header does not contain PTS.
- {
- mp_msg(MSGT_DEMUX,MSGL_V,"Audio PES packet does not contain PTS. (pes_head_len=%d)\n",pes_head_len);
- payload->pts=priv->last_audio_pts;
- break;
- }
- else //PES header DOES contain PTS
- {
- if((buffer[0] & 0xf0)!=0x20) // PTS badly formatted
- {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: expected audio PTS but badly formatted... (read 0x%02X). Falling back to previous PTS (hack).\n",buffer[0]);
- payload->pts=priv->last_audio_pts;
- // return 0;
- }
- else
- {
- uint64_t temp_pts;
-
- temp_pts=0LL;
- temp_pts|=((uint64_t)(buffer[0] & 0x0e) << 29);
- temp_pts|=buffer[1]<<22;
- temp_pts|=(buffer[2] & 0xfe) << 14;
- temp_pts|=buffer[3]<<7;
- temp_pts|=(buffer[4] & 0xfe) >> 1;
- /*
- * PTS parsing is hopefully finished.
- */
- payload->pts=(float)temp_pts/90000;
- }
- }
- payload->offset=stream_tell(d->stream);
- payload->size=pack_size-stream_tell(d->stream)+pva_payload_start;
- break;
- }
- }
- return 1;
-}
-
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_pva_fill_buffer (demuxer_t * demux, demux_stream_t *ds)
-{
- uint8_t done=0;
- demux_packet_t * dp;
- pva_priv_t * priv=demux->priv;
- pva_payload_t current_payload;
-
- while(!done)
- {
- if(!pva_get_payload(demux,&current_payload)) return 0;
- switch(current_payload.type)
- {
- case VIDEOSTREAM:
- if(demux->video->id==-1) demux->video->id=0;
- if(!current_payload.is_packet_start && priv->last_video_pts==-1)
- {
- /* We should only be here at the beginning of a stream, when we have
- * not yet encountered a valid Video PTS, or after a seek.
- * So, skip these starting packets in order not to deliver the
- * player a bogus PTS.
- */
- done=0;
- }
- else
- {
- /*
- * In every other condition, we are delivering the payload. Set this
- * so that the following code knows whether to skip it or read it.
- */
- done=1;
- }
- if(demux->video->id!=0) done=0;
- if(current_payload.is_packet_start)
- {
- priv->last_video_pts=current_payload.pts;
- //mp_msg(MSGT_DEMUXER,MSGL_DBG2,"demux_pva: Video PTS=%llu , delivered %f\n",current_payload.pts,priv->last_video_pts);
- }
- if(done)
- {
- dp=new_demux_packet(current_payload.size);
- dp->pts=priv->last_video_pts;
- stream_read(demux->stream,dp->buffer,current_payload.size);
- ds_add_packet(demux->video,dp);
- }
- else
- {
- //printf("Skipping %u video bytes\n",current_payload.size);
- stream_skip(demux->stream,current_payload.size);
- }
- break;
- case MAINAUDIOSTREAM:
- if(demux->audio->id==-1) demux->audio->id=0;
- if(!current_payload.is_packet_start && priv->last_audio_pts==-1)
- {
- /* Same as above for invalid video PTS, just for audio. */
- done=0;
- }
- else
- {
- done=1;
- }
- if(current_payload.is_packet_start)
- {
- priv->last_audio_pts=current_payload.pts;
- }
- if(demux->audio->id!=0) done=0;
- if(done)
- {
- dp=new_demux_packet(current_payload.size);
- dp->pts=priv->last_audio_pts;
- if(current_payload.offset != stream_tell(demux->stream))
- stream_seek(demux->stream,current_payload.offset);
- stream_read(demux->stream,dp->buffer,current_payload.size);
- ds_add_packet(demux->audio,dp);
- }
- else
- {
- stream_skip(demux->stream,current_payload.size);
- }
- break;
- }
- }
- return 1;
-}
-
-static void demux_seek_pva(demuxer_t * demuxer,float rel_seek_secs,float audio_delay,int flags)
-{
- int total_bitrate=0;
- off_t dest_offset;
- pva_priv_t * priv=demuxer->priv;
-
- total_bitrate=((sh_audio_t *)demuxer->audio->sh)->i_bps + ((sh_video_t *)demuxer->video->sh)->i_bps;
-
- /*
- * Compute absolute offset inside the stream. Approximate total bitrate with sum of bitrates
- * reported by the audio and video codecs. The seek is not accurate because, just like
- * with MPEG streams, the bitrate is not constant. Moreover, we do not take into account
- * the overhead caused by PVA and PES headers.
- * If the calculated absolute offset is negative, seek to the beginning of the file.
- */
-
- dest_offset=stream_tell(demuxer->stream)+rel_seek_secs*total_bitrate;
- if(dest_offset<0) dest_offset=0;
-
- stream_seek(demuxer->stream,dest_offset);
-
- if(!pva_sync(demuxer))
- {
- mp_msg(MSGT_DEMUX,MSGL_V,"demux_pva: Couldn't seek!\n");
- return;
- }
-
- /*
- * Reset the PTS info inside the pva_priv_t structure. This way we don't deliver
- * data with the wrong PTSs (the ones we had before seeking).
- *
- */
-
- priv->last_video_pts=-1;
- priv->last_audio_pts=-1;
-}
-
-
-
-static void demux_close_pva(demuxer_t * demuxer)
-{
- free(demuxer->priv);
- demuxer->priv = NULL;
-}
-
-
-const demuxer_desc_t demuxer_desc_pva = {
- "PVA demuxer",
- "pva",
- "PVA",
- "Matteo Giani",
- "streams from DVB cards",
- DEMUXER_TYPE_PVA,
- 0, // unsafe autodetect
- pva_check_file,
- demux_pva_fill_buffer,
- demux_open_pva,
- demux_close_pva,
- demux_seek_pva,
- NULL
-};
diff --git a/libmpdemux/demux_roq.c b/libmpdemux/demux_roq.c
deleted file mode 100644
index af9e4c5a8e..0000000000
--- a/libmpdemux/demux_roq.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * RoQ file demuxer
- * copyright (c) 2002 Mike Melanson
- * based on Dr. Tim Ferguson's RoQ document found at:
- * http://www.csse.monash.edu.au/~timf/videocodec.html
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-#include "libavutil/attributes.h"
-
-#define RoQ_INFO 0x1001
-#define RoQ_QUAD_CODEBOOK 0x1002
-#define RoQ_QUAD_VQ 0x1011
-#define RoQ_SOUND_MONO 0x1020
-#define RoQ_SOUND_STEREO 0x1021
-
-#define CHUNK_TYPE_AUDIO 0
-#define CHUNK_TYPE_VIDEO 1
-
-typedef struct roq_chunk_t
-{
- int chunk_type;
- off_t chunk_offset;
- int chunk_size;
-
- float video_chunk_number; // in the case of a video chunk
- int running_audio_sample_count; // for an audio chunk
-} roq_chunk_t;
-
-typedef struct roq_data_t
-{
- int total_chunks;
- int current_chunk;
- int total_video_chunks;
- int total_audio_sample_count;
- roq_chunk_t *chunks;
-} roq_data_t;
-
-// Check if a stream qualifies as a RoQ file based on the magic numbers
-// at the start of the file:
-// 84 10 FF FF FF FF xx xx
-static int roq_check_file(demuxer_t *demuxer)
-{
- if ((stream_read_dword(demuxer->stream) == 0x8410FFFF) &&
- ((stream_read_dword(demuxer->stream) & 0xFFFF0000) == 0xFFFF0000))
- return DEMUXER_TYPE_ROQ;
- else
- return 0;
-}
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_roq_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
-{
- sh_video_t *sh_video = demuxer->video->sh;
- roq_data_t *roq_data = (roq_data_t *)demuxer->priv;
- roq_chunk_t roq_chunk;
-
- if (roq_data->current_chunk >= roq_data->total_chunks)
- return 0;
-
- roq_chunk = roq_data->chunks[roq_data->current_chunk];
-
- // make sure we're at the right place in the stream and fetch the chunk
- stream_seek(demuxer->stream, roq_chunk.chunk_offset);
-
- if (roq_chunk.chunk_type == CHUNK_TYPE_AUDIO)
- ds_read_packet(demuxer->audio, demuxer->stream, roq_chunk.chunk_size,
- 0,
- roq_chunk.chunk_offset, 0);
- else
- ds_read_packet(demuxer->video, demuxer->stream, roq_chunk.chunk_size,
- roq_chunk.video_chunk_number / sh_video->fps,
- roq_chunk.chunk_offset, 0);
-
- roq_data->current_chunk++;
- return 1;
-}
-
-static demuxer_t* demux_open_roq(demuxer_t* demuxer)
-{
- sh_video_t *sh_video = NULL;
- sh_audio_t *sh_audio = NULL;
-
- roq_data_t *roq_data = malloc(sizeof(roq_data_t));
- int chunk_id;
- int chunk_size;
- int chunk_arg av_unused;
- int last_chunk_id = 0;
- int largest_audio_chunk = 0;
- int fps;
-
- roq_data->total_chunks = 0;
- roq_data->current_chunk = 0;
- roq_data->total_video_chunks = 0;
- roq_data->chunks = NULL;
-
- // position the stream and start traversing
- stream_seek(demuxer->stream, 6);
- fps = stream_read_word_le(demuxer->stream);
- while (!stream_eof(demuxer->stream))
- {
- chunk_id = stream_read_word_le(demuxer->stream);
- chunk_size = stream_read_dword_le(demuxer->stream);
- chunk_arg = stream_read_word_le(demuxer->stream);
-
- // this is the only useful header info in the file
- if (chunk_id == RoQ_INFO)
- {
- // there should only be one RoQ_INFO chunk per file
- if (sh_video)
- {
- mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Found more than one RoQ_INFO chunk\n");
- stream_skip(demuxer->stream, 8);
- }
- else
- {
- // this is a good opportunity to create a video stream header
- sh_video = new_sh_video(demuxer, 0);
- // make sure the demuxer knows about the new stream header
- demuxer->video->sh = sh_video;
- // make sure that the video demuxer stream header knows about its
- // parent video demuxer stream
- sh_video->ds = demuxer->video;
-
- sh_video->disp_w = stream_read_word_le(demuxer->stream);
- sh_video->disp_h = stream_read_word_le(demuxer->stream);
- stream_skip(demuxer->stream, 4);
-
- // custom fourcc for internal MPlayer use
- sh_video->format = mmioFOURCC('R', 'o', 'Q', 'V');
-
- // constant frame rate
- sh_video->fps = fps;
- sh_video->frametime = 1 / sh_video->fps;
- }
- }
- else if ((chunk_id == RoQ_SOUND_MONO) ||
- (chunk_id == RoQ_SOUND_STEREO))
- {
- // create the audio stream header if it hasn't been created it
- if (sh_audio == NULL)
- {
- // make the header first
- sh_audio = new_sh_audio(demuxer, 0);
- // make sure the demuxer knows about the new stream header
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- // make sure that the audio demuxer stream header knows about its
- // parent audio demuxer stream
- sh_audio->ds = demuxer->audio;
-
- // go through the bother of making a WAVEFORMATEX structure
- sh_audio->wf = malloc(sizeof(*sh_audio->wf));
-
- // custom fourcc for internal MPlayer use
- sh_audio->format = mmioFOURCC('R', 'o', 'Q', 'A');
- if (chunk_id == RoQ_SOUND_STEREO)
- sh_audio->wf->nChannels = 2;
- else
- sh_audio->wf->nChannels = 1;
- // always 22KHz, 16-bit
- sh_audio->wf->nSamplesPerSec = 22050;
- sh_audio->wf->wBitsPerSample = 16;
- }
-
- // index the chunk
- roq_data->chunks = realloc(roq_data->chunks,
- (roq_data->total_chunks + 1) * sizeof (roq_chunk_t));
- roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_AUDIO;
- roq_data->chunks[roq_data->total_chunks].chunk_offset =
- stream_tell(demuxer->stream) - 8;
- roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8;
- roq_data->chunks[roq_data->total_chunks].running_audio_sample_count =
- roq_data->total_audio_sample_count;
-
- // audio housekeeping
- if (chunk_size > largest_audio_chunk)
- largest_audio_chunk = chunk_size;
- roq_data->total_audio_sample_count +=
- (chunk_size / sh_audio->wf->nChannels);
-
- stream_skip(demuxer->stream, chunk_size);
- roq_data->total_chunks++;
- }
- else if ((chunk_id == RoQ_QUAD_CODEBOOK) ||
- ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id != RoQ_QUAD_CODEBOOK)))
- {
- // index a new chunk if it's a codebook or quad VQ not following a
- // codebook
- roq_data->chunks = realloc(roq_data->chunks,
- (roq_data->total_chunks + 1) * sizeof (roq_chunk_t));
- roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_VIDEO;
- roq_data->chunks[roq_data->total_chunks].chunk_offset =
- stream_tell(demuxer->stream) - 8;
- roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8;
- roq_data->chunks[roq_data->total_chunks].video_chunk_number =
- roq_data->total_video_chunks++;
-
- stream_skip(demuxer->stream, chunk_size);
- roq_data->total_chunks++;
- }
- else if ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id == RoQ_QUAD_CODEBOOK))
- {
- // if it's a quad VQ chunk following a codebook chunk, extend the last
- // chunk
- roq_data->chunks[roq_data->total_chunks - 1].chunk_size += (chunk_size + 8);
- stream_skip(demuxer->stream, chunk_size);
- }
- else if (!stream_eof(demuxer->stream))
- {
- mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown RoQ chunk ID: %04X\n", chunk_id);
- }
-
- last_chunk_id = chunk_id;
- }
-
- // minimum output buffer size = largest audio chunk * 2, since each byte
- // in the DPCM encoding effectively represents 1 16-bit sample
- // (store it in wf->nBlockAlign for the time being since init_audio() will
- // step on it anyway)
- if (sh_audio)
- sh_audio->wf->nBlockAlign = largest_audio_chunk * 2;
-
- roq_data->current_chunk = 0;
-
- demuxer->priv = roq_data;
-
- stream_reset(demuxer->stream);
-
- return demuxer;
-}
-
-static void demux_close_roq(demuxer_t* demuxer) {
- roq_data_t *roq_data = demuxer->priv;
-
- free(roq_data);
-}
-
-
-const demuxer_desc_t demuxer_desc_roq = {
- "RoQ demuxer",
- "roq",
- "ROQ",
- "Mike Melanson",
- "",
- DEMUXER_TYPE_ROQ,
- 0, // unsafe autodetect
- roq_check_file,
- demux_roq_fill_buffer,
- demux_open_roq,
- demux_close_roq,
- NULL,
- NULL
-};
diff --git a/libmpdemux/demux_smjpeg.c b/libmpdemux/demux_smjpeg.c
deleted file mode 100644
index 8dabc8a0e2..0000000000
--- a/libmpdemux/demux_smjpeg.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * SMJPEG file parser
- * copyright (c) 2002 Alex Beregszaszi
- * based on text by Arpi (SMJPEG-format.txt) and later on
- * http://www.lokigames.com/development/download/smjpeg/SMJPEG.txt
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h> /* strtok */
-
-#include "config.h"
-#include "mp_msg.h"
-#include "libavutil/attributes.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-static int smjpeg_check_file(demuxer_t* demuxer){
- int orig_pos = stream_tell(demuxer->stream);
- char buf[8];
- int version;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "Checking for SMJPEG\n");
-
- if (stream_read_word(demuxer->stream) == 0xA)
- {
- stream_read(demuxer->stream, buf, 6);
- buf[7] = 0;
-
- if (strncmp("SMJPEG", buf, 6)) {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Failed: SMJPEG\n");
- return 0;
- }
- }
- else
- return 0;
-
- version = stream_read_dword(demuxer->stream);
- if (version != 0)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Unknown version (%d) of SMJPEG. Please report!\n",
- version);
- return 0;
- }
-
- stream_seek(demuxer->stream, orig_pos);
-
- return DEMUXER_TYPE_SMJPEG;
-}
-
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_smjpeg_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
-{
- int dtype, dsize, dpts;
-
- demux->filepos = stream_tell(demux->stream);
-
- dtype = stream_read_dword_le(demux->stream);
- dpts = stream_read_dword(demux->stream);
- dsize = stream_read_dword(demux->stream);
-
- switch(dtype)
- {
- case mmioFOURCC('s','n','d','D'):
- /* fixme, but no decoder implemented yet */
- ds_read_packet(demux->audio, demux->stream, dsize,
- (float)dpts/1000.0, demux->filepos, 0);
- break;
- case mmioFOURCC('v','i','d','D'):
- ds_read_packet(demux->video, demux->stream, dsize,
- (float)dpts/1000.0, demux->filepos, 0);
- break;
- case mmioFOURCC('D','O','N','E'):
- return 1;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static demuxer_t* demux_open_smjpeg(demuxer_t* demuxer){
- sh_video_t* sh_video;
- sh_audio_t* sh_audio;
- unsigned int htype = 0, hleng av_unused;
- int i = 0;
-
- /* file header */
- stream_skip(demuxer->stream, 8); /* \x00\x0aSMJPEG */
- stream_skip(demuxer->stream, 4);
-
- mp_msg(MSGT_DEMUX, MSGL_INFO, "This clip is %d seconds\n",
- stream_read_dword(demuxer->stream));
-
- /* stream header */
- while (i < 3)
- {
- i++;
- htype = stream_read_dword_le(demuxer->stream);
- if (htype == mmioFOURCC('H','E','N','D'))
- break;
- hleng = (stream_read_word(demuxer->stream)<<16)|stream_read_word(demuxer->stream);
- switch(htype)
- {
- case mmioFOURCC('_','V','I','D'):
- sh_video = new_sh_video(demuxer, 0);
- demuxer->video->sh = sh_video;
- sh_video->ds = demuxer->video;
-
- sh_video->bih = calloc(1, sizeof(*sh_video->bih));
-
- stream_skip(demuxer->stream, 4); /* number of frames */
-// sh_video->fps = 24;
-// sh_video->frametime = 1.0f/sh_video->fps;
- sh_video->disp_w = stream_read_word(demuxer->stream);
- sh_video->disp_h = stream_read_word(demuxer->stream);
- sh_video->format = stream_read_dword_le(demuxer->stream);
-
- /* these are false values */
- sh_video->bih->biSize = 40;
- sh_video->bih->biWidth = sh_video->disp_w;
- sh_video->bih->biHeight = sh_video->disp_h;
- sh_video->bih->biPlanes = 3;
- sh_video->bih->biBitCount = 12;
- sh_video->bih->biCompression = sh_video->format;
- sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h;
- break;
- case mmioFOURCC('_','S','N','D'):
- sh_audio = new_sh_audio(demuxer, 0);
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- sh_audio->ds = demuxer->audio;
-
- sh_audio->wf = calloc(1, sizeof(*sh_audio->wf));
-
- sh_audio->samplerate = stream_read_word(demuxer->stream);
- sh_audio->wf->wBitsPerSample = stream_read_char(demuxer->stream);
- sh_audio->channels = stream_read_char(demuxer->stream);
- sh_audio->format = stream_read_dword_le(demuxer->stream);
- sh_audio->wf->wFormatTag = sh_audio->format;
- sh_audio->wf->nChannels = sh_audio->channels;
- sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
- sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels*
- sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8;
- sh_audio->wf->nBlockAlign = sh_audio->channels *2;
- sh_audio->wf->cbSize = 0;
- break;
- case mmioFOURCC('_','T','X','T'):
- stream_skip(demuxer->stream, stream_read_dword(demuxer->stream));
- break;
- }
- }
-
- demuxer->seekable = 0;
-
- return demuxer;
-}
-
-static void demux_close_smjpeg(demuxer_t *demuxer)
-{
- return;
-}
-
-
-const demuxer_desc_t demuxer_desc_smjpeg = {
- "smjpeg demuxer",
- "smjpeg",
- "SMJPEG",
- "Alex Beregszasi",
- "",
- DEMUXER_TYPE_SMJPEG,
- 1, // safe autodetect
- smjpeg_check_file,
- demux_smjpeg_fill_buffer,
- demux_open_smjpeg,
- demux_close_smjpeg,
- NULL,
- NULL
-};
diff --git a/libmpdemux/demux_ts.c b/libmpdemux/demux_ts.c
deleted file mode 100644
index dbf12b7456..0000000000
--- a/libmpdemux/demux_ts.c
+++ /dev/null
@@ -1,3533 +0,0 @@
-/*
- * Demultiplexer for MPEG2 Transport Streams.
- *
- * Written by Nico <nsabbi@libero.it>
- * Kind feedback is appreciated; 'sucks' and alike is not.
- * Originally based on demux_pva.c written by Matteo Giani and FFmpeg (libavformat) sources
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "options.h"
-
-#include "libmpcodecs/dec_audio.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "parse_es.h"
-#include "stheader.h"
-#include "ms_hdr.h"
-#include "mpeg_hdr.h"
-#include "demux_ts.h"
-
-#define TS_PH_PACKET_SIZE 192
-#define TS_FEC_PACKET_SIZE 204
-#define TS_PACKET_SIZE 188
-#define NB_PID_MAX 8192
-
-#define MAX_HEADER_SIZE 6 /* enough for PES header + length */
-#define MAX_CHECK_SIZE 65535
-#define NUM_CONSECUTIVE_TS_PACKETS 32
-#define NUM_CONSECUTIVE_AUDIO_PACKETS 348
-#define MAX_A52_FRAME_SIZE 3840
-
-#ifndef SIZE_MAX
-#define SIZE_MAX ((size_t)-1)
-#endif
-
-#define TYPE_AUDIO 1
-#define TYPE_VIDEO 2
-#define TYPE_SUB 3
-
-int ts_prog;
-int ts_keep_broken=0;
-off_t ts_probe = 0;
-int audio_substream_id = -1;
-
-typedef enum
-{
- UNKNOWN = -1,
- VIDEO_MPEG1 = 0x10000001,
- VIDEO_MPEG2 = 0x10000002,
- VIDEO_MPEG4 = 0x10000004,
- VIDEO_H264 = 0x10000005,
- VIDEO_AVC = mmioFOURCC('a', 'v', 'c', '1'),
- VIDEO_DIRAC = mmioFOURCC('d', 'r', 'a', 'c'),
- VIDEO_VC1 = mmioFOURCC('W', 'V', 'C', '1'),
- AUDIO_MP2 = 0x50,
- AUDIO_A52 = 0x2000,
- AUDIO_DTS = 0x2001,
- AUDIO_LPCM_BE = 0x10001,
- AUDIO_AAC = mmioFOURCC('M', 'P', '4', 'A'),
- AUDIO_AAC_LATM = mmioFOURCC('M', 'P', '4', 'L'),
- AUDIO_TRUEHD = mmioFOURCC('T', 'R', 'H', 'D'),
- AUDIO_S302M = mmioFOURCC('B', 'S', 'S', 'D'),
- SPU_DVD = 0x3000000,
- SPU_DVB = 0x3000001,
- SPU_TELETEXT = 0x3000002,
- SPU_PGS = 0x3000003,
- PES_PRIVATE1 = 0xBD00000,
- SL_PES_STREAM = 0xD000000,
- SL_SECTION = 0xD100000,
- MP4_OD = 0xD200000,
-} es_stream_type_t;
-
-typedef struct {
- uint8_t *buffer;
- uint16_t buffer_len;
-} ts_section_t;
-
-typedef struct {
- int size;
- unsigned char *start;
- uint16_t payload_size;
- es_stream_type_t type, subtype;
- double pts, last_pts;
- int pid;
- char lang[4];
- int last_cc; // last cc code (-1 if first packet)
- int is_synced;
- ts_section_t section;
- uint8_t *extradata;
- int extradata_alloc, extradata_len;
- struct {
- uint8_t au_start, au_end, last_au_end;
- } sl;
-} ES_stream_t;
-
-typedef struct {
- void *sh;
- int id;
- int type;
-} sh_av_t;
-
-typedef struct MpegTSContext {
- int packet_size; // raw packet size, including FEC if present e.g. 188 bytes
- ES_stream_t *pids[NB_PID_MAX];
- sh_av_t streams[NB_PID_MAX];
-} MpegTSContext;
-
-
-typedef struct {
- demux_stream_t *ds;
- demux_packet_t *pack;
- int offset, buffer_size;
-} av_fifo_t;
-
-#define MAX_EXTRADATA_SIZE 64*1024
-typedef struct {
- int32_t object_type; //aka codec used
- int32_t stream_type; //video, audio etc.
- uint8_t buf[MAX_EXTRADATA_SIZE];
- uint16_t buf_size;
- uint8_t szm1;
-} mp4_decoder_config_t;
-
-typedef struct {
- //flags
- uint8_t flags;
- uint8_t au_start;
- uint8_t au_end;
- uint8_t random_accesspoint;
- uint8_t random_accesspoint_only;
- uint8_t padding;
- uint8_t use_ts;
- uint8_t idle;
- uint8_t duration;
-
- uint32_t ts_resolution, ocr_resolution;
- uint8_t ts_len, ocr_len, au_len, instant_bitrate_len, degr_len, au_seqnum_len, packet_seqnum_len;
- uint32_t timescale;
- uint16_t au_duration, cts_duration;
- uint64_t ocr, dts, cts;
-} mp4_sl_config_t;
-
-typedef struct {
- uint16_t id;
- uint8_t flags;
- mp4_decoder_config_t decoder;
- mp4_sl_config_t sl;
-} mp4_es_descr_t;
-
-typedef struct {
- uint16_t id;
- uint8_t flags;
- mp4_es_descr_t *es;
- uint16_t es_cnt;
-} mp4_od_t;
-
-typedef struct {
- uint8_t skip;
- uint8_t table_id;
- uint8_t ssi;
- uint16_t section_length;
- uint16_t ts_id;
- uint8_t version_number;
- uint8_t curr_next;
- uint8_t section_number;
- uint8_t last_section_number;
- struct pat_progs_t {
- uint16_t id;
- uint16_t pmt_pid;
- } *progs;
- uint16_t progs_cnt;
- ts_section_t section;
-} pat_t;
-
-typedef struct {
- uint16_t progid;
- uint8_t skip;
- uint8_t table_id;
- uint8_t ssi;
- uint16_t section_length;
- uint8_t version_number;
- uint8_t curr_next;
- uint8_t section_number;
- uint8_t last_section_number;
- uint16_t PCR_PID;
- uint16_t prog_descr_length;
- ts_section_t section;
- uint16_t es_cnt;
- struct pmt_es_t {
- uint16_t pid;
- uint32_t type; //it's 8 bit long, but cast to the right type as FOURCC
- uint16_t descr_length;
- uint8_t format_descriptor[5];
- uint8_t lang[4];
- uint16_t mp4_es_id;
- } *es;
- mp4_od_t iod, *od;
- mp4_es_descr_t *mp4es;
- int od_cnt, mp4es_cnt;
-} pmt_t;
-
-typedef struct {
- uint64_t size;
- float duration;
- double first_pts;
- double last_pts;
-} TS_stream_info;
-
-typedef struct {
- MpegTSContext ts;
- int last_pid;
- av_fifo_t fifo[3]; //0 for audio, 1 for video, 2 for subs
- pat_t pat;
- pmt_t *pmt;
- uint16_t pmt_cnt;
- uint32_t prog;
- uint32_t vbitrate;
- int keep_broken;
- int last_aid;
- int last_vid;
- int last_sid;
- char packet[TS_FEC_PACKET_SIZE];
- TS_stream_info vstr, astr;
-} ts_priv_t;
-
-
-typedef struct {
- es_stream_type_t type;
- ts_section_t section;
-} TS_pids_t;
-
-
-static int IS_AUDIO(es_stream_type_t type)
-{
- switch (type) {
- case AUDIO_MP2:
- case AUDIO_A52:
- case AUDIO_LPCM_BE:
- case AUDIO_AAC:
- case AUDIO_AAC_LATM:
- case AUDIO_DTS:
- case AUDIO_TRUEHD:
- case AUDIO_S302M:
- return 1;
- }
- return 0;
-}
-
-static int IS_VIDEO(es_stream_type_t type)
-{
- switch (type) {
- case VIDEO_MPEG1:
- case VIDEO_MPEG2:
- case VIDEO_MPEG4:
- case VIDEO_H264:
- case VIDEO_AVC:
- case VIDEO_DIRAC:
- case VIDEO_VC1:
- return 1;
- }
- return 0;
-}
-
-static int IS_SUB(es_stream_type_t type)
-{
- switch (type) {
- case SPU_DVD:
- case SPU_DVB:
- case SPU_PGS:
- case SPU_TELETEXT:
- return 1;
- }
- return 0;
-}
-
-static int ts_parse(demuxer_t *demuxer, ES_stream_t *es, unsigned char *packet, int probe);
-
-static uint8_t get_packet_size(const unsigned char *buf, int size)
-{
- int i;
-
- if (size < (TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS))
- return 0;
-
- for(i=0; i<NUM_CONSECUTIVE_TS_PACKETS; i++)
- {
- if (buf[i * TS_PACKET_SIZE] != 0x47)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "GET_PACKET_SIZE, pos %d, char: %2x\n", i, buf[i * TS_PACKET_SIZE]);
- goto try_fec;
- }
- }
- return TS_PACKET_SIZE;
-
-try_fec:
- for(i=0; i<NUM_CONSECUTIVE_TS_PACKETS; i++)
- {
- if (buf[i * TS_FEC_PACKET_SIZE] != 0x47){
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "GET_PACKET_SIZE, pos %d, char: %2x\n", i, buf[i * TS_PACKET_SIZE]);
- goto try_philips;
- }
- }
- return TS_FEC_PACKET_SIZE;
-
- try_philips:
- for(i=0; i<NUM_CONSECUTIVE_TS_PACKETS; i++)
- {
- if (buf[i * TS_PH_PACKET_SIZE] != 0x47)
- return 0;
- }
- return TS_PH_PACKET_SIZE;
-}
-
-static int parse_avc_sps(uint8_t *buf, int len, int *w, int *h);
-static inline uint8_t *pid_lang_from_pmt(ts_priv_t *priv, int pid);
-
-static void ts_add_stream(demuxer_t * demuxer, ES_stream_t *es)
-{
- int i;
- ts_priv_t *priv = (ts_priv_t*) demuxer->priv;
-
- if(priv->ts.streams[es->pid].sh)
- return;
-
- if((IS_AUDIO(es->type) || IS_AUDIO(es->subtype)) && priv->last_aid+1 < MAX_A_STREAMS)
- {
- sh_audio_t *sh = new_sh_audio_aid(demuxer, priv->last_aid, es->pid);
- if(sh)
- {
- const char *lang = pid_lang_from_pmt(priv, es->pid);
- sh->needs_parsing = 1;
- sh->format = IS_AUDIO(es->type) ? es->type : es->subtype;
- sh->ds = demuxer->audio;
-
- priv->ts.streams[es->pid].id = priv->last_aid;
- priv->ts.streams[es->pid].sh = sh;
- priv->ts.streams[es->pid].type = TYPE_AUDIO;
- mp_msg(MSGT_DEMUX, MSGL_V, "\r\nADDED AUDIO PID %d, type: %x stream n. %d\r\n", es->pid, sh->format, priv->last_aid);
- if (lang && lang[0])
- mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_AID_%d_LANG=%s\n", es->pid, lang);
- priv->last_aid++;
- }
-
- if(es->extradata && es->extradata_len)
- {
- sh->wf = malloc(sizeof(*sh->wf) + es->extradata_len);
- sh->wf->cbSize = es->extradata_len;
- memcpy(sh->wf + 1, es->extradata, es->extradata_len);
- }
- }
-
- if((IS_VIDEO(es->type) || IS_VIDEO(es->subtype)) && priv->last_vid+1 < MAX_V_STREAMS)
- {
- sh_video_t *sh = new_sh_video_vid(demuxer, priv->last_vid, es->pid);
- if(sh)
- {
- sh->format = IS_VIDEO(es->type) ? es->type : es->subtype;
- sh->ds = demuxer->video;
-
- priv->ts.streams[es->pid].id = priv->last_vid;
- priv->ts.streams[es->pid].sh = sh;
- priv->ts.streams[es->pid].type = TYPE_VIDEO;
- mp_msg(MSGT_DEMUX, MSGL_V, "\r\nADDED VIDEO PID %d, type: %x stream n. %d\r\n", es->pid, sh->format, priv->last_vid);
- priv->last_vid++;
-
-
- if(sh->format == VIDEO_AVC && es->extradata && es->extradata_len)
- {
- int w = 0, h = 0;
- sh->bih = calloc(1, sizeof(*sh->bih) + es->extradata_len);
- sh->bih->biSize= sizeof(*sh->bih) + es->extradata_len;
- sh->bih->biCompression = sh->format;
- memcpy(sh->bih + 1, es->extradata, es->extradata_len);
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "EXTRADATA(%d BYTES): \n", es->extradata_len);
- for(i = 0;i < es->extradata_len; i++)
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "%02x ", (int) es->extradata[i]);
- mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\n");
- if(parse_avc_sps(es->extradata, es->extradata_len, &w, &h))
- {
- sh->bih->biWidth = w;
- sh->bih->biHeight = h;
- }
- }
- }
- }
-
- if(IS_SUB(es->type) && priv->last_sid+1 < MAX_S_STREAMS)
- {
- sh_sub_t *sh = new_sh_sub_sid_lang(demuxer, priv->last_sid, es->pid, pid_lang_from_pmt(priv, es->pid));
- if (sh) {
- switch (es->type) {
- case SPU_DVB:
- sh->type = 'b'; break;
- case SPU_DVD:
- sh->type = 'v'; break;
- case SPU_PGS:
- sh->type = 'p'; break;
- }
- priv->ts.streams[es->pid].id = priv->last_sid;
- priv->ts.streams[es->pid].sh = sh;
- priv->ts.streams[es->pid].type = TYPE_SUB;
- priv->last_sid++;
- }
- }
-}
-
-static int ts_check_file(demuxer_t * demuxer)
-{
- const int buf_size = (TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS);
- unsigned char buf[TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS], done = 0, *ptr;
- uint32_t _read, i, count = 0, is_ts;
- int cc[NB_PID_MAX], last_cc[NB_PID_MAX], pid, cc_ok, c, good, bad;
- uint8_t size = 0;
- off_t pos = 0;
- off_t init_pos;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "Checking for MPEG-TS...\n");
-
- init_pos = stream_tell(demuxer->stream);
- is_ts = 0;
- while(! done)
- {
- i = 1;
- c = 0;
-
- while(((c=stream_read_char(demuxer->stream)) != 0x47)
- && (c >= 0)
- && (i < MAX_CHECK_SIZE)
- && ! demuxer->stream->eof
- ) i++;
-
-
- if(c != 0x47)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "THIS DOESN'T LOOK LIKE AN MPEG-TS FILE!\n");
- is_ts = 0;
- done = 1;
- continue;
- }
-
- pos = stream_tell(demuxer->stream) - 1;
- buf[0] = c;
- _read = stream_read(demuxer->stream, &buf[1], buf_size-1);
-
- if(_read < buf_size-1)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "COULDN'T READ ENOUGH DATA, EXITING TS_CHECK\n");
- stream_reset(demuxer->stream);
- return 0;
- }
-
- size = get_packet_size(buf, buf_size);
- if(size)
- {
- done = 1;
- is_ts = 1;
- }
-
- if(pos - init_pos >= MAX_CHECK_SIZE)
- {
- done = 1;
- is_ts = 0;
- }
- }
-
- mp_msg(MSGT_DEMUX, MSGL_V, "TRIED UP TO POSITION %"PRIu64", FOUND %x, packet_size= %d, SEEMS A TS? %d\n", (uint64_t) pos, c, size, is_ts);
- stream_seek(demuxer->stream, pos);
-
- if(! is_ts)
- return 0;
-
- //LET'S CHECK continuity counters
- good = bad = 0;
- for(count = 0; count < NB_PID_MAX; count++)
- {
- cc[count] = last_cc[count] = -1;
- }
-
- for(count = 0; count < NUM_CONSECUTIVE_TS_PACKETS; count++)
- {
- ptr = &(buf[size * count]);
- pid = ((ptr[1] & 0x1f) << 8) | ptr[2];
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "BUF: %02x %02x %02x %02x, PID %d, SIZE: %d \n",
- ptr[0], ptr[1], ptr[2], ptr[3], pid, size);
-
- if((pid == 8191) || (pid < 16))
- continue;
-
- cc[pid] = (ptr[3] & 0xf);
- cc_ok = (last_cc[pid] < 0) || ((((last_cc[pid] + 1) & 0x0f) == cc[pid]));
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "PID %d, COMPARE CC %d AND LAST_CC %d\n", pid, cc[pid], last_cc[pid]);
- if(! cc_ok)
- //return 0;
- bad++;
- else
- good++;
-
- last_cc[pid] = cc[pid];
- }
-
- mp_msg(MSGT_DEMUX, MSGL_V, "GOOD CC: %d, BAD CC: %d\n", good, bad);
-
- if(good >= bad)
- return size;
- else
- return 0;
-}
-
-
-static inline int32_t progid_idx_in_pmt(ts_priv_t *priv, uint16_t progid)
-{
- int x;
-
- if(priv->pmt == NULL)
- return -1;
-
- for(x = 0; x < priv->pmt_cnt; x++)
- {
- if(priv->pmt[x].progid == progid)
- return x;
- }
-
- return -1;
-}
-
-
-static inline int32_t progid_for_pid(ts_priv_t *priv, int pid, int32_t req) //finds the first program listing a pid
-{
- int i, j;
- pmt_t *pmt;
-
-
- if(priv->pmt == NULL)
- return -1;
-
-
- for(i=0; i < priv->pmt_cnt; i++)
- {
- pmt = &(priv->pmt[i]);
-
- if(pmt->es == NULL)
- return -1;
-
- for(j = 0; j < pmt->es_cnt; j++)
- {
- if(pmt->es[j].pid == pid)
- {
- if((req == 0) || (req == pmt->progid))
- return pmt->progid;
- }
- }
-
- }
- return -1;
-}
-
-static inline int32_t prog_pcr_pid(ts_priv_t *priv, int progid)
-{
- int i;
-
- if(priv->pmt == NULL)
- return -1;
- for(i=0; i < priv->pmt_cnt; i++)
- {
- if(priv->pmt[i].progid == progid)
- return priv->pmt[i].PCR_PID;
- }
- return -1;
-}
-
-
-static inline int pid_match_lang(ts_priv_t *priv, uint16_t pid, char *lang)
-{
- uint16_t i, j;
- pmt_t *pmt;
-
- if(priv->pmt == NULL)
- return -1;
-
- for(i=0; i < priv->pmt_cnt; i++)
- {
- pmt = &(priv->pmt[i]);
-
- if(pmt->es == NULL)
- return -1;
-
- for(j = 0; j < pmt->es_cnt; j++)
- {
- if(pmt->es[j].pid != pid)
- continue;
-
- mp_msg(MSGT_DEMUXER, MSGL_V, "CMP LANG %s AND %s, pids: %d %d\n",pmt->es[j].lang, lang, pmt->es[j].pid, pid);
- if(strncmp(pmt->es[j].lang, lang, 3) == 0)
- {
- return 1;
- }
- }
-
- }
-
- return -1;
-}
-
-typedef struct {
- int32_t atype, vtype, stype; //types
- int32_t apid, vpid, spid; //stream ids
- char alang[4]; //languages
- uint16_t prog;
- off_t probe;
-} tsdemux_init_t;
-
-//second stage: returns the count of A52 syncwords found
-static int a52_check(char *buf, int len)
-{
- int cnt, frame_length = 0, ok, srate;
-
- cnt = ok = 0;
- if(len < 8)
- return 0;
-
- while(cnt < len - 7)
- {
- if(buf[cnt] == 0x0B && buf[cnt+1] == 0x77)
- {
- frame_length = mp_a52_framesize(&buf[cnt], &srate);
- if(frame_length>=7 && frame_length<=3840)
- {
- cnt += frame_length;
- ok++;
- }
- else
- cnt++;
- }
- else
- cnt++;
- }
-
- mp_msg(MSGT_DEMUXER, MSGL_V, "A52_CHECK(%d input bytes), found %d frame syncwords of %d bytes length\n", len, ok, frame_length);
- return ok;
-}
-
-
-static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
-{
- int video_found = 0, audio_found = 0, i, num_packets = 0, req_apid, req_vpid, req_spid;
- int is_audio, is_video, is_sub, has_tables;
- int32_t p, chosen_pid = 0;
- off_t pos=0, ret = 0, init_pos, end_pos;
- ES_stream_t es;
- unsigned char tmp[TS_FEC_PACKET_SIZE];
- ts_priv_t *priv = (ts_priv_t*) demuxer->priv;
- struct {
- char *buf;
- int pos;
- } pes_priv1[8192], *pptr;
- char *tmpbuf;
-
- priv->last_pid = 8192; //invalid pid
-
- req_apid = param->apid;
- req_vpid = param->vpid;
- req_spid = param->spid;
-
- has_tables = 0;
- memset(pes_priv1, 0, sizeof(pes_priv1));
- init_pos = stream_tell(demuxer->stream);
- mp_msg(MSGT_DEMUXER, MSGL_V, "PROBING UP TO %"PRIu64", PROG: %d\n", (uint64_t) param->probe, param->prog);
- end_pos = init_pos + (param->probe ? param->probe : TS_MAX_PROBE_SIZE);
- while(1)
- {
- pos = stream_tell(demuxer->stream);
- if(pos > end_pos || demuxer->stream->eof)
- break;
-
- if(ts_parse(demuxer, &es, tmp, 1))
- {
- //Non PES-aligned A52 audio may escape detection if PMT is not present;
- //in this case we try to find at least 3 A52 syncwords
- if((es.type == PES_PRIVATE1) && (! audio_found) && req_apid > -2)
- {
- pptr = &pes_priv1[es.pid];
- if(pptr->pos < 64*1024)
- {
- tmpbuf = realloc(pptr->buf, pptr->pos + es.size);
- if(tmpbuf != NULL)
- {
- pptr->buf = tmpbuf;
- memcpy(&(pptr->buf[ pptr->pos ]), es.start, es.size);
- pptr->pos += es.size;
- if(a52_check(pptr->buf, pptr->pos) > 2)
- {
- param->atype = AUDIO_A52;
- param->apid = es.pid;
- es.type = AUDIO_A52;
- }
- }
- }
- }
-
- is_audio = IS_AUDIO(es.type) || ((es.type==SL_PES_STREAM) && IS_AUDIO(es.subtype));
- is_video = IS_VIDEO(es.type) || ((es.type==SL_PES_STREAM) && IS_VIDEO(es.subtype));
- is_sub = IS_SUB(es.type);
-
-
- if((! is_audio) && (! is_video) && (! is_sub))
- continue;
- if(is_audio && req_apid==-2)
- continue;
-
- if(is_video)
- {
- chosen_pid = (req_vpid == es.pid);
- if((! chosen_pid) && (req_vpid > 0))
- continue;
- }
- else if(is_audio)
- {
- if(req_apid > 0)
- {
- chosen_pid = (req_apid == es.pid);
- if(! chosen_pid)
- continue;
- }
- else if(param->alang[0] > 0 && es.lang[0] > 0)
- {
- if(pid_match_lang(priv, es.pid, param->alang) == -1)
- continue;
-
- chosen_pid = 1;
- param->apid = req_apid = es.pid;
- }
- }
- else if(is_sub)
- {
- chosen_pid = (req_spid == es.pid);
- if((! chosen_pid) && (req_spid > 0))
- continue;
- }
-
- if(req_apid < 0 && (param->alang[0] == 0) && req_vpid < 0 && req_spid < 0)
- chosen_pid = 1;
-
- if((ret == 0) && chosen_pid)
- {
- ret = stream_tell(demuxer->stream);
- }
-
- p = progid_for_pid(priv, es.pid, param->prog);
- if(p != -1)
- {
- has_tables++;
- if(!param->prog && chosen_pid)
- param->prog = p;
- }
-
- if((param->prog > 0) && (param->prog != p))
- {
- if(audio_found)
- {
- if(is_video && (req_vpid == es.pid))
- {
- param->vtype = IS_VIDEO(es.type) ? es.type : es.subtype;
- param->vpid = es.pid;
- video_found = 1;
- break;
- }
- }
-
- if(video_found)
- {
- if(is_audio && (req_apid == es.pid))
- {
- param->atype = IS_AUDIO(es.type) ? es.type : es.subtype;
- param->apid = es.pid;
- audio_found = 1;
- break;
- }
- }
-
-
- continue;
- }
-
-
- mp_msg(MSGT_DEMUXER, MSGL_DBG2, "TYPE: %x, PID: %d, PROG FOUND: %d\n", es.type, es.pid, param->prog);
-
-
- if(is_video)
- {
- if((req_vpid == -1) || (req_vpid == es.pid))
- {
- param->vtype = IS_VIDEO(es.type) ? es.type : es.subtype;
- param->vpid = es.pid;
- video_found = 1;
- }
- }
-
-
- if(((req_vpid == -2) || (num_packets >= NUM_CONSECUTIVE_AUDIO_PACKETS)) && audio_found && !param->probe)
- {
- //novideo or we have at least 348 audio packets (64 KB) without video (TS with audio only)
- param->vtype = 0;
- break;
- }
-
- if(is_sub)
- {
- if((req_spid == -1) || (req_spid == es.pid))
- {
- param->stype = es.type;
- param->spid = es.pid;
- }
- }
-
- if(is_audio)
- {
- if((req_apid == -1) || (req_apid == es.pid))
- {
- param->atype = IS_AUDIO(es.type) ? es.type : es.subtype;
- param->apid = es.pid;
- audio_found = 1;
- }
- }
-
- if(audio_found && (param->apid == es.pid) && (! video_found))
- num_packets++;
-
- if((has_tables==0) && (video_found && audio_found) && (pos >= 1000000))
- break;
- }
- }
-
- for(i=0; i<8192; i++)
- {
- if(pes_priv1[i].buf != NULL)
- {
- free(pes_priv1[i].buf);
- pes_priv1[i].buf = NULL;
- pes_priv1[i].pos = 0;
- }
- }
-
- if(video_found)
- {
- if(param->vtype == VIDEO_MPEG1)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG1(pid=%d) ", param->vpid);
- else if(param->vtype == VIDEO_MPEG2)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG2(pid=%d) ", param->vpid);
- else if(param->vtype == VIDEO_MPEG4)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG4(pid=%d) ", param->vpid);
- else if(param->vtype == VIDEO_H264)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO H264(pid=%d) ", param->vpid);
- else if(param->vtype == VIDEO_VC1)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO VC1(pid=%d) ", param->vpid);
- else if(param->vtype == VIDEO_AVC)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO AVC(NAL-H264, pid=%d) ", param->vpid);
- }
- else
- {
- param->vtype = UNKNOWN;
- //WE DIDN'T MATCH ANY VIDEO STREAM
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO VIDEO! ");
- }
-
- if(param->atype == AUDIO_MP2)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MPA(pid=%d)", param->apid);
- else if(param->atype == AUDIO_A52)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO A52(pid=%d)", param->apid);
- else if(param->atype == AUDIO_DTS)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO DTS(pid=%d)", param->apid);
- else if(param->atype == AUDIO_LPCM_BE)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO LPCM(pid=%d)", param->apid);
- else if(param->atype == AUDIO_AAC)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO AAC(pid=%d)", param->apid);
- else if(param->atype == AUDIO_AAC_LATM)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO AAC LATM(pid=%d)", param->apid);
- else if(param->atype == AUDIO_TRUEHD)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO TRUEHD(pid=%d)", param->apid);
- else if(param->atype == AUDIO_S302M)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO S302M(pid=%d)", param->apid);
- else
- {
- audio_found = 0;
- param->atype = UNKNOWN;
- //WE DIDN'T MATCH ANY AUDIO STREAM, SO WE FORCE THE DEMUXER TO IGNORE AUDIO
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO AUDIO! (try increasing -tsprobe)");
- }
-
- if(IS_SUB(param->stype))
- mp_msg(MSGT_DEMUXER, MSGL_INFO, " SUB %s(pid=%d) ", (param->stype==SPU_DVD ? "DVD" : param->stype==SPU_DVB ? "DVB" : "Teletext"), param->spid);
- else
- {
- param->stype = UNKNOWN;
- mp_msg(MSGT_DEMUXER, MSGL_INFO, " NO SUBS (yet)! ");
- }
-
- if(video_found || audio_found)
- {
- if(!param->prog)
- {
- p = progid_for_pid(priv, video_found ? param->vpid : param->apid, 0);
- if(p != -1)
- param->prog = p;
- }
-
- if(demuxer->stream->eof && (ret == 0))
- ret = init_pos;
- mp_msg(MSGT_DEMUXER, MSGL_INFO, " PROGRAM N. %d\n", param->prog);
- }
- else
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "\n");
-
-
- for(i=0; i<NB_PID_MAX; i++)
- {
- if(priv->ts.pids[i] != NULL)
- {
- priv->ts.pids[i]->payload_size = 0;
- priv->ts.pids[i]->pts = priv->ts.pids[i]->last_pts = 0;
- priv->ts.pids[i]->last_cc = -1;
- priv->ts.pids[i]->is_synced = 0;
- }
- }
-
- return ret;
-}
-
-static int parse_avc_sps(uint8_t *buf, int len, int *w, int *h)
-{
- int sps, sps_len;
- unsigned char *ptr;
- mp_mpeg_header_t picture;
- if(len < 6)
- return 0;
- sps = buf[5] & 0x1f;
- if(!sps)
- return 0;
- sps_len = (buf[6] << 8) | buf[7];
- if(!sps_len || (sps_len > len - 8))
- return 0;
- ptr = &(buf[8]);
- picture.display_picture_width = picture.display_picture_height = 0;
- h264_parse_sps(&picture, ptr, len - 8);
- if(!picture.display_picture_width || !picture.display_picture_height)
- return 0;
- *w = picture.display_picture_width;
- *h = picture.display_picture_height;
- return 1;
-}
-
-static demuxer_t *demux_open_ts(demuxer_t * demuxer)
-{
- int i;
- uint8_t packet_size;
- sh_video_t *sh_video;
- sh_audio_t *sh_audio;
- off_t start_pos;
- tsdemux_init_t params;
- ts_priv_t * priv = demuxer->priv;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "DEMUX OPEN, AUDIO_ID: %d, VIDEO_ID: %d, SUBTITLE_ID: %d,\n",
- demuxer->audio->id, demuxer->video->id, demuxer->sub->id);
-
-
- demuxer->type= DEMUXER_TYPE_MPEG_TS;
-
-
- stream_reset(demuxer->stream);
-
- packet_size = ts_check_file(demuxer);
- if(!packet_size)
- return NULL;
-
- priv = calloc(1, sizeof(ts_priv_t));
- if(priv == NULL)
- {
- mp_msg(MSGT_DEMUX, MSGL_FATAL, "DEMUX_OPEN_TS, couldn't allocate enough memory for ts->priv, exit\n");
- return NULL;
- }
-
- for(i=0; i < NB_PID_MAX; i++)
- {
- priv->ts.pids[i] = NULL;
- priv->ts.streams[i].id = -3;
- }
- priv->pat.progs = NULL;
- priv->pat.progs_cnt = 0;
- priv->pat.section.buffer = NULL;
- priv->pat.section.buffer_len = 0;
-
- priv->pmt = NULL;
- priv->pmt_cnt = 0;
-
- priv->keep_broken = ts_keep_broken;
- priv->ts.packet_size = packet_size;
-
-
- demuxer->priv = priv;
- if(demuxer->stream->type != STREAMTYPE_FILE)
- demuxer->seekable = 1;
- else
- demuxer->seekable = 1;
-
-
- params.atype = params.vtype = params.stype = UNKNOWN;
- params.apid = demuxer->audio->id;
- params.vpid = demuxer->video->id;
- params.spid = demuxer->sub->id;
- params.prog = ts_prog;
- params.probe = ts_probe;
-
- if(demuxer->opts->audio_lang != NULL)
- {
- strncpy(params.alang, demuxer->opts->audio_lang[0], 3);
- params.alang[3] = 0;
- }
- else
- memset(params.alang, 0, 4);
-
- start_pos = ts_detect_streams(demuxer, &params);
-
- demuxer->sub->id = params.spid;
- priv->prog = params.prog;
-
- if(params.vtype != UNKNOWN)
- {
- ts_add_stream(demuxer, priv->ts.pids[params.vpid]);
- sh_video = priv->ts.streams[params.vpid].sh;
- demuxer->video->id = priv->ts.streams[params.vpid].id;
- sh_video->ds = demuxer->video;
- sh_video->format = params.vtype;
- demuxer->video->sh = sh_video;
- }
-
- if(params.atype != UNKNOWN)
- {
- ES_stream_t *es = priv->ts.pids[params.apid];
-
- if(!IS_AUDIO(es->type) && !IS_AUDIO(es->subtype) && IS_AUDIO(params.atype)) es->subtype = params.atype;
- ts_add_stream(demuxer, priv->ts.pids[params.apid]);
- sh_audio = priv->ts.streams[params.apid].sh;
- demuxer->audio->id = priv->ts.streams[params.apid].id;
- sh_audio->ds = demuxer->audio;
- sh_audio->format = params.atype;
- demuxer->audio->sh = sh_audio;
- }
-
-
- mp_msg(MSGT_DEMUXER,MSGL_V, "Opened TS demuxer, audio: %x(pid %d), video: %x(pid %d)...POS=%"PRIu64", PROBE=%"PRIu64"\n", params.atype, demuxer->audio->id, params.vtype, demuxer->video->id, (uint64_t) start_pos, ts_probe);
-
-
- start_pos = start_pos <= priv->ts.packet_size ?
- demuxer->stream->start_pos :
- start_pos - priv->ts.packet_size;
- demuxer->movi_start = start_pos;
- demuxer->reference_clock = MP_NOPTS_VALUE;
- stream_reset(demuxer->stream);
- stream_seek(demuxer->stream, start_pos); //IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES?
-
-
- priv->last_pid = 8192; //invalid pid
-
- for(i = 0; i < 3; i++)
- {
- priv->fifo[i].pack = NULL;
- priv->fifo[i].offset = 0;
- }
- priv->fifo[0].ds = demuxer->audio;
- priv->fifo[1].ds = demuxer->video;
- priv->fifo[2].ds = demuxer->sub;
-
- priv->fifo[0].buffer_size = 1536;
- priv->fifo[1].buffer_size = 32767;
- priv->fifo[2].buffer_size = 32767;
-
- priv->pat.section.buffer_len = 0;
- for(i = 0; i < priv->pmt_cnt; i++)
- priv->pmt[i].section.buffer_len = 0;
-
- demuxer->filepos = stream_tell(demuxer->stream);
- return demuxer;
-}
-
-static void demux_close_ts(demuxer_t * demuxer)
-{
- uint16_t i;
- ts_priv_t *priv = (ts_priv_t*) demuxer->priv;
-
- if(priv)
- {
- free(priv->pat.section.buffer);
- free(priv->pat.progs);
-
- if(priv->pmt)
- {
- for(i = 0; i < priv->pmt_cnt; i++)
- {
- free(priv->pmt[i].section.buffer);
- free(priv->pmt[i].es);
- }
- free(priv->pmt);
- }
- for (i = 0; i < NB_PID_MAX; i++)
- {
- free(priv->ts.pids[i]);
- priv->ts.pids[i] = NULL;
- }
- for (i = 0; i < 3; i++)
- {
- if (priv->fifo[i].pack)
- free_demux_packet(priv->fifo[i].pack);
- priv->fifo[i].pack = NULL;
- }
- free(priv);
- }
- demuxer->priv=NULL;
-}
-
-
-#define getbits mp_getbits
-
-static int mp4_parse_sl_packet(pmt_t *pmt, uint8_t *buf, uint16_t packet_len, int pid, ES_stream_t *pes_es)
-{
- int i, n, m, mp4_es_id = -1;
- uint64_t v = 0;
- uint32_t pl_size = 0;
- int deg_flag = 0;
- mp4_es_descr_t *es = NULL;
- mp4_sl_config_t *sl = NULL;
- uint8_t au_start = 0, au_end = 0, rap_flag = 0, ocr_flag = 0, padding = 0, padding_bits = 0, idle = 0;
-
- pes_es->is_synced = 0;
- mp_msg(MSGT_DEMUXER,MSGL_V, "mp4_parse_sl_packet, pid: %d, pmt: %pm, packet_len: %d\n", pid, pmt, packet_len);
- if(! pmt || !packet_len)
- return 0;
-
- for(i = 0; i < pmt->es_cnt; i++)
- {
- if(pmt->es[i].pid == pid)
- mp4_es_id = pmt->es[i].mp4_es_id;
- }
- if(mp4_es_id < 0)
- return -1;
-
- for(i = 0; i < pmt->mp4es_cnt; i++)
- {
- if(pmt->mp4es[i].id == mp4_es_id)
- es = &(pmt->mp4es[i]);
- }
- if(! es)
- return -1;
-
- pes_es->subtype = es->decoder.object_type;
-
- sl = &(es->sl);
- if(!sl)
- return -1;
-
- //now es is the complete es_descriptor of out mp4 ES stream
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "ID: %d, FLAGS: 0x%x, subtype: %x\n", es->id, sl->flags, pes_es->subtype);
-
- n = 0;
- if(sl->au_start)
- pes_es->sl.au_start = au_start = getbits(buf, n++, 1);
- else
- pes_es->sl.au_start = (pes_es->sl.last_au_end ? 1 : 0);
- if(sl->au_end)
- pes_es->sl.au_end = au_end = getbits(buf, n++, 1);
-
- if(!sl->au_start && !sl->au_end)
- {
- pes_es->sl.au_start = pes_es->sl.au_end = au_start = au_end = 1;
- }
- pes_es->sl.last_au_end = pes_es->sl.au_end;
-
-
- if(sl->ocr_len > 0)
- ocr_flag = getbits(buf, n++, 1);
- if(sl->idle)
- idle = getbits(buf, n++, 1);
- if(sl->padding)
- padding = getbits(buf, n++, 1);
- if(padding)
- {
- padding_bits = getbits(buf, n, 3);
- n += 3;
- }
-
- if(idle || (padding && !padding_bits))
- {
- pes_es->payload_size = 0;
- return -1;
- }
-
- //(! idle && (!padding || padding_bits != 0)) is true
- n += sl->packet_seqnum_len;
- if(sl->degr_len)
- deg_flag = getbits(buf, n++, 1);
- if(deg_flag)
- n += sl->degr_len;
-
- if(ocr_flag)
- {
- n += sl->ocr_len;
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "OCR: %d bits\n", sl->ocr_len);
- }
-
- if(packet_len * 8 <= n)
- return -1;
-
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "\nAU_START: %d, AU_END: %d\n", au_start, au_end);
- if(au_start)
- {
- int dts_flag = 0, cts_flag = 0, ib_flag = 0;
-
- if(sl->random_accesspoint)
- rap_flag = getbits(buf, n++, 1);
-
- //check commented because it seems it's rarely used, and we need this flag set in case of au_start
- //the decoder will eventually discard the payload if it can't decode it
- //if(rap_flag || sl->random_accesspoint_only)
- pes_es->is_synced = 1;
-
- n += sl->au_seqnum_len;
- if(packet_len * 8 <= n+8)
- return -1;
- if(sl->use_ts)
- {
- dts_flag = getbits(buf, n++, 1);
- cts_flag = getbits(buf, n++, 1);
- }
- if(sl->instant_bitrate_len)
- ib_flag = getbits(buf, n++, 1);
- if(packet_len * 8 <= n+8)
- return -1;
- if(dts_flag && (sl->ts_len > 0))
- {
- n += sl->ts_len;
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "DTS: %d bits\n", sl->ts_len);
- }
- if(packet_len * 8 <= n+8)
- return -1;
- if(cts_flag && (sl->ts_len > 0))
- {
- int i = 0, m;
-
- while(i < sl->ts_len)
- {
- m = FFMIN(8, sl->ts_len - i);
- v |= getbits(buf, n, m);
- if(sl->ts_len - i > 8)
- v <<= 8;
- i += m;
- n += m;
- if(packet_len * 8 <= n+8)
- return -1;
- }
-
- pes_es->pts = (double) v / (double) sl->ts_resolution;
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "CTS: %d bits, value: %"PRIu64"/%d = %.3f\n", sl->ts_len, v, sl->ts_resolution, pes_es->pts);
- }
-
-
- i = 0;
- pl_size = 0;
- while(i < sl->au_len)
- {
- m = FFMIN(8, sl->au_len - i);
- pl_size |= getbits(buf, n, m);
- if(sl->au_len - i > 8)
- pl_size <<= 8;
- i += m;
- n += m;
- if(packet_len * 8 <= n+8)
- return -1;
- }
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "AU_LEN: %u (%d bits)\n", pl_size, sl->au_len);
- if(ib_flag)
- n += sl->instant_bitrate_len;
- }
-
- m = (n+7)/8;
- if(0 < pl_size && pl_size < pes_es->payload_size)
- pes_es->payload_size = pl_size;
-
- mp_msg(MSGT_DEMUXER,MSGL_V, "mp4_parse_sl_packet, n=%d, m=%d, size from pes hdr: %u, sl hdr size: %u, RAP FLAGS: %d/%d\n",
- n, m, pes_es->payload_size, pl_size, (int) rap_flag, (int) sl->random_accesspoint_only);
-
- return m;
-}
-
-//this function parses the extension fields in the PES header and returns the substream_id, or -1 in case of errors
-static int parse_pes_extension_fields(unsigned char *p, int pkt_len)
-{
- int skip;
- unsigned char flags;
-
- if(!(p[7] & 0x1)) //no extension_field
- return -1;
- skip = 9;
- if(p[7] & 0x80)
- {
- skip += 5;
- if(p[7] & 0x40)
- skip += 5;
- }
- if(p[7] & 0x20) //escr_flag
- skip += 6;
- if(p[7] & 0x10) //es_rate_flag
- skip += 3;
- if(p[7] & 0x08)//dsm_trick_mode is unsupported, skip
- {
- skip = 0;//don't let's parse the extension fields
- }
- if(p[7] & 0x04) //additional_copy_info
- skip += 1;
- if(p[7] & 0x02) //pes_crc_flag
- skip += 2;
- if(skip >= pkt_len) //too few bytes
- return -1;
- flags = p[skip];
- skip++;
- if(flags & 0x80) //pes_private_data_flag
- skip += 16;
- if(skip >= pkt_len)
- return -1;
- if(flags & 0x40) //pack_header_field_flag
- {
- unsigned char l = p[skip];
- skip += l;
- }
- if(flags & 0x20) //program_packet_sequence_counter
- skip += 2;
- if(flags & 0x10) //p_std
- skip += 2;
- if(skip >= pkt_len)
- return -1;
- if(flags & 0x01) //finally the long desired pes_extension2
- {
- unsigned char l = p[skip]; //ext2 flag+len
- skip++;
- if((l == 0x81) && (skip < pkt_len))
- {
- int ssid = p[skip];
- mp_msg(MSGT_IDENTIFY, MSGL_V, "SUBSTREAM_ID=%d (0x%02X)\n", ssid, ssid);
- return ssid;
- }
- }
-
- return -1;
-}
-
-static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es, int32_t type_from_pmt, pmt_t *pmt, int pid)
-{
- unsigned char *p;
- uint32_t header_len;
- int64_t pts;
- uint32_t stream_id;
- uint32_t pkt_len, pes_is_aligned;
-
- //Here we are always at the start of a PES packet
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(%p, %d): \n", buf, (uint32_t) packet_len);
-
- if(packet_len == 0 || packet_len > 184)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2, BUFFER LEN IS TOO SMALL OR TOO BIG: %d EXIT\n", packet_len);
- return 0;
- }
-
- p = buf;
- pkt_len = packet_len;
-
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: HEADER %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
- if (p[0] || p[1] || (p[2] != 1))
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: error HEADER %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]);
- return 0 ;
- }
-
- packet_len -= 6;
- if(packet_len==0)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: packet too short: %d, exit\n", packet_len);
- return 0;
- }
-
- es->payload_size = (p[4] << 8 | p[5]);
- pes_is_aligned = (p[6] & 4);
-
- stream_id = p[3];
-
-
- if (p[7] & 0x80)
- { /* pts available */
- pts = (int64_t)(p[9] & 0x0E) << 29 ;
- pts |= p[10] << 22 ;
- pts |= (p[11] & 0xFE) << 14 ;
- pts |= p[12] << 7 ;
- pts |= (p[13] & 0xFE) >> 1 ;
-
- es->pts = pts / 90000.0;
- }
- else
- es->pts = 0.0;
-
-
- header_len = p[8];
-
-
- if (header_len + 9 > pkt_len) //9 are the bytes read up to the header_length field
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_ts: illegal value for PES_header_data_length (0x%02x)\n", header_len);
- return 0;
- }
-
- if(stream_id==0xfd)
- {
- int ssid = parse_pes_extension_fields(p, pkt_len);
- if((audio_substream_id!=-1) && (ssid != audio_substream_id))
- return 0;
- if(ssid == 0x72 && type_from_pmt != AUDIO_DTS && type_from_pmt != SPU_PGS)
- es->type = type_from_pmt = AUDIO_TRUEHD;
- }
-
- p += header_len + 9;
- packet_len -= header_len + 3;
-
- if(es->payload_size)
- es->payload_size -= header_len + 3;
-
-
- es->is_synced = 1; //only for SL streams we have to make sure it's really true, see below
- if (stream_id == 0xbd)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG3, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X, 80: %d\n",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[0] & 0x80);
-
-
- /*
- * we check the descriptor tag first because some stations
- * do not include any of the A52 header info in their audio tracks
- * these "raw" streams may begin with a byte that looks like a stream type.
- */
-
-
- if(type_from_pmt == SPU_PGS)
- {
- es->start = p;
- es->size = packet_len;
- es->type = SPU_PGS;
- es->payload_size -= packet_len;
- return 1;
- }
- if(
- (type_from_pmt == AUDIO_A52) || /* A52 - raw */
- (packet_len >= 2 && p[0] == 0x0B && p[1] == 0x77) /* A52 - syncword */
- )
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "A52 RAW OR SYNCWORD\n");
- es->start = p;
- es->size = packet_len;
- es->type = AUDIO_A52;
- es->payload_size -= packet_len;
-
- return 1;
- }
- /* SPU SUBS */
- else if(type_from_pmt == SPU_DVB ||
- (packet_len >= 2 && (p[0] == 0x20) && pes_is_aligned)) // && p[1] == 0x00))
- {
- // offset/length fiddling to make decoding with lavc possible
- es->start = p + 2;
- es->size = packet_len - 2;
- es->type = SPU_DVB;
- es->payload_size -= packet_len;
-
- return 1;
- }
- else if (pes_is_aligned && packet_len >= 1 && ((p[0] & 0xE0) == 0x20)) //SPU_DVD
- {
- //DVD SUBS
- es->start = p+1;
- es->size = packet_len-1;
- es->type = SPU_DVD;
- es->payload_size -= packet_len;
-
- return 1;
- }
- else if (pes_is_aligned && packet_len >= 4 && (p[0] & 0xF8) == 0x80)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "A52 WITH HEADER\n");
- es->start = p+4;
- es->size = packet_len - 4;
- es->type = AUDIO_A52;
- es->payload_size -= packet_len;
-
- return 1;
- }
- else if (pes_is_aligned && packet_len >= 1 && ((p[0]&0xf0) == 0xa0))
- {
- int pcm_offset;
-
- for (pcm_offset=0; ++pcm_offset < packet_len-1 ; )
- {
- if (p[pcm_offset] == 0x01 && p[pcm_offset+1] == 0x80)
- { /* START */
- pcm_offset += 2;
- break;
- }
- }
-
- es->start = p + pcm_offset;
- es->size = packet_len - pcm_offset;
- es->type = AUDIO_LPCM_BE;
- es->payload_size -= packet_len;
-
- return 1;
- }
- else
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "PES_PRIVATE1\n");
- es->start = p;
- es->size = packet_len;
- es->type = (type_from_pmt == UNKNOWN ? PES_PRIVATE1 : type_from_pmt);
- es->payload_size -= packet_len;
-
- return 1;
- }
- }
- else if((stream_id >= 0xe0 && stream_id <= 0xef) || (stream_id == 0xfd && type_from_pmt != UNKNOWN))
- {
- es->start = p;
- es->size = packet_len;
- if(type_from_pmt != UNKNOWN)
- es->type = type_from_pmt;
- else
- es->type = VIDEO_MPEG2;
- if(es->payload_size)
- es->payload_size -= packet_len;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: M2V size %d\n", es->size);
- return 1;
- }
- else if (stream_id == 0xfa)
- {
- int l;
-
- es->is_synced = 0;
- if(type_from_pmt != UNKNOWN) //MP4 A/V or SL
- {
- es->start = p;
- es->size = packet_len;
- es->type = type_from_pmt;
-
- if(type_from_pmt == SL_PES_STREAM)
- {
- //if(pes_is_aligned)
- //{
- l = mp4_parse_sl_packet(pmt, p, packet_len, pid, es);
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "L=%d, TYPE=%x\n", l, type_from_pmt);
- if(l < 0)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: couldn't parse SL header, passing along full PES payload\n");
- l = 0;
- }
- //}
-
- es->start += l;
- es->size -= l;
- }
-
- if(es->payload_size)
- es->payload_size -= packet_len;
- return 1;
- }
- }
- else if ((stream_id & 0xe0) == 0xc0)
- {
- es->start = p;
- es->size = packet_len;
-
- if(type_from_pmt != UNKNOWN)
- es->type = type_from_pmt;
- else
- es->type = AUDIO_MP2;
-
- es->payload_size -= packet_len;
-
- return 1;
- }
- else if (type_from_pmt != -1) //as a last resort here we trust the PMT, if present
- {
- es->start = p;
- es->size = packet_len;
- es->type = type_from_pmt;
- es->payload_size -= packet_len;
-
- return 1;
- }
- else
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: unknown packet, id: %x\n", stream_id);
- }
-
- es->is_synced = 0;
- return 0;
-}
-
-
-
-
-static int ts_sync(stream_t *stream)
-{
- mp_msg(MSGT_DEMUX, MSGL_DBG3, "TS_SYNC \n");
-
- while (!stream->eof)
- if (stream_read_char(stream) == 0x47)
- return 1;
-
- return 0;
-}
-
-
-static void ts_dump_streams(ts_priv_t *priv)
-{
- int i;
-
- for(i = 0; i < 3; i++)
- {
- if((priv->fifo[i].pack != NULL) && (priv->fifo[i].offset != 0))
- {
- resize_demux_packet(priv->fifo[i].pack, priv->fifo[i].offset);
- ds_add_packet(priv->fifo[i].ds, priv->fifo[i].pack);
- priv->fifo[i].offset = 0;
- priv->fifo[i].pack = NULL;
- }
- }
-}
-
-
-static inline int32_t prog_idx_in_pat(ts_priv_t *priv, uint16_t progid)
-{
- int x;
-
- if(priv->pat.progs == NULL)
- return -1;
-
- for(x = 0; x < priv->pat.progs_cnt; x++)
- {
- if(priv->pat.progs[x].id == progid)
- return x;
- }
-
- return -1;
-}
-
-
-static inline int32_t prog_id_in_pat(ts_priv_t *priv, uint16_t pid)
-{
- int x;
-
- if(priv->pat.progs == NULL)
- return -1;
-
- for(x = 0; x < priv->pat.progs_cnt; x++)
- {
- if(priv->pat.progs[x].pmt_pid == pid)
- return priv->pat.progs[x].id;
- }
-
- return -1;
-}
-
-static int collect_section(ts_section_t *section, int is_start, unsigned char *buff, int size)
-{
- uint8_t *ptr;
- uint16_t tlen;
- int skip, tid;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "COLLECT_SECTION, start: %d, size: %d, collected: %d\n", is_start, size, section->buffer_len);
- if(! is_start && !section->buffer_len)
- return 0;
-
- if(is_start)
- {
- if(! section->buffer)
- {
- section->buffer = malloc(4096 + 256);
- if(section->buffer == NULL)
- return 0;
- }
- section->buffer_len = 0;
- }
-
- if(size + section->buffer_len > 4096+256)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "COLLECT_SECTION, excessive len: %d + %d\n", section->buffer_len, size);
- return 0;
- }
-
- memcpy(&(section->buffer[section->buffer_len]), buff, size);
- section->buffer_len += size;
-
- if(section->buffer_len < 3)
- return 0;
-
- skip = section->buffer[0];
- if(skip + 4 > section->buffer_len)
- return 0;
-
- ptr = &(section->buffer[skip + 1]);
- tid = ptr[0];
- tlen = ((ptr[1] & 0x0f) << 8) | ptr[2];
- mp_msg(MSGT_DEMUX, MSGL_V, "SKIP: %d+1, TID: %d, TLEN: %d, COLLECTED: %d\n", skip, tid, tlen, section->buffer_len);
- if(section->buffer_len < (skip+1+3+tlen))
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "DATA IS NOT ENOUGH, NEXT TIME\n");
- return 0;
- }
-
- return skip+1;
-}
-
-static int parse_pat(ts_priv_t * priv, int is_start, unsigned char *buff, int size)
-{
- int skip;
- unsigned char *ptr;
- unsigned char *base;
- int entries, i;
- uint16_t progid;
- struct pat_progs_t *tmp;
- ts_section_t *section;
-
- section = &(priv->pat.section);
- skip = collect_section(section, is_start, buff, size);
- if(! skip)
- return 0;
-
- ptr = &(section->buffer[skip]);
- //PARSING
- priv->pat.table_id = ptr[0];
- if(priv->pat.table_id != 0)
- return 0;
- priv->pat.ssi = (ptr[1] >> 7) & 0x1;
- priv->pat.curr_next = ptr[5] & 0x01;
- priv->pat.ts_id = (ptr[3] << 8 ) | ptr[4];
- priv->pat.version_number = (ptr[5] >> 1) & 0x1F;
- priv->pat.section_length = ((ptr[1] & 0x03) << 8 ) | ptr[2];
- priv->pat.section_number = ptr[6];
- priv->pat.last_section_number = ptr[7];
-
- //check_crc32(0xFFFFFFFFL, ptr, priv->pat.buffer_len - 4, &ptr[priv->pat.buffer_len - 4]);
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PAT: section_len: %d, section %d/%d\n", priv->pat.section_length, priv->pat.section_number, priv->pat.last_section_number);
-
- entries = (int) (priv->pat.section_length - 9) / 4; //entries per section
-
- for(i=0; i < entries; i++)
- {
- int32_t idx;
- base = &ptr[8 + i*4];
- progid = (base[0] << 8) | base[1];
-
- if((idx = prog_idx_in_pat(priv, progid)) == -1)
- {
- int sz = sizeof(struct pat_progs_t) * (priv->pat.progs_cnt+1);
- tmp = realloc_struct(priv->pat.progs, priv->pat.progs_cnt+1, sizeof(struct pat_progs_t));
- if(tmp == NULL)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "PARSE_PAT: COULDN'T REALLOC %d bytes, NEXT\n", sz);
- break;
- }
- priv->pat.progs = tmp;
- idx = priv->pat.progs_cnt;
- priv->pat.progs_cnt++;
- }
-
- priv->pat.progs[idx].id = progid;
- priv->pat.progs[idx].pmt_pid = ((base[2] & 0x1F) << 8) | base[3];
- mp_msg(MSGT_DEMUX, MSGL_V, "PROG: %d (%d-th of %d), PMT: %d\n", priv->pat.progs[idx].id, i+1, entries, priv->pat.progs[idx].pmt_pid);
- mp_msg(MSGT_IDENTIFY, MSGL_V, "PROGRAM_ID=%d (0x%02X), PMT_PID: %d(0x%02X)\n",
- progid, progid, priv->pat.progs[idx].pmt_pid, priv->pat.progs[idx].pmt_pid);
- }
-
- return 1;
-}
-
-
-static inline int32_t es_pid_in_pmt(pmt_t * pmt, uint16_t pid)
-{
- uint16_t i;
-
- if(pmt == NULL)
- return -1;
-
- if(pmt->es == NULL)
- return -1;
-
- for(i = 0; i < pmt->es_cnt; i++)
- {
- if(pmt->es[i].pid == pid)
- return (int32_t) i;
- }
-
- return -1;
-}
-
-
-static uint16_t get_mp4_desc_len(uint8_t *buf, int *len)
-{
- //uint16_t i = 0, size = 0;
- int i = 0, j, size = 0;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "PARSE_MP4_DESC_LEN(%d), bytes: ", *len);
- j = FFMIN(*len, 4);
- while(i < j)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, " %x ", buf[i]);
- size |= (buf[i] & 0x7f);
- if(!(buf[i] & 0x80))
- break;
- size <<= 7;
- i++;
- }
- mp_msg(MSGT_DEMUX, MSGL_DBG2, ", SIZE=%d\n", size);
-
- *len = i+1;
- return size;
-}
-
-
-static uint16_t parse_mp4_slconfig_descriptor(uint8_t *buf, int len, void *elem)
-{
- int i = 0;
- mp4_es_descr_t *es;
- mp4_sl_config_t *sl;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_SLCONFIG_DESCRIPTOR(%d)\n", len);
- es = (mp4_es_descr_t *) elem;
- if(!es)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");
- return len;
- }
- sl = &(es->sl);
-
- sl->ts_len = sl->ocr_len = sl->au_len = sl->instant_bitrate_len = sl->degr_len = sl->au_seqnum_len = sl->packet_seqnum_len = 0;
- sl->ocr = sl->dts = sl->cts = 0;
-
- if(buf[0] == 0)
- {
- i++;
- sl->flags = buf[i];
- i++;
- sl->ts_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];
- i += 4;
- sl->ocr_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];
- i += 4;
- sl->ts_len = buf[i];
- i++;
- sl->ocr_len = buf[i];
- i++;
- sl->au_len = buf[i];
- i++;
- sl->instant_bitrate_len = buf[i];
- i++;
- sl->degr_len = (buf[i] >> 4) & 0x0f;
- sl->au_seqnum_len = ((buf[i] & 0x0f) << 1) | ((buf[i+1] >> 7) & 0x01);
- i++;
- sl->packet_seqnum_len = ((buf[i] >> 2) & 0x1f);
- i++;
-
- }
- else if(buf[0] == 1)
- {
- sl->flags = 0;
- sl->ts_resolution = 1000;
- sl->ts_len = 32;
- i++;
- }
- else if(buf[0] == 2)
- {
- sl->flags = 4;
- i++;
- }
- else
- {
- sl->flags = 0;
- i++;
- }
-
- sl->au_start = (sl->flags >> 7) & 0x1;
- sl->au_end = (sl->flags >> 6) & 0x1;
- sl->random_accesspoint = (sl->flags >> 5) & 0x1;
- sl->random_accesspoint_only = (sl->flags >> 4) & 0x1;
- sl->padding = (sl->flags >> 3) & 0x1;
- sl->use_ts = (sl->flags >> 2) & 0x1;
- sl->idle = (sl->flags >> 1) & 0x1;
- sl->duration = sl->flags & 0x1;
-
- if(sl->duration)
- {
- sl->timescale = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];
- i += 4;
- sl->au_duration = (buf[i] << 8) | buf[i+1];
- i += 2;
- sl->cts_duration = (buf[i] << 8) | buf[i+1];
- i += 2;
- }
- else //no support for fixed durations atm
- sl->timescale = sl->au_duration = sl->cts_duration = 0;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "MP4SLCONFIG(len=0x%x), predef: %d, flags: %x, use_ts: %d, tslen: %d, timescale: %d, dts: %"PRIu64", cts: %"PRIu64"\n",
- len, buf[0], sl->flags, sl->use_ts, sl->ts_len, sl->timescale, (uint64_t) sl->dts, (uint64_t) sl->cts);
-
- return len;
-}
-
-static int parse_mp4_descriptors(pmt_t *pmt, uint8_t *buf, int len, void *elem);
-
-static uint16_t parse_mp4_decoder_config_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem)
-{
- int i = 0, j;
- mp4_es_descr_t *es;
- mp4_decoder_config_t *dec;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_CONFIG_DESCRIPTOR(%d)\n", len);
- es = (mp4_es_descr_t *) elem;
- if(!es)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");
- return len;
- }
- dec = (mp4_decoder_config_t*) &(es->decoder);
-
- dec->object_type = buf[i];
- dec->stream_type = (buf[i+1]>>2) & 0x3f;
-
- if(dec->object_type == 1 && dec->stream_type == 1)
- {
- dec->object_type = MP4_OD;
- dec->stream_type = MP4_OD;
- }
- else if(dec->stream_type == 4)
- {
- if(dec->object_type == 0x6a)
- dec->object_type = VIDEO_MPEG1;
- if(dec->object_type >= 0x60 && dec->object_type <= 0x65)
- dec->object_type = VIDEO_MPEG2;
- else if(dec->object_type == 0x20)
- dec->object_type = VIDEO_MPEG4;
- else if(dec->object_type == 0x21)
- dec->object_type = VIDEO_AVC;
- /*else if(dec->object_type == 0x22)
- fprintf(stderr, "TYPE 0x22\n");*/
- else dec->object_type = UNKNOWN;
- }
- else if(dec->stream_type == 5)
- {
- if(dec->object_type == 0x40)
- dec->object_type = AUDIO_AAC;
- else if(dec->object_type == 0x6b)
- dec->object_type = AUDIO_MP2;
- else if(dec->object_type >= 0x66 && dec->object_type <= 0x69)
- dec->object_type = AUDIO_MP2;
- else
- dec->object_type = UNKNOWN;
- }
- else
- dec->object_type = dec->stream_type = UNKNOWN;
-
- if(dec->object_type != UNKNOWN)
- {
- //update the type of the current stream
- for(j = 0; j < pmt->es_cnt; j++)
- {
- if(pmt->es[j].mp4_es_id == es->id)
- {
- pmt->es[j].type = SL_PES_STREAM;
- }
- }
- }
-
- if(len > 13)
- parse_mp4_descriptors(pmt, &buf[13], len-13, dec);
-
- mp_msg(MSGT_DEMUX, MSGL_V, "MP4DECODER(0x%x), object_type: 0x%x, stream_type: 0x%x\n", len, dec->object_type, dec->stream_type);
-
- return len;
-}
-
-static uint16_t parse_mp4_decoder_specific_descriptor(uint8_t *buf, int len, void *elem)
-{
- int i;
- mp4_decoder_config_t *dec;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_SPECIFIC_DESCRIPTOR(%d)\n", len);
- dec = (mp4_decoder_config_t *) elem;
- if(!dec)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");
- return len;
- }
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4 SPECIFIC INFO BYTES: \n");
- for(i=0; i<len; i++)
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "%02x ", buf[i]);
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "\n");
-
- if(len > MAX_EXTRADATA_SIZE)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "DEMUX_TS, EXTRADATA SUSPICIOUSLY BIG: %d, REFUSED\r\n", len);
- return len;
- }
- memcpy(dec->buf, buf, len);
- dec->buf_size = len;
-
- return len;
-}
-
-static uint16_t parse_mp4_es_descriptor(pmt_t *pmt, uint8_t *buf, int len)
-{
- int i = 0, j = 0, k, found;
- uint8_t flag;
- mp4_es_descr_t es, *target_es = NULL, *tmp;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES: len=%d\n", len);
- memset(&es, 0, sizeof(mp4_es_descr_t));
- while(i < len)
- {
- es.id = (buf[i] << 8) | buf[i+1];
- mp_msg(MSGT_DEMUX, MSGL_V, "MP4ES_ID: %d\n", es.id);
- i += 2;
- flag = buf[i];
- i++;
- if(flag & 0x80)
- i += 2;
- if(flag & 0x40)
- i += buf[i]+1;
- if(flag & 0x20) //OCR, maybe we need it
- i += 2;
-
- j = parse_mp4_descriptors(pmt, &buf[i], len-i, &es);
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES, types after parse_mp4_descriptors: 0x%x, 0x%x\n", es.decoder.object_type, es.decoder.stream_type);
- if(es.decoder.object_type != UNKNOWN && es.decoder.stream_type != UNKNOWN)
- {
- found = 0;
- //search this ES_ID if we already have it
- for(k=0; k < pmt->mp4es_cnt; k++)
- {
- if(pmt->mp4es[k].id == es.id)
- {
- target_es = &(pmt->mp4es[k]);
- found = 1;
- }
- }
-
- if(! found)
- {
- tmp = realloc_struct(pmt->mp4es, pmt->mp4es_cnt+1, sizeof(mp4_es_descr_t));
- if(tmp == NULL)
- {
- fprintf(stderr, "CAN'T REALLOC MP4_ES_DESCR\n");
- continue;
- }
- pmt->mp4es = tmp;
- target_es = &(pmt->mp4es[pmt->mp4es_cnt]);
- pmt->mp4es_cnt++;
- }
- memcpy(target_es, &es, sizeof(mp4_es_descr_t));
- mp_msg(MSGT_DEMUX, MSGL_V, "MP4ES_CNT: %d, ID=%d\n", pmt->mp4es_cnt, target_es->id);
- }
-
- i += j;
- }
-
- return len;
-}
-
-static void parse_mp4_object_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem)
-{
- int i, j = 0, id;
-
- i=0;
- id = (buf[0] << 2) | ((buf[1] & 0xc0) >> 6);
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_OBJECT_DESCRIPTOR: len=%d, OD_ID=%d\n", len, id);
- if(buf[1] & 0x20)
- {
- i += buf[2] + 1; //url
- mp_msg(MSGT_DEMUX, MSGL_V, "URL\n");
- }
- else
- {
- i = 2;
-
- while(i < len)
- {
- j = parse_mp4_descriptors(pmt, &(buf[i]), len-i, elem);
- mp_msg(MSGT_DEMUX, MSGL_V, "OBJD, NOW i = %d, j=%d, LEN=%d\n", i, j, len);
- i += j;
- }
- }
-}
-
-
-static void parse_mp4_iod(pmt_t *pmt, uint8_t *buf, int len, void *elem)
-{
- int i, j = 0;
- mp4_od_t *iod = &(pmt->iod);
-
- iod->id = (buf[0] << 2) | ((buf[1] & 0xc0) >> 6);
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_IOD: len=%d, IOD_ID=%d\n", len, iod->id);
- i = 2;
- if(buf[1] & 0x20)
- {
- i += buf[2] + 1; //url
- mp_msg(MSGT_DEMUX, MSGL_V, "URL\n");
- }
- else
- {
- i = 7;
- while(i < len)
- {
- j = parse_mp4_descriptors(pmt, &(buf[i]), len-i, elem);
- mp_msg(MSGT_DEMUX, MSGL_V, "IOD, NOW i = %d, j=%d, LEN=%d\n", i, j, len);
- i += j;
- }
- }
-}
-
-static int parse_mp4_descriptors(pmt_t *pmt, uint8_t *buf, int len, void *elem)
-{
- int tag, descr_len, i = 0, j = 0;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DESCRIPTORS, len=%d\n", len);
- if(! len)
- return len;
-
- while(i < len)
- {
- tag = buf[i];
- j = len - i -1;
- descr_len = get_mp4_desc_len(&(buf[i+1]), &j);
- mp_msg(MSGT_DEMUX, MSGL_V, "TAG=%d (0x%x), DESCR_len=%d, len=%d, j=%d\n", tag, tag, descr_len, len, j);
- if(descr_len > len - j+1)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "descriptor is too long, exit\n");
- return len;
- }
- i += j+1;
-
- switch(tag)
- {
- case 0x1:
- parse_mp4_object_descriptor(pmt, &(buf[i]), descr_len, elem);
- break;
- case 0x2:
- parse_mp4_iod(pmt, &(buf[i]), descr_len, elem);
- break;
- case 0x3:
- parse_mp4_es_descriptor(pmt, &(buf[i]), descr_len);
- break;
- case 0x4:
- parse_mp4_decoder_config_descriptor(pmt, &buf[i], descr_len, elem);
- break;
- case 0x05:
- parse_mp4_decoder_specific_descriptor(&buf[i], descr_len, elem);
- break;
- case 0x6:
- parse_mp4_slconfig_descriptor(&buf[i], descr_len, elem);
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_V, "Unsupported mp4 descriptor 0x%x\n", tag);
- }
- i += descr_len;
- }
-
- return len;
-}
-
-static ES_stream_t *new_pid(ts_priv_t *priv, int pid)
-{
- ES_stream_t *tss;
-
- tss = calloc(sizeof(*tss), 1);
- if(! tss)
- return NULL;
- tss->pid = pid;
- tss->last_cc = -1;
- tss->type = UNKNOWN;
- tss->subtype = UNKNOWN;
- tss->is_synced = 0;
- tss->extradata = NULL;
- tss->extradata_alloc = tss->extradata_len = 0;
- priv->ts.pids[pid] = tss;
-
- return tss;
-}
-
-
-static int parse_program_descriptors(pmt_t *pmt, uint8_t *buf, uint16_t len)
-{
- uint16_t i = 0, k, olen = len;
-
- while(len > 0)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "PROG DESCR, TAG=%x, LEN=%d(%x)\n", buf[i], buf[i+1], buf[i+1]);
- if(buf[i+1] > len-2)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "ERROR, descriptor len is too long, skipping\n");
- return olen;
- }
-
- if(buf[i] == 0x1d)
- {
- if(buf[i+3] == 2) //buggy versions of vlc muxer make this non-standard mess (missing iod_scope)
- k = 3;
- else
- k = 4; //this is standard compliant
- parse_mp4_descriptors(pmt, &buf[i+k], (int) buf[i+1]-(k-2), NULL);
- }
-
- len -= 2 + buf[i+1];
- }
-
- return olen;
-}
-
-static int parse_descriptors(struct pmt_es_t *es, uint8_t *ptr)
-{
- int j, descr_len, len;
-
- j = 0;
- len = es->descr_length;
- while(len > 2)
- {
- descr_len = ptr[j+1];
- mp_msg(MSGT_DEMUX, MSGL_V, "...descr id: 0x%x, len=%d\n", ptr[j], descr_len);
- if(descr_len > len)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "INVALID DESCR LEN for tag %02x: %d vs %d max, EXIT LOOP\n", ptr[j], descr_len, len);
- return -1;
- }
-
-
- if(ptr[j] == 0x6a || ptr[j] == 0x7a) //A52 Descriptor
- {
- if(es->type == 0x6)
- {
- es->type = AUDIO_A52;
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "DVB A52 Descriptor\n");
- }
- }
- else if(ptr[j] == 0x7b) //DVB DTS Descriptor
- {
- if(es->type == 0x6)
- {
- es->type = AUDIO_DTS;
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "DVB DTS Descriptor\n");
- }
- }
- else if(ptr[j] == 0x56) // Teletext
- {
- if(descr_len >= 5) {
- memcpy(es->lang, ptr+2, 3);
- es->lang[3] = 0;
- }
- es->type = SPU_TELETEXT;
- }
- else if(ptr[j] == 0x59) //Subtitling Descriptor
- {
- uint8_t subtype;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Subtitling Descriptor\n");
- if(descr_len < 8)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Descriptor length too short for DVB Subtitle Descriptor: %d, SKIPPING\n", descr_len);
- }
- else
- {
- memcpy(es->lang, &ptr[j+2], 3);
- es->lang[3] = 0;
- subtype = ptr[j+5];
- if(
- (subtype >= 0x10 && subtype <= 0x13) ||
- (subtype >= 0x20 && subtype <= 0x23)
- )
- {
- es->type = SPU_DVB;
- //page parameters: compo page 2 bytes, ancillary page 2 bytes
- }
- else
- es->type = UNKNOWN;
- }
- }
- else if(ptr[j] == 0x50) //Component Descriptor
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Component Descriptor\n");
- memcpy(es->lang, &ptr[j+5], 3);
- es->lang[3] = 0;
- }
- else if(ptr[j] == 0xa) //Language Descriptor
- {
- memcpy(es->lang, &ptr[j+2], 3);
- es->lang[3] = 0;
- mp_msg(MSGT_DEMUX, MSGL_V, "Language Descriptor: %s\n", es->lang);
- }
- else if(ptr[j] == 0x5) //Registration Descriptor (looks like e fourCC :) )
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Registration Descriptor\n");
- if(descr_len < 4)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Registration Descriptor length too short: %d, SKIPPING\n", descr_len);
- }
- else
- {
- char *d;
- memcpy(es->format_descriptor, &ptr[j+2], 4);
- es->format_descriptor[4] = 0;
-
- d = &ptr[j+2];
- if(d[0] == 'A' && d[1] == 'C' && d[2] == '-' && d[3] == '3')
- {
- es->type = AUDIO_A52;
- }
- else if(d[0] == 'D' && d[1] == 'T' && d[2] == 'S' && d[3] == '1')
- {
- es->type = AUDIO_DTS;
- }
- else if(d[0] == 'D' && d[1] == 'T' && d[2] == 'S' && d[3] == '2')
- {
- es->type = AUDIO_DTS;
- }
- else if(d[0] == 'V' && d[1] == 'C' && d[2] == '-' && d[3] == '1')
- {
- es->type = VIDEO_VC1;
- }
- else if(d[0] == 'd' && d[1] == 'r' && d[2] == 'a' && d[3] == 'c')
- {
- es->type = VIDEO_DIRAC;
- }
- else if(d[0] == 'B' && d[1] == 'S' && d[2] == 'S' && d[3] == 'D')
- {
- es->type = AUDIO_S302M;
- }
- else
- es->type = UNKNOWN;
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "FORMAT %s\n", es->format_descriptor);
- }
- }
- else if(ptr[j] == 0x1e || ptr[j] == 0x1f)
- {
- // 0x1f is FMC, but currently it is easiest to handle them the same way
- es->mp4_es_id = (ptr[j+2] << 8) | ptr[j+3];
- mp_msg(MSGT_DEMUX, MSGL_V, "SL Descriptor: ES_ID: %d(%x), pid: %d\n", es->mp4_es_id, es->mp4_es_id, es->pid);
- }
- else
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "Unknown descriptor 0x%x, SKIPPING\n", ptr[j]);
-
- len -= 2 + descr_len;
- j += 2 + descr_len;
- }
-
- return 1;
-}
-
-static int parse_sl_section(pmt_t *pmt, ts_section_t *section, int is_start, unsigned char *buff, int size)
-{
- int tid, len, skip;
- uint8_t *ptr;
- skip = collect_section(section, is_start, buff, size);
- if(! skip)
- return 0;
-
- ptr = &(section->buffer[skip]);
- tid = ptr[0];
- len = ((ptr[1] & 0x0f) << 8) | ptr[2];
- mp_msg(MSGT_DEMUX, MSGL_V, "TABLEID: %d (av. %d), skip=%d, LEN: %d\n", tid, section->buffer_len, skip, len);
- if(len > 4093 || section->buffer_len < len || tid != 5)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "SECTION TOO LARGE or wrong section type, EXIT\n");
- return 0;
- }
-
- if(! (ptr[5] & 1))
- return 0;
-
- //8 is the current position, len - 9 is the amount of data available
- parse_mp4_descriptors(pmt, &ptr[8], len - 9, NULL);
-
- return 1;
-}
-
-static int parse_pmt(ts_priv_t * priv, uint16_t progid, uint16_t pid, int is_start, unsigned char *buff, int size)
-{
- unsigned char *base, *es_base;
- pmt_t *pmt;
- int32_t idx, es_count, section_bytes;
- uint8_t m=0;
- int skip;
- pmt_t *tmp;
- struct pmt_es_t *tmp_es;
- ts_section_t *section;
- ES_stream_t *tss;
- int i;
-
- idx = progid_idx_in_pmt(priv, progid);
-
- if(idx == -1)
- {
- int sz = (priv->pmt_cnt + 1) * sizeof(pmt_t);
- tmp = realloc_struct(priv->pmt, priv->pmt_cnt + 1, sizeof(pmt_t));
- if(tmp == NULL)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "PARSE_PMT: COULDN'T REALLOC %d bytes, NEXT\n", sz);
- return 0;
- }
- priv->pmt = tmp;
- idx = priv->pmt_cnt;
- memset(&(priv->pmt[idx]), 0, sizeof(pmt_t));
- priv->pmt_cnt++;
- priv->pmt[idx].progid = progid;
- }
-
- pmt = &(priv->pmt[idx]);
-
- section = &(pmt->section);
- skip = collect_section(section, is_start, buff, size);
- if(! skip)
- return 0;
-
- base = &(section->buffer[skip]);
-
- mp_msg(MSGT_DEMUX, MSGL_V, "FILL_PMT(prog=%d), PMT_len: %d, IS_START: %d, TS_PID: %d, SIZE=%d, M=%d, ES_CNT=%d, IDX=%d, PMT_PTR=%p\n",
- progid, pmt->section.buffer_len, is_start, pid, size, m, pmt->es_cnt, idx, pmt);
-
- pmt->table_id = base[0];
- if(pmt->table_id != 2)
- return -1;
- pmt->ssi = base[1] & 0x80;
- pmt->section_length = (((base[1] & 0xf) << 8 ) | base[2]);
- pmt->version_number = (base[5] >> 1) & 0x1f;
- pmt->curr_next = (base[5] & 1);
- pmt->section_number = base[6];
- pmt->last_section_number = base[7];
- pmt->PCR_PID = ((base[8] & 0x1f) << 8 ) | base[9];
- pmt->prog_descr_length = ((base[10] & 0xf) << 8 ) | base[11];
- if(pmt->prog_descr_length > pmt->section_length - 9)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PMT, INVALID PROG_DESCR LENGTH (%d vs %d)\n", pmt->prog_descr_length, pmt->section_length - 9);
- return -1;
- }
-
- if(pmt->prog_descr_length)
- parse_program_descriptors(pmt, &base[12], pmt->prog_descr_length);
-
- es_base = &base[12 + pmt->prog_descr_length]; //the beginning of th ES loop
-
- section_bytes= pmt->section_length - 13 - pmt->prog_descr_length;
- es_count = 0;
-
- while(section_bytes >= 5)
- {
- int es_pid, es_type;
-
- es_type = es_base[0];
- es_pid = ((es_base[1] & 0x1f) << 8) | es_base[2];
-
- idx = es_pid_in_pmt(pmt, es_pid);
- if(idx == -1)
- {
- int sz = sizeof(struct pmt_es_t) * (pmt->es_cnt + 1);
- tmp_es = realloc_struct(pmt->es, pmt->es_cnt + 1, sizeof(struct pmt_es_t));
- if(tmp_es == NULL)
- {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "PARSE_PMT, COULDN'T ALLOCATE %d bytes for PMT_ES\n", sz);
- continue;
- }
- pmt->es = tmp_es;
- idx = pmt->es_cnt;
- memset(&(pmt->es[idx]), 0, sizeof(struct pmt_es_t));
- pmt->es_cnt++;
- }
-
- pmt->es[idx].descr_length = ((es_base[3] & 0xf) << 8) | es_base[4];
-
-
- if(pmt->es[idx].descr_length > section_bytes - 5)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PMT, ES_DESCR_LENGTH TOO LARGE %d > %d, EXIT\n",
- pmt->es[idx].descr_length, section_bytes - 5);
- return -1;
- }
-
-
- pmt->es[idx].pid = es_pid;
- if(es_type != 0x6)
- pmt->es[idx].type = UNKNOWN;
- else
- pmt->es[idx].type = es_type;
-
- parse_descriptors(&pmt->es[idx], &es_base[5]);
-
- switch(es_type)
- {
- case 1:
- pmt->es[idx].type = VIDEO_MPEG1;
- break;
- case 2:
- pmt->es[idx].type = VIDEO_MPEG2;
- break;
- case 3:
- case 4:
- pmt->es[idx].type = AUDIO_MP2;
- break;
- case 6:
- if(pmt->es[idx].type == 0x6) //this could have been ovrwritten by parse_descriptors
- pmt->es[idx].type = UNKNOWN;
- break;
- case 0x10:
- pmt->es[idx].type = VIDEO_MPEG4;
- break;
- case 0x0f:
- pmt->es[idx].type = AUDIO_AAC;
- break;
- case 0x11:
- pmt->es[idx].type = AUDIO_AAC_LATM;
- for (i = 0; i < pmt->mp4es_cnt; i++)
- if (pmt->mp4es[i].id == pmt->es[idx].mp4_es_id &&
- pmt->mp4es[i].decoder.object_type == AUDIO_AAC)
- pmt->es[idx].type = AUDIO_AAC;
- break;
- case 0x1b:
- pmt->es[idx].type = VIDEO_H264;
- break;
- case 0x12:
- pmt->es[idx].type = SL_PES_STREAM;
- break;
- case 0x13:
- pmt->es[idx].type = SL_SECTION;
- break;
- case 0x81:
- pmt->es[idx].type = AUDIO_A52;
- break;
- case 0x8A:
- case 0x82:
- case 0x85:
- case 0x86:
- pmt->es[idx].type = AUDIO_DTS;
- break;
- case 0x90:
- pmt->es[idx].type = SPU_PGS;
- break;
- case 0xD1:
- pmt->es[idx].type = VIDEO_DIRAC;
- break;
- case 0xEA:
- pmt->es[idx].type = VIDEO_VC1;
- break;
- default:
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "UNKNOWN ES TYPE=0x%x\n", es_type);
- pmt->es[idx].type = UNKNOWN;
- }
-
- tss = priv->ts.pids[es_pid]; //an ES stream
- if(tss == NULL)
- {
- tss = new_pid(priv, es_pid);
- if(tss)
- tss->type = pmt->es[idx].type;
- }
-
- section_bytes -= 5 + pmt->es[idx].descr_length;
- mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PMT(%d INDEX %d), STREAM: %d, FOUND pid=0x%x (%d), type=0x%x, ES_DESCR_LENGTH: %d, bytes left: %d\n",
- progid, idx, es_count, pmt->es[idx].pid, pmt->es[idx].pid, pmt->es[idx].type, pmt->es[idx].descr_length, section_bytes);
-
-
- es_base += 5 + pmt->es[idx].descr_length;
-
- es_count++;
- }
-
- mp_msg(MSGT_DEMUX, MSGL_V, "----------------------------\n");
- return 1;
-}
-
-static pmt_t* pmt_of_pid(ts_priv_t *priv, int pid, mp4_decoder_config_t **mp4_dec)
-{
- int32_t i, j, k;
-
- if(priv->pmt)
- {
- for(i = 0; i < priv->pmt_cnt; i++)
- {
- if(priv->pmt[i].es && priv->pmt[i].es_cnt)
- {
- for(j = 0; j < priv->pmt[i].es_cnt; j++)
- {
- if(priv->pmt[i].es[j].pid == pid)
- {
- //search mp4_es_id
- if(priv->pmt[i].es[j].mp4_es_id)
- {
- for(k = 0; k < priv->pmt[i].mp4es_cnt; k++)
- {
- if(priv->pmt[i].mp4es[k].id == priv->pmt[i].es[j].mp4_es_id)
- {
- *mp4_dec = &(priv->pmt[i].mp4es[k].decoder);
- break;
- }
- }
- }
-
- return &(priv->pmt[i]);
- }
- }
- }
- }
- }
-
- return NULL;
-}
-
-
-static inline int32_t pid_type_from_pmt(ts_priv_t *priv, int pid)
-{
- int32_t pmt_idx, pid_idx, i, j;
-
- pmt_idx = progid_idx_in_pmt(priv, priv->prog);
-
- if(pmt_idx != -1)
- {
- pid_idx = es_pid_in_pmt(&(priv->pmt[pmt_idx]), pid);
- if(pid_idx != -1)
- return priv->pmt[pmt_idx].es[pid_idx].type;
- }
- //else
- //{
- for(i = 0; i < priv->pmt_cnt; i++)
- {
- pmt_t *pmt = &(priv->pmt[i]);
- for(j = 0; j < pmt->es_cnt; j++)
- if(pmt->es[j].pid == pid)
- return pmt->es[j].type;
- }
- //}
-
- return UNKNOWN;
-}
-
-
-static inline uint8_t *pid_lang_from_pmt(ts_priv_t *priv, int pid)
-{
- int32_t pmt_idx, pid_idx, i, j;
-
- pmt_idx = progid_idx_in_pmt(priv, priv->prog);
-
- if(pmt_idx != -1)
- {
- pid_idx = es_pid_in_pmt(&(priv->pmt[pmt_idx]), pid);
- if(pid_idx != -1)
- return priv->pmt[pmt_idx].es[pid_idx].lang;
- }
- else
- {
- for(i = 0; i < priv->pmt_cnt; i++)
- {
- pmt_t *pmt = &(priv->pmt[i]);
- for(j = 0; j < pmt->es_cnt; j++)
- if(pmt->es[j].pid == pid)
- return pmt->es[j].lang;
- }
- }
-
- return NULL;
-}
-
-
-static int fill_packet(demuxer_t *demuxer, demux_stream_t *ds, demux_packet_t **dp, int *dp_offset, TS_stream_info *si)
-{
- int ret = 0;
-
- if(*dp && *dp_offset <= 0)
- {
- free_demux_packet(*dp);
- *dp = NULL;
- }
- if(*dp)
- {
- ret = *dp_offset;
- resize_demux_packet(*dp, ret); //shrinked to the right size
- ds_add_packet(ds, *dp);
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "ADDED %d bytes to %s fifo, PTS=%.3f\n", ret, (ds == demuxer->audio ? "audio" : (ds == demuxer->video ? "video" : "sub")), (*dp)->pts);
- if(si)
- {
- float diff = (*dp)->pts - si->last_pts;
- float dur;
-
- if(abs(diff) > 1) //1 second, there's a discontinuity
- {
- si->duration += si->last_pts - si->first_pts;
- si->first_pts = si->last_pts = (*dp)->pts;
- }
- else
- {
- si->last_pts = (*dp)->pts;
- }
- si->size += ret;
- dur = si->duration + (si->last_pts - si->first_pts);
-
- if(dur > 0 && ds == demuxer->video)
- {
- ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
- if(dur > 1) //otherwise it may be unreliable
- priv->vbitrate = (uint32_t) ((float) si->size / dur);
- }
- }
- }
-
- *dp = NULL;
- *dp_offset = 0;
-
- return ret;
-}
-
-static int fill_extradata(mp4_decoder_config_t * mp4_dec, ES_stream_t *tss)
-{
- uint8_t *tmp;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4_dec: %p, pid: %d\n", mp4_dec, tss->pid);
-
- if(mp4_dec->buf_size > tss->extradata_alloc)
- {
- tmp = realloc(tss->extradata, mp4_dec->buf_size);
- if(!tmp)
- return 0;
- tss->extradata = tmp;
- tss->extradata_alloc = mp4_dec->buf_size;
- }
- memcpy(tss->extradata, mp4_dec->buf, mp4_dec->buf_size);
- tss->extradata_len = mp4_dec->buf_size;
- mp_msg(MSGT_DEMUX, MSGL_V, "EXTRADATA: %p, alloc=%d, len=%d\n", tss->extradata, tss->extradata_alloc, tss->extradata_len);
-
- return tss->extradata_len;
-}
-
-// 0 = EOF or no stream found
-// else = [-] number of bytes written to the packet
-static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet, int probe)
-{
- ES_stream_t *tss;
- int buf_size, is_start, pid, base;
- int len, cc, cc_ok av_unused, afc, retv = 0, is_video, is_audio, is_sub;
- ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
- stream_t *stream = demuxer->stream;
- char *p;
- demux_stream_t *ds = NULL;
- demux_packet_t **dp = NULL;
- int *dp_offset = 0, *buffer_size = 0;
- int32_t progid, pid_type, bad, ts_error;
- int junk = 0, rap_flag = 0;
- pmt_t *pmt;
- mp4_decoder_config_t *mp4_dec;
- TS_stream_info *si;
-
-
- memset(es, 0, sizeof(*es));
- while(1)
- {
- bad = ts_error = 0;
- ds = NULL;
- dp = NULL;
- dp_offset = buffer_size = NULL;
- rap_flag = 0;
- mp4_dec = NULL;
- es->is_synced = 0;
- es->lang[0] = 0;
- si = NULL;
-
- junk = priv->ts.packet_size - TS_PACKET_SIZE;
- buf_size = priv->ts.packet_size - junk;
-
- if(stream_eof(stream))
- {
- if(! probe)
- {
- ts_dump_streams(priv);
- demuxer->filepos = stream_tell(demuxer->stream);
- }
-
- return 0;
- }
-
-
- if(! ts_sync(stream))
- {
- mp_msg(MSGT_DEMUX, MSGL_INFO, "TS_PARSE: COULDN'T SYNC\n");
- return 0;
- }
-
- len = stream_read(stream, &packet[1], 3);
- if (len != 3)
- return 0;
- buf_size -= 4;
-
- if((packet[1] >> 7) & 0x01) //transport error
- ts_error = 1;
-
-
- is_start = packet[1] & 0x40;
- pid = ((packet[1] & 0x1f) << 8) | packet[2];
-
- tss = priv->ts.pids[pid]; //an ES stream
- if(tss == NULL)
- {
- tss = new_pid(priv, pid);
- if(tss == NULL)
- continue;
- }
-
- cc = (packet[3] & 0xf);
- cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
- tss->last_cc = cc;
-
- bad = ts_error; // || (! cc_ok);
- if(bad)
- {
- if(priv->keep_broken == 0)
- {
- stream_skip(stream, buf_size-1+junk);
- continue;
- }
-
- is_start = 0; //queued to the packet data
- }
-
- if(is_start)
- tss->is_synced = 1;
-
- if((!is_start && !tss->is_synced) || ((pid > 1) && (pid < 16)) || (pid == 8191)) //invalid pid
- {
- stream_skip(stream, buf_size-1+junk);
- continue;
- }
-
-
- afc = (packet[3] >> 4) & 3;
- if(! (afc % 2)) //no payload in this TS packet
- {
- stream_skip(stream, buf_size-1+junk);
- continue;
- }
-
- if(afc > 1)
- {
- int c;
- c = stream_read_char(stream);
- buf_size--;
- if(c < 0 || c > 183) //broken from the stream layer or invalid
- {
- stream_skip(stream, buf_size-1+junk);
- continue;
- }
-
- //c==0 is allowed!
- if(c > 0)
- {
- uint8_t pcrbuf[188];
- int flags = stream_read_char(stream);
- int has_pcr;
- rap_flag = (flags & 0x40) >> 6;
- has_pcr = flags & 0x10;
-
- buf_size--;
- c--;
- stream_read(stream, pcrbuf, c);
-
- if(has_pcr)
- {
- int pcr_pid = prog_pcr_pid(priv, priv->prog);
- if(pcr_pid == pid)
- {
- uint64_t pcr, pcr_ext;
-
- pcr = (int64_t)(pcrbuf[0]) << 25;
- pcr |= pcrbuf[1] << 17 ;
- pcr |= (pcrbuf[2]) << 9;
- pcr |= pcrbuf[3] << 1 ;
- pcr |= (pcrbuf[4] & 0x80) >> 7;
-
- pcr_ext = (pcrbuf[4] & 0x01) << 8;
- pcr_ext |= pcrbuf[5];
-
- pcr = pcr * 300 + pcr_ext;
-
- demuxer->reference_clock = (double)pcr/(double)27000000.0;
- }
- }
-
- buf_size -= c;
- if(buf_size == 0)
- continue;
- }
- }
-
- //find the program that the pid belongs to; if (it's the right one or -1) && pid_type==SL_SECTION
- //call parse_sl_section()
- pmt = pmt_of_pid(priv, pid, &mp4_dec);
- if(mp4_dec)
- {
- fill_extradata(mp4_dec, tss);
- if(IS_VIDEO(mp4_dec->object_type) || IS_AUDIO(mp4_dec->object_type))
- {
- tss->type = SL_PES_STREAM;
- tss->subtype = mp4_dec->object_type;
- }
- }
-
-
- //TABLE PARSING
-
- base = priv->ts.packet_size - buf_size;
-
- priv->last_pid = pid;
-
- is_video = IS_VIDEO(tss->type) || (tss->type==SL_PES_STREAM && IS_VIDEO(tss->subtype));
- is_audio = IS_AUDIO(tss->type) || (tss->type==SL_PES_STREAM && IS_AUDIO(tss->subtype)) || (tss->type == PES_PRIVATE1);
- is_sub = IS_SUB(tss->type);
- pid_type = pid_type_from_pmt(priv, pid);
-
- // PES CONTENT STARTS HERE
- if(! probe)
- {
- if((is_video || is_audio || is_sub) && is_start)
- ts_add_stream(demuxer, tss);
-
- if(is_video && (demuxer->video->id == priv->ts.streams[pid].id))
- {
- ds = demuxer->video;
-
- dp = &priv->fifo[1].pack;
- dp_offset = &priv->fifo[1].offset;
- buffer_size = &priv->fifo[1].buffer_size;
- si = &priv->vstr;
- }
- else if(is_audio && (demuxer->audio->id == priv->ts.streams[pid].id))
- {
- ds = demuxer->audio;
-
- dp = &priv->fifo[0].pack;
- dp_offset = &priv->fifo[0].offset;
- buffer_size = &priv->fifo[0].buffer_size;
- si = &priv->astr;
- }
- else if(is_sub)
- {
- sh_sub_t *sh_sub = demuxer->sub->sh;
-
- if(sh_sub && sh_sub->sid == tss->pid)
- {
- ds = demuxer->sub;
-
- dp = &priv->fifo[2].pack;
- dp_offset = &priv->fifo[2].offset;
- buffer_size = &priv->fifo[2].buffer_size;
- }
- else
- {
- stream_skip(stream, buf_size+junk);
- continue;
- }
- }
-
- //IS IT TIME TO QUEUE DATA to the dp_packet?
- if(is_start && (dp != NULL))
- {
- retv = fill_packet(demuxer, ds, dp, dp_offset, si);
- }
-
-
- if(dp && *dp == NULL)
- {
- if(*buffer_size > MAX_PACK_BYTES)
- *buffer_size = MAX_PACK_BYTES;
- *dp = new_demux_packet(*buffer_size); //es->size
- *dp_offset = 0;
- if(! *dp)
- {
- fprintf(stderr, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", *buffer_size);
- continue;
- }
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "CREATED DP(%d)\n", *buffer_size);
- }
- }
-
-
- if(probe || !dp) //dp is NULL for tables and sections
- {
- p = &packet[base];
- }
- else //feeding
- {
- if(*dp_offset + buf_size > *buffer_size)
- {
- *buffer_size = *dp_offset + buf_size + TS_FEC_PACKET_SIZE;
- resize_demux_packet(*dp, *buffer_size);
- }
- p = &((*dp)->buffer[*dp_offset]);
- }
-
- len = stream_read(stream, p, buf_size);
- if(len < buf_size)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "\r\nts_parse() couldn't read enough data: %d < %d\r\n", len, buf_size);
- continue;
- }
- stream_skip(stream, junk);
-
- if(pid == 0)
- {
- parse_pat(priv, is_start, p, buf_size);
- continue;
- }
- else if((tss->type == SL_SECTION) && pmt)
- {
- int k, mp4_es_id = -1;
- ts_section_t *section;
- for(k = 0; k < pmt->mp4es_cnt; k++)
- {
- if(pmt->mp4es[k].decoder.object_type == MP4_OD && pmt->mp4es[k].decoder.stream_type == MP4_OD)
- mp4_es_id = pmt->mp4es[k].id;
- }
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4ESID: %d\n", mp4_es_id);
- for(k = 0; k < pmt->es_cnt; k++)
- {
- if(pmt->es[k].mp4_es_id == mp4_es_id)
- {
- section = &(tss->section);
- parse_sl_section(pmt, section, is_start, &packet[base], buf_size);
- }
- }
- continue;
- }
- else
- {
- progid = prog_id_in_pat(priv, pid);
- if(progid != -1)
- {
- if(pid != demuxer->video->id && pid != demuxer->audio->id && pid != demuxer->sub->id)
- {
- parse_pmt(priv, progid, pid, is_start, &packet[base], buf_size);
- continue;
- }
- else
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Argh! Data pid %d used in the PMT, Skipping PMT parsing!\n", pid);
- }
- }
-
- if(!probe && !dp)
- continue;
-
- if(is_start)
- {
- uint8_t *lang = NULL;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "IS_START\n");
-
- len = pes_parse2(p, buf_size, es, pid_type, pmt, pid);
- if(! len)
- {
- tss->is_synced = 0;
- continue;
- }
- es->pid = tss->pid;
- tss->is_synced |= es->is_synced || rap_flag;
- tss->payload_size = es->payload_size;
-
- if((is_sub || is_audio) && (lang = pid_lang_from_pmt(priv, es->pid)))
- {
- memcpy(es->lang, lang, 3);
- es->lang[3] = 0;
- }
- else
- es->lang[0] = 0;
-
- if(probe)
- {
- if(es->type == UNKNOWN)
- return 0;
-
- tss->type = es->type;
- tss->subtype = es->subtype;
-
- return 1;
- }
- else
- {
- if(es->pts == 0.0)
- es->pts = tss->pts = tss->last_pts;
- else
- tss->pts = tss->last_pts = es->pts;
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "ts_parse, NEW pid=%d, PSIZE: %u, type=%X, start=%p, len=%d\n",
- es->pid, es->payload_size, es->type, es->start, es->size);
-
- demuxer->filepos = stream_tell(demuxer->stream) - es->size;
-
- if(es->size < 0 || es->size > buf_size) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "Broken ES packet size\n");
- es->size = 0;
- }
- memmove(p, es->start, es->size);
- *dp_offset += es->size;
- (*dp)->keyframe = 0;
- (*dp)->pos = stream_tell(demuxer->stream);
- (*dp)->pts = es->pts;
- // subtitle packets must be returned immediately if possible
- if (is_sub && !tss->payload_size)
- retv = fill_packet(demuxer, ds, dp, dp_offset, si);
-
- if(retv > 0)
- return retv;
- else
- continue;
- }
- }
- else
- {
- uint16_t sz;
-
- es->pid = tss->pid;
- es->type = tss->type;
- es->subtype = tss->subtype;
- es->pts = tss->pts = tss->last_pts;
- es->start = &packet[base];
-
-
- if(tss->payload_size > 0)
- {
- sz = FFMIN(tss->payload_size, buf_size);
- tss->payload_size -= sz;
- es->size = sz;
- }
- else
- {
- if(is_video)
- {
- sz = es->size = buf_size;
- }
- else
- {
- continue;
- }
- }
-
-
- if(! probe)
- {
- *dp_offset += sz;
-
- // subtitle packets must be returned immediately if possible
- if(*dp_offset >= MAX_PACK_BYTES || (is_sub && !tss->payload_size))
- {
- (*dp)->pts = tss->last_pts;
- retv = fill_packet(demuxer, ds, dp, dp_offset, si);
- return 1;
- }
-
- continue;
- }
- else
- {
- memmove(es->start, p, sz);
-
- if(es->size)
- return es->size;
- else
- continue;
- }
- }
- }
-
- return 0;
-}
-
-
-static void reset_fifos(demuxer_t *demuxer, int a, int v, int s)
-{
- ts_priv_t* priv = demuxer->priv;
- if(a)
- {
- if(priv->fifo[0].pack != NULL)
- {
- free_demux_packet(priv->fifo[0].pack);
- priv->fifo[0].pack = NULL;
- }
- priv->fifo[0].offset = 0;
- }
-
- if(v)
- {
- if(priv->fifo[1].pack != NULL)
- {
- free_demux_packet(priv->fifo[1].pack);
- priv->fifo[1].pack = NULL;
- }
- priv->fifo[1].offset = 0;
- }
-
- if(s)
- {
- if(priv->fifo[2].pack != NULL)
- {
- free_demux_packet(priv->fifo[2].pack);
- priv->fifo[2].pack = NULL;
- }
- priv->fifo[2].offset = 0;
- }
- demuxer->reference_clock = MP_NOPTS_VALUE;
-}
-
-
-static void demux_seek_ts(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
-{
- demux_stream_t *d_audio=demuxer->audio;
- demux_stream_t *d_video=demuxer->video;
- sh_audio_t *sh_audio=d_audio->sh;
- sh_video_t *sh_video=d_video->sh;
- ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
- int i, video_stats;
- off_t newpos;
-
- //================= seek in MPEG-TS ==========================
-
- ts_dump_streams(demuxer->priv);
- reset_fifos(demuxer, sh_audio != NULL, sh_video != NULL, demuxer->sub->id > 0);
-
- demux_flush(demuxer);
-
-
-
- video_stats = (sh_video != NULL);
- if(video_stats)
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "IBPS: %d, vb: %d\r\n", sh_video->i_bps, priv->vbitrate);
- if(priv->vbitrate)
- video_stats = priv->vbitrate;
- else
- video_stats = sh_video->i_bps;
- }
-
- newpos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : demuxer->filepos;
- if(flags & SEEK_FACTOR) // float seek 0..1
- newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
- else
- {
- // time seek (secs)
- if(! video_stats) // unspecified or VBR
- newpos += 2324*75*rel_seek_secs; // 174.3 kbyte/sec
- else
- newpos += video_stats*rel_seek_secs;
- }
-
-
- if(newpos < demuxer->movi_start)
- newpos = demuxer->movi_start; //begininng of stream
-
- stream_seek(demuxer->stream, newpos);
- for(i = 0; i < NB_PID_MAX; i++)
- if(priv->ts.pids[i] != NULL)
- priv->ts.pids[i]->is_synced = 0;
-
- videobuf_code_len = 0;
-
- if(sh_video != NULL)
- ds_fill_buffer(d_video);
-
- if(sh_audio != NULL)
- {
- ds_fill_buffer(d_audio);
- }
-
- while(sh_video != NULL)
- {
- if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts)
- {
- double a_pts=d_audio->pts;
- a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(double)sh_audio->i_bps;
- if(d_video->pts > a_pts)
- {
- skip_audio_frame(sh_audio); // sync audio
- continue;
- }
- }
-
-
- i = sync_video_packet(d_video);
- if((sh_video->format == VIDEO_MPEG1) || (sh_video->format == VIDEO_MPEG2))
- {
- if(i==0x1B3 || i==0x1B8) break; // found it!
- }
- else if((sh_video->format == VIDEO_MPEG4) && (i==0x1B6))
- break;
- else if(sh_video->format == VIDEO_VC1 && (i==0x10E || i==0x10F))
- break;
- else //H264
- {
- if((i & ~0x60) == 0x105 || (i & ~0x60) == 0x107) break;
- }
-
- if(!i || !skip_video_packet(d_video)) break; // EOF?
- }
-}
-
-
-static int demux_ts_fill_buffer(demuxer_t * demuxer, demux_stream_t *ds)
-{
- ES_stream_t es;
- ts_priv_t *priv = (ts_priv_t *)demuxer->priv;
-
- return -ts_parse(demuxer, &es, priv->packet, 0);
-}
-
-
-static int ts_check_file_dmx(demuxer_t *demuxer)
-{
- return ts_check_file(demuxer) ? DEMUXER_TYPE_MPEG_TS : 0;
-}
-
-static int is_usable_program(ts_priv_t *priv, pmt_t *pmt)
-{
- int j;
-
- for(j = 0; j < pmt->es_cnt; j++)
- {
- if(priv->ts.pids[pmt->es[j].pid] == NULL || priv->ts.streams[pmt->es[j].pid].sh == NULL)
- continue;
- if(
- priv->ts.streams[pmt->es[j].pid].type == TYPE_VIDEO ||
- priv->ts.streams[pmt->es[j].pid].type == TYPE_AUDIO
- )
- return 1;
- }
-
- return 0;
-}
-
-static int demux_ts_control(demuxer_t *demuxer, int cmd, void *arg)
-{
- ts_priv_t* priv = (ts_priv_t *)demuxer->priv;
-
- switch(cmd)
- {
- case DEMUXER_CTRL_SWITCH_AUDIO:
- case DEMUXER_CTRL_SWITCH_VIDEO:
- {
- void *sh = NULL;
- int i, n;
- int reftype, areset = 0, vreset = 0;
- demux_stream_t *ds;
-
- if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
- {
- reftype = TYPE_VIDEO;
- ds = demuxer->video;
- vreset = 1;
- }
- else
- {
- reftype = TYPE_AUDIO;
- ds = demuxer->audio;
- areset = 1;
- }
- n = *((int*)arg);
- if(n == -2)
- {
- reset_fifos(demuxer, areset, vreset, 0);
- ds->id = -2;
- ds->sh = NULL;
- ds_free_packs(ds);
- *((int*)arg) = ds->id;
- return DEMUXER_CTRL_OK;
- }
-
- if(n < 0)
- {
- for(i = 0; i < 8192; i++)
- {
- if(priv->ts.streams[i].id == ds->id && priv->ts.streams[i].type == reftype)
- break;
- }
-
- while(!sh)
- {
- i = (i+1) % 8192;
- if(priv->ts.streams[i].type == reftype)
- {
- if(priv->ts.streams[i].id == ds->id) //we made a complete loop
- break;
- sh = priv->ts.streams[i].sh;
- }
- }
- }
- else //audio track <n>
- {
- if (n >= 8192 || priv->ts.streams[n].type != reftype) return DEMUXER_CTRL_NOTIMPL;
- i = n;
- sh = priv->ts.streams[i].sh;
- }
-
- if(sh)
- {
- if(ds->id != priv->ts.streams[i].id)
- reset_fifos(demuxer, areset, vreset, 0);
- ds->id = priv->ts.streams[i].id;
- ds->sh = sh;
- ds_free_packs(ds);
- mp_msg(MSGT_DEMUX, MSGL_V, "\r\ndemux_ts, switched to audio pid %d, id: %d, sh: %p\r\n", i, ds->id, sh);
- }
-
- *((int*)arg) = ds->id;
- return DEMUXER_CTRL_OK;
- }
-
- case DEMUXER_CTRL_IDENTIFY_PROGRAM: //returns in prog->{aid,vid} the new ids that comprise a program
- {
- int i, j, cnt=0;
- int vid_done=0, aid_done=0;
- pmt_t *pmt = NULL;
- demux_program_t *prog = arg;
-
- if(priv->pmt_cnt < 2)
- return DEMUXER_CTRL_NOTIMPL;
-
- if(prog->progid == -1)
- {
- int cur_pmt_idx = 0;
-
- for(i = 0; i < priv->pmt_cnt; i++)
- if(priv->pmt[i].progid == priv->prog)
- {
- cur_pmt_idx = i;
- break;
- }
-
- i = (cur_pmt_idx + 1) % priv->pmt_cnt;
- while(i != cur_pmt_idx)
- {
- pmt = &priv->pmt[i];
- cnt = is_usable_program(priv, pmt);
- if(cnt)
- break;
- i = (i + 1) % priv->pmt_cnt;
- }
- }
- else
- {
- for(i = 0; i < priv->pmt_cnt; i++)
- if(priv->pmt[i].progid == prog->progid)
- {
- pmt = &priv->pmt[i]; //required program
- cnt = is_usable_program(priv, pmt);
- }
- }
-
- if(!cnt)
- return DEMUXER_CTRL_NOTIMPL;
-
- //finally some food
- prog->aid = prog->vid = -2; //no audio and no video by default
- for(j = 0; j < pmt->es_cnt; j++)
- {
- if(priv->ts.pids[pmt->es[j].pid] == NULL || priv->ts.streams[pmt->es[j].pid].sh == NULL)
- continue;
-
- if(!vid_done && priv->ts.streams[pmt->es[j].pid].type == TYPE_VIDEO)
- {
- vid_done = 1;
- prog->vid = pmt->es[j].pid;
- }
- else if(!aid_done && priv->ts.streams[pmt->es[j].pid].type == TYPE_AUDIO)
- {
- aid_done = 1;
- prog->aid = pmt->es[j].pid;
- }
- }
-
- priv->prog = prog->progid = pmt->progid;
- return DEMUXER_CTRL_OK;
- }
-
- default:
- return DEMUXER_CTRL_NOTIMPL;
- }
-}
-
-
-const demuxer_desc_t demuxer_desc_mpeg_ts = {
- "MPEG-TS demuxer",
- "mpegts",
- "TS",
- "Nico Sabbi",
- "",
- DEMUXER_TYPE_MPEG_TS,
- 0, // unsafe autodetect
- ts_check_file_dmx,
- demux_ts_fill_buffer,
- demux_open_ts,
- demux_close_ts,
- demux_seek_ts,
- demux_ts_control
-};
diff --git a/libmpdemux/demux_ts.h b/libmpdemux/demux_ts.h
deleted file mode 100644
index 37bddb86da..0000000000
--- a/libmpdemux/demux_ts.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_DEMUX_TS_H
-#define MPLAYER_DEMUX_TS_H
-
-#define TS_MAX_PROBE_SIZE 2000000
-
-#endif /* MPLAYER_DEMUX_TS_H */
diff --git a/libmpdemux/demux_ty.c b/libmpdemux/demux_ty.c
deleted file mode 100644
index 527d350bc6..0000000000
--- a/libmpdemux/demux_ty.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * tivo@wingert.org, February 2003
- *
- * Copyright (C) 2003 Christopher R. Wingert
- *
- * The license covers the portions of this file regarding TiVo additions.
- *
- * Olaf Beck and Tridge (indirectly) were essential at providing
- * information regarding the format of the TiVo streams.
- *
- * However, no code in the following subsection is directly copied from
- * either author.
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdarg.h>
-
-#include <libavutil/avstring.h>
-#include <libavutil/intreadwrite.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "libmpcodecs/dec_audio.h"
-#include "stream/stream.h"
-#include "demuxer.h"
-#ifdef DEMUX_TY_OSD
-#include "demux_ty_osd.h"
-#endif
-#include "parse_es.h"
-#include "stheader.h"
-#include "sub/sub_cc.h"
-#include "sub/sub.h"
-
-// 2/c0: audio data
-// 3/c0: audio packet header (PES header)
-// 4/c0: audio data (S/A only?)
-// 9/c0: audio packet header, AC-3 audio
-// 2/e0: video data
-// 6/e0: video packet header (PES header)
-// 7/e0: video sequence header start
-// 8/e0: video I-frame header start
-// a/e0: video P-frame header start
-// b/e0: video B-frame header start
-// c/e0: video GOP header start
-// e/01: closed-caption data
-// e/02: Extended data services data
-
-
-#define TIVO_PES_FILEID 0xf5467abd
-#define TIVO_PART_LENGTH 0x20000000
-
-#define CHUNKSIZE ( 128 * 1024 )
-#define MAX_AUDIO_BUFFER ( 16 * 1024 )
-
-#define TY_V 1
-#define TY_A 2
-
-typedef struct
-{
- off_t startOffset;
- off_t fileSize;
- int chunks;
-} tmf_fileParts;
-
-#define MAX_TMF_PARTS 16
-
-typedef struct
-{
- int whichChunk;
- unsigned char chunk[ CHUNKSIZE ];
-
- unsigned char lastAudio[ MAX_AUDIO_BUFFER ];
- int lastAudioEnd;
-
- int tivoType; // 1 = SA, 2 = DTiVo
-
- int64_t lastAudioPTS;
- int64_t lastVideoPTS;
-
- off_t size;
- int readHeader;
-
- int tmf;
- tmf_fileParts tmfparts[ MAX_TMF_PARTS ];
- int tmf_totalparts;
-} TiVoInfo;
-
-// ===========================================================================
-#define TMF_SIG "showing.xml"
-
-// ===========================================================================
-static int ty_tmf_filetoparts( demuxer_t *demux, TiVoInfo *tivo )
-{
- int parts = 0;
-
- stream_seek(demux->stream, 0);
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "Dumping tar contents\n" );
- while (!demux->stream->eof)
- {
- char header[ 512 ];
- char *name;
- char *extension;
- char *sizestr;
- int size;
- off_t skip;
- if (stream_read(demux->stream, header, 512) < 512)
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "Read bad\n" );
- break;
- }
- name = header;
- name[99] = 0;
- sizestr = &header[124];
- sizestr[11] = 0;
- size = strtol(sizestr, NULL, 8);
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "name %-20.20s size %-12.12s %d\n",
- name, sizestr, size );
-
- extension = strrchr(name, '.');
- if (extension && strcmp(extension, ".ty") == 0)
- {
- if ( parts >= MAX_TMF_PARTS ) {
- mp_msg( MSGT_DEMUX, MSGL_ERR, "ty:tmf too big\n" );
- break;
- }
- tivo->tmfparts[ parts ].fileSize = size;
- tivo->tmfparts[ parts ].startOffset = stream_tell(demux->stream);
- tivo->tmfparts[ parts ].chunks = size / CHUNKSIZE;
- mp_msg(MSGT_DEMUX, MSGL_DBG3,
- "tmf_filetoparts(): index %d, chunks %d\n"
- "tmf_filetoparts(): size %"PRId64"\n"
- "tmf_filetoparts(): startOffset %"PRId64"\n",
- parts, tivo->tmfparts[ parts ].chunks,
- tivo->tmfparts[ parts ].fileSize, tivo->tmfparts[ parts ].startOffset
- );
- parts++;
- }
-
- // size rounded up to blocks
- skip = (size + 511) & ~511;
- stream_skip(demux->stream, skip);
- }
- stream_reset(demux->stream);
- tivo->tmf_totalparts = parts;
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "tmf_filetoparts(): No More Part Files %d\n", parts );
-
- return 1;
-}
-
-
-// ===========================================================================
-static off_t tmf_filetooffset(TiVoInfo *tivo, int chunk)
-{
- int i;
- for (i = 0; i < tivo->tmf_totalparts; i++) {
- if (chunk < tivo->tmfparts[i].chunks)
- return tivo->tmfparts[i].startOffset + chunk * CHUNKSIZE;
- chunk -= tivo->tmfparts[i].chunks;
- }
- return -1;
-}
-
-
-// ===========================================================================
-static int tmf_load_chunk( demuxer_t *demux, TiVoInfo *tivo,
- unsigned char *buff, int readChunk )
-{
- off_t fileoffset;
- int count;
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "\ntmf_load_chunk() begin %d\n",
- readChunk );
-
- fileoffset = tmf_filetooffset(tivo, readChunk);
-
- if (fileoffset == -1 || !stream_seek(demux->stream, fileoffset)) {
- mp_msg( MSGT_DEMUX, MSGL_ERR, "Read past EOF()\n" );
- return 0;
- }
- count = stream_read( demux->stream, buff, CHUNKSIZE );
- demux->filepos = stream_tell( demux->stream );
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() count %x\n",
- count );
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "tmf_load_chunk() bytes %x %x %x %x %x %x %x %x\n",
- buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ],
- buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] );
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() end\n" );
-
- return count;
-}
-
-// ===========================================================================
-
-// DTiVo MPEG 336, 480, 576, 768
-// SA TiVo 864
-// DTiVo AC-3 1550
-//
-#define SERIES1_PTS_LENGTH 11
-#define SERIES1_PTS_OFFSET 6
-#define SERIES2_PTS_LENGTH 16
-#define SERIES2_PTS_OFFSET 9
-#define AC3_PTS_LENGTH 16
-#define AC3_PTS_OFFSET 9
-
-static int IsValidAudioPacket( int size, int *ptsOffset, int *ptsLen )
-{
- // AC-3
- if ( size == 1550 || size == 1552 )
- {
- *ptsOffset = AC3_PTS_OFFSET;
- *ptsLen = AC3_PTS_LENGTH;
- return 1;
- }
-
- // MPEG
- if ( (size & 15) == (SERIES1_PTS_LENGTH & 15) )
- {
- *ptsOffset = SERIES1_PTS_OFFSET;
- *ptsLen = SERIES1_PTS_LENGTH;
- return 1;
- }
- if ( (size & 15) == (SERIES2_PTS_LENGTH & 15) )
- {
- *ptsOffset = SERIES2_PTS_OFFSET;
- *ptsLen = SERIES2_PTS_LENGTH;
- return 1;
- }
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Tossing Audio Packet Size %d\n",
- size );
- return 0;
-}
-
-
-static int64_t get_ty_pts( unsigned char *buf )
-{
- int a = buf[0] & 0xe;
- int b = AV_RB16(buf + 1);
- int c = AV_RB16(buf + 3);
-
- if (!(1 & a & b & c)) // invalid MPEG timestamp
- return MP_NOPTS_VALUE;
- a >>= 1; b >>= 1; c >>= 1;
- return (((uint64_t)a) << 30) | (b << 15) | c;
-}
-
-static void demux_ty_AddToAudioBuffer( TiVoInfo *tivo, unsigned char *buffer,
- int size )
-{
- if ( tivo->lastAudioEnd + size < MAX_AUDIO_BUFFER )
- {
- memcpy( &tivo->lastAudio[ tivo->lastAudioEnd ],
- buffer, size );
- tivo->lastAudioEnd += size;
- }
- else
- mp_msg( MSGT_DEMUX, MSGL_ERR,
- "ty:WARNING - Would have blown my audio buffer\n" );
-}
-
-static void demux_ty_CopyToDemuxPacket( demux_stream_t *ds,
- unsigned char *buffer, int size, off_t pos, int64_t pts )
-{
- demux_packet_t *dp = new_demux_packet( size );
- memcpy( dp->buffer, buffer, size );
- if (pts != MP_NOPTS_VALUE)
- dp->pts = pts / 90000.0;
- dp->pos = pos;
- ds_add_packet( ds, dp );
-}
-
-static int demux_ty_FindESHeader( uint8_t nal,
- unsigned char *buffer, int bufferSize )
-{
- uint32_t search = 0x00000100 | nal;
- uint32_t found = -1;
- uint8_t *p = buffer;
- uint8_t *end = p + bufferSize;
- while (p < end) {
- found <<= 8;
- found |= *p++;
- if (found == search)
- return p - buffer - 4;
- }
- return -1;
-}
-
-static void demux_ty_FindESPacket( uint8_t nal,
- unsigned char *buffer, int bufferSize, int *esOffset1, int *esOffset2 )
-{
- *esOffset1 = demux_ty_FindESHeader(nal, buffer, bufferSize);
- if (*esOffset1 == -1) {
- *esOffset2 = -1;
- return;
- }
- buffer += *esOffset1 + 1;
- bufferSize -= *esOffset1 + 1;
- *esOffset2 = demux_ty_FindESHeader(nal, buffer, bufferSize);
- if (*esOffset2 != -1)
- *esOffset2 += *esOffset1 + 1;
-}
-
-#define VIDEO_NAL 0xe0
-#define AUDIO_NAL 0xc0
-#define AC3_NAL 0xbd
-
-static int demux_ty_fill_buffer( demuxer_t *demux, demux_stream_t *dsds )
-{
- int invalidType = 0;
- int errorHeader = 0;
- int recordsDecoded = 0;
-
- int readSize;
-
- int numberRecs;
- unsigned char *recPtr;
- int offset;
-
- int counter;
-
- int aid;
-
- TiVoInfo *tivo = demux->priv;
- unsigned char *chunk = tivo->chunk;
-
- if ( demux->stream->type == STREAMTYPE_DVD )
- return 0;
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" );
-
- if( demux->stream->eof ) return 0;
-
- // ======================================================================
- // If we haven't figured out the size of the stream, let's do so
- // ======================================================================
- if ( demux->stream->type == STREAMTYPE_VSTREAM )
- {
- // The vstream code figures out the exact size of the stream
- demux->movi_start = 0;
- demux->movi_end = demux->stream->end_pos;
- tivo->size = demux->stream->end_pos;
- }
- else
- {
- // If its a local file, try to find the Part Headers, so we can
- // calculate the ACTUAL stream size
- // If we can't find it, go off with the file size and hope the
- // extract program did the "right thing"
- if ( tivo->readHeader == 0 )
- {
- off_t filePos;
- tivo->readHeader = 1;
-
- filePos = demux->filepos;
- stream_seek( demux->stream, 0 );
-
- readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
-
- if ( memcmp( chunk, TMF_SIG, sizeof( TMF_SIG ) ) == 0 )
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Detected a tmf\n" );
- tivo->tmf = 1;
- ty_tmf_filetoparts( demux, tivo );
- readSize = tmf_load_chunk( demux, tivo, chunk, 0 );
- }
-
- if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID )
- {
- off_t numberParts;
-
- readSize = 0;
-
- if ( tivo->tmf != 1 )
- {
- off_t offset;
-
- numberParts = demux->stream->end_pos / TIVO_PART_LENGTH;
- offset = numberParts * TIVO_PART_LENGTH;
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty/ty+Number Parts %"PRId64"\n",
- (int64_t)numberParts );
-
- if ( offset + CHUNKSIZE < demux->stream->end_pos )
- {
- stream_seek( demux->stream, offset );
- readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
- }
- }
- else
- {
- numberParts = tivo->tmf_totalparts;
- offset = numberParts * TIVO_PART_LENGTH;
- readSize = tmf_load_chunk( demux, tivo, chunk,
- numberParts * ( TIVO_PART_LENGTH - CHUNKSIZE ) /
- CHUNKSIZE );
- }
-
- if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID )
- {
- int size = AV_RB24(chunk + 12);
- size -= 4;
- size *= CHUNKSIZE;
- tivo->size = numberParts * TIVO_PART_LENGTH;
- tivo->size += size;
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:Header Calc Stream Size %"PRId64"\n", tivo->size );
- }
- }
-
- if ( demux->stream->start_pos > 0 )
- filePos = demux->stream->start_pos;
- stream_seek( demux->stream, filePos );
- demux->filepos = stream_tell( demux->stream );
- tivo->whichChunk = filePos / CHUNKSIZE;
- }
- demux->movi_start = 0;
- demux->movi_end = tivo->size;
- }
-
- // ======================================================================
- // Give a clue as to where we are in the stream
- // ======================================================================
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:ty header size %"PRIx64"\n", (int64_t)tivo->size );
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:ty which Chunk %d\n", tivo->whichChunk );
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:file end_pos %"PRIx64"\n", (int64_t)demux->stream->end_pos );
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "\nty:wanted current offset %"PRIx64"\n", (int64_t)stream_tell( demux->stream ) );
-
- if ( tivo->size > 0 && stream_tell( demux->stream ) > tivo->size )
- {
- demux->stream->eof = 1;
- return 0;
- }
-
- do {
- if ( tivo->tmf != 1 )
- {
- // Make sure we are on a 128k boundary
- if ( demux->filepos % CHUNKSIZE != 0 )
- {
- int whichChunk = demux->filepos / CHUNKSIZE;
- if ( demux->filepos % CHUNKSIZE > CHUNKSIZE / 2 )
- whichChunk++;
- stream_seek( demux->stream, whichChunk * CHUNKSIZE );
- }
-
- demux->filepos = stream_tell( demux->stream );
- tivo->whichChunk = demux->filepos / CHUNKSIZE;
- readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
- if ( readSize != CHUNKSIZE )
- return 0;
- }
- else
- {
- readSize = tmf_load_chunk( demux, tivo, chunk, tivo->whichChunk );
- if ( readSize != CHUNKSIZE )
- return 0;
- tivo->whichChunk++;
- }
- if (AV_RB32(chunk) == TIVO_PES_FILEID)
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" );
- } while (AV_RB32(chunk) == TIVO_PES_FILEID);
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) -
- CHUNKSIZE );
-
-
- // Let's make a Video Demux Stream for MPlayer
- aid = 0x0;
- if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid );
- if( demux->video->id == -1 ) demux->video->id = aid;
- if( demux->video->id == aid )
- {
- demux_stream_t *ds = demux->video;
- if( !ds->sh ) ds->sh = demux->v_streams[ aid ];
- }
-
- // ======================================================================
- // Finally, we get to actually parse the chunk
- // ======================================================================
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty parsing a chunk\n" );
- numberRecs = chunk[ 0 ];
- recPtr = &chunk[ 4 ];
- offset = numberRecs * 16 + 4;
- for ( counter = 0 ; counter < numberRecs ; counter++ )
- {
- int size = AV_RB24(recPtr) >> 4;
- int type = recPtr[ 3 ];
- int nybbleType = recPtr[ 2 ] & 0x0f;
- recordsDecoded++;
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:Record Type %x/%x %d\n", nybbleType, type, size );
-
- // ================================================================
- // Video Parsing
- // ================================================================
- if ( type == 0xe0 )
- {
- if ( size > 0 && size + offset <= CHUNKSIZE )
- {
- int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ],
- size);
- if ( esOffset1 != -1 )
- tivo->lastVideoPTS = get_ty_pts(
- &chunk[ offset + esOffset1 + 9 ] );
-
- // Do NOT Pass the PES Header onto the MPEG2 Decode
- if( nybbleType != 0x06 )
- demux_ty_CopyToDemuxPacket( demux->video,
- &chunk[ offset ], size, demux->filepos + offset,
- tivo->lastVideoPTS );
- offset += size;
- }
- else
- errorHeader++;
- }
- // ================================================================
- // Audio Parsing
- // ================================================================
- else if ( type == 0xc0 )
- {
- if ( size > 0 && size + offset <= CHUNKSIZE )
- {
- if( demux->audio->id == -1 )
- {
- if ( nybbleType == 0x02 )
- continue; // DTiVo inconclusive, wait for more
- else if ( nybbleType == 0x09 )
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting AC-3 Audio\n" );
- aid = 0x80; // AC-3
- }
- else
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting MPEG Audio\n" );
- aid = 0x0; // MPEG Audio
- }
-
- demux->audio->id = aid;
- if( !demux->a_streams[ aid ] ) new_sh_audio( demux, aid );
- if( demux->audio->id == aid )
- {
- demux_stream_t *ds = demux->audio;
- if( !ds->sh ) {
- sh_audio_t* sh_a;
- ds->sh = demux->a_streams[ aid ];
- sh_a = (sh_audio_t*)ds->sh;
- switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
- case 0x00: sh_a->format=0x50;break; // mpeg
- case 0xA0: sh_a->format=0x10001;break; // dvd pcm
- case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
- else sh_a->format=0x2000;break; // ac3
- }
- }
- }
- }
-
- aid = demux->audio->id;
-
-
- // SA DTiVo Audio Data, no PES
- // ================================================
- if ( nybbleType == 0x02 || nybbleType == 0x04 )
- {
- if ( nybbleType == 0x02 && tivo->tivoType == 2 )
- demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );
- else
- {
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:Adding Audio Packet Size %d\n", size );
- demux_ty_CopyToDemuxPacket( demux->audio,
- &chunk[ offset ], size, ( demux->filepos + offset ),
- tivo->lastAudioPTS );
- }
- }
-
- // 3 - MPEG Audio with PES Header, either SA or DTiVo
- // 9 - DTiVo AC3 Audio Data with PES Header
- // ================================================
- if ( nybbleType == 0x03 || nybbleType == 0x09 )
- {
- int esOffset1, esOffset2;
- if ( nybbleType == 0x03 )
- esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ],
- size);
-
- // SA PES Header, No Audio Data
- // ================================================
- if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 )
- {
- tivo->tivoType = 1;
- tivo->lastAudioPTS = get_ty_pts( &chunk[ offset +
- SERIES2_PTS_OFFSET ] );
- }
- else
- // DTiVo Audio with PES Header
- // ================================================
- {
- tivo->tivoType = 2;
-
- demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );
- demux_ty_FindESPacket( nybbleType == 9 ? AC3_NAL : AUDIO_NAL,
- tivo->lastAudio, tivo->lastAudioEnd, &esOffset1,
- &esOffset2 );
-
- if ( esOffset1 != -1 && esOffset2 != -1 )
- {
- int packetSize = esOffset2 - esOffset1;
- int headerSize;
- int ptsOffset;
-
- if ( IsValidAudioPacket( packetSize, &ptsOffset,
- &headerSize ) )
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:Adding DTiVo Audio Packet Size %d\n",
- packetSize );
-
- tivo->lastAudioPTS = get_ty_pts(
- &tivo->lastAudio[ esOffset1 + ptsOffset ] );
-
- if (nybbleType == 9) headerSize = 0;
- demux_ty_CopyToDemuxPacket
- (
- demux->audio,
- &tivo->lastAudio[ esOffset1 + headerSize ],
- packetSize - headerSize,
- demux->filepos + offset,
- tivo->lastAudioPTS
- );
-
- }
-
- // Collapse the Audio Buffer
- tivo->lastAudioEnd -= esOffset2;
- memmove( &tivo->lastAudio[ 0 ],
- &tivo->lastAudio[ esOffset2 ],
- tivo->lastAudioEnd );
- }
- }
- }
-
- offset += size;
- }
- else
- errorHeader++;
- }
- // ================================================================
- // 1 = Closed Caption
- // 2 = Extended Data Services
- // ================================================================
- else if ( type == 0x01 || type == 0x02 )
- {
- unsigned char lastXDS[ 16 ];
- int b = AV_RB24(recPtr) >> 4;
- b &= 0x7f7f;
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b);
-
- lastXDS[ 0x00 ] = 0x00;
- lastXDS[ 0x01 ] = 0x00;
- lastXDS[ 0x02 ] = 0x01;
- lastXDS[ 0x03 ] = 0xb2;
- lastXDS[ 0x04 ] = 'T';
- lastXDS[ 0x05 ] = 'Y';
- lastXDS[ 0x06 ] = type;
- lastXDS[ 0x07 ] = b >> 8;
- lastXDS[ 0x08 ] = b;
- if ( subcc_enabled )
- demux_ty_CopyToDemuxPacket( demux->video, lastXDS, 0x09,
- demux->filepos + offset, tivo->lastVideoPTS );
- }
- // ================================================================
- // Unknown
- // ================================================================
- else
- {
- if ( size > 0 && size + offset <= CHUNKSIZE )
- offset += size;
- if (type != 3 && type != 5 && (type != 0 || size > 0)) {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Invalid Type %x\n", type );
- invalidType++;
- }
- }
- recPtr += 16;
- }
-
- if ( errorHeader > 0 || invalidType > 0 )
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "ty:Error Check - Records %d, Parsed %d, Errors %d + %d\n",
- numberRecs, recordsDecoded, errorHeader, invalidType );
-
- // Invalid MPEG ES Size Check
- if ( errorHeader > numberRecs / 2 )
- return 0;
-
- // Invalid MPEG Stream Type Check
- if ( invalidType > numberRecs / 2 )
- return 0;
- }
-
- demux->filepos = stream_tell( demux->stream );
-
- return 1;
-}
-
-static void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags )
-{
- demux_stream_t *d_audio = demuxer->audio;
- demux_stream_t *d_video = demuxer->video;
- sh_audio_t *sh_audio = d_audio->sh;
- sh_video_t *sh_video = d_video->sh;
- off_t newpos;
- off_t res;
- TiVoInfo *tivo = demuxer->priv;
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Seeking to %7.1f\n", rel_seek_secs );
-
- tivo->lastAudioEnd = 0;
- tivo->lastAudioPTS = MP_NOPTS_VALUE;
- tivo->lastVideoPTS = MP_NOPTS_VALUE;
- //
- //================= seek in MPEG ==========================
- demuxer->filepos = stream_tell( demuxer->stream );
-
- newpos = ( flags & SEEK_ABSOLUTE ) ? demuxer->movi_start : demuxer->filepos;
-
- if( flags & SEEK_FACTOR )
- // float seek 0..1
- newpos += ( demuxer->movi_end - demuxer->movi_start ) * rel_seek_secs;
- else
- {
- // time seek (secs)
- if( ! sh_video->i_bps ) // unspecified or VBR
- newpos += 2324 * 75 * rel_seek_secs; // 174.3 kbyte/sec
- else
- newpos += sh_video->i_bps * rel_seek_secs;
- }
-
- if ( newpos < demuxer->movi_start )
- {
- if( demuxer->stream->type != STREAMTYPE_VCD ) demuxer->movi_start = 0;
- if( newpos < demuxer->movi_start ) newpos = demuxer->movi_start;
- }
-
- res = newpos / CHUNKSIZE;
- if ( rel_seek_secs >= 0 )
- newpos = ( res + 1 ) * CHUNKSIZE;
- else
- newpos = res * CHUNKSIZE;
-
- if ( newpos < 0 )
- newpos = 0;
-
- tivo->whichChunk = newpos / CHUNKSIZE;
-
- stream_seek( demuxer->stream, newpos );
-
- // re-sync video:
- videobuf_code_len = 0; // reset ES stream buffer
-
- ds_fill_buffer( d_video );
- if( sh_audio )
- ds_fill_buffer( d_audio );
-
- while( 1 )
- {
- int i;
- if( sh_audio && !d_audio->eof && d_video->pts && d_audio->pts )
- {
- float a_pts = d_audio->pts;
- a_pts += ( ds_tell_pts( d_audio ) - sh_audio->a_in_buffer_len ) /
- (float)sh_audio->i_bps;
- if( d_video->pts > a_pts )
- {
- skip_audio_frame( sh_audio ); // sync audio
- continue;
- }
- }
- i = sync_video_packet( d_video );
- if( i == 0x1B3 || i == 0x1B8 ) break; // found it!
- if( !i || !skip_video_packet( d_video ) ) break; // EOF?
- }
-#ifdef DEMUX_TY_OSD
- if ( subcc_enabled )
- ty_ClearOSD( 0 );
-#endif
-}
-
-static int demux_ty_control( demuxer_t *demuxer,int cmd, void *arg )
-{
- demux_stream_t *d_video = demuxer->video;
- sh_video_t *sh_video = d_video->sh;
-
- switch(cmd)
- {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if(!sh_video->i_bps) // unspecified or VBR
- return DEMUXER_CTRL_DONTKNOW;
- *(double *)arg=
- (double)demuxer->movi_end-demuxer->movi_start/sh_video->i_bps;
- return DEMUXER_CTRL_GUESS;
-
- case DEMUXER_CTRL_GET_PERCENT_POS:
- return DEMUXER_CTRL_DONTKNOW;
- default:
- return DEMUXER_CTRL_NOTIMPL;
- }
-}
-
-
-static void demux_close_ty( demuxer_t *demux )
-{
- TiVoInfo *tivo = demux->priv;
-
- free( tivo );
- sub_justify = 0;
-}
-
-
-static int ty_check_file(demuxer_t* demuxer)
-{
- demuxer->filepos = 0;
- TiVoInfo *tivo = calloc(1, sizeof(TiVoInfo));
- demuxer->priv = tivo;
- return ds_fill_buffer(demuxer->video) ? DEMUXER_TYPE_MPEG_TY : 0;
-}
-
-
-static demuxer_t* demux_open_ty(demuxer_t* demuxer)
-{
- sh_audio_t *sh_audio=NULL;
- sh_video_t *sh_video=NULL;
-
- sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
-
- if(demuxer->audio->id!=-2) {
- if(!ds_fill_buffer(demuxer->audio)){
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "MPEG: %s",
- mp_gtext("No audio stream found -> no sound.\n"));
- demuxer->audio->sh=NULL;
- } else {
- sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
- }
- }
-
- return demuxer;
-}
-
-
-const demuxer_desc_t demuxer_desc_mpeg_ty = {
- "TiVo demuxer",
- "tivo",
- "TiVo",
- "Christopher R. Wingert",
- "Demux streams from TiVo",
- DEMUXER_TYPE_MPEG_TY,
- 0, // unsafe autodetect
- ty_check_file,
- demux_ty_fill_buffer,
- demux_open_ty,
- demux_close_ty,
- demux_seek_ty,
- demux_ty_control
-};
diff --git a/libmpdemux/demux_ty_osd.c b/libmpdemux/demux_ty_osd.c
deleted file mode 100644
index 983c243f98..0000000000
--- a/libmpdemux/demux_ty_osd.c
+++ /dev/null
@@ -1,911 +0,0 @@
-// Most of this was written by Mike Baker <mbm@linux.com>
-// and released under the GPL v2+ license.
-//
-// Modifications and SEVERE cleanup of the code was done by
-// Christopher Wingert
-// Copyright 2003
-//
-// Released under GPL2 License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-//#include "stream/stream.h"
-//#include "demuxer.h"
-//#include "parse_es.h"
-//#include "stheader.h"
-//#include "mp3_hdr.h"
-//#include "subreader.h"
-#include "sub/sub_cc.h"
-#include "sub/sub.h"
-#include "demux_ty_osd.h"
-
-//#include "dvdauth.h"
-
-extern int sub_justify;
-
-#define TY_TEXT_MODE ( 1 << 0 )
-#define TY_OSD_MODE ( 1 << 1 )
-
-static int TY_OSD_flags = TY_TEXT_MODE | TY_OSD_MODE;
-static int TY_OSD_debug = 0;
-
-// ===========================================================================
-// Closed Caption Decoding and OSD Presentation
-// ===========================================================================
-#define TY_CCNONE ( -3 )
-#define TY_CCTEXTMODE ( -2 )
-#define TY_CCPOPUPNB ( -1 )
-#define TY_CCPOPUP ( 0 )
-#define TY_CCPAINTON ( 1 )
-
-#define TY_CC_MAX_X ( 45 )
-
-static int TY_CC_CUR_X;
-static int TY_CC_CUR_Y;
-static int TY_CC_stat = TY_CCNONE;
-static char TY_CC_buf[ 255 ];
-static char *TY_CC_ptr = TY_CC_buf;
-static unsigned TY_CC_lastcap = 0;
-static int TY_CC_TextItalic;
-static int TY_CC_Y_Offset;
-
-static subtitle ty_OSD1;
-static subtitle ty_OSD2;
-static subtitle *ty_pOSD1;
-static subtitle *ty_pOSD2;
-static int tyOSDInitialized = 0;
-static int tyOSDUpdate = 0;
-
-static void ty_DrawOSD(void)
-{
- // printf( "Calling ty_DrawOSD()\n" );
- tyOSDUpdate = 1;
-}
-
-void ty_ClearOSD( int start )
-{
- int index;
- // printf( "Calling ty_ClearOSD()\n" );
- for ( index = start ; index < SUB_MAX_TEXT ; index++ )
- {
- memset( ty_OSD1.text[ index ], ' ', TY_CC_MAX_X - 1 );
- ty_OSD1.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
- memset( ty_OSD2.text[ index ], ' ', TY_CC_MAX_X - 1 );
- ty_OSD2.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
- }
-}
-
-static void ty_DrawChar( int *x, int *y, char disChar, int fgColor, int bgColor )
-{
- int cx;
- int cy;
-
- cx = *x;
- cy = *y;
-
- if ( *x >= ( TY_CC_MAX_X - 1 ) )
- {
- cx = 0;
- }
- if ( ( *y + TY_CC_Y_Offset ) > SUB_MAX_TEXT )
- {
- cy = SUB_MAX_TEXT - TY_CC_Y_Offset - 1;
- }
-
- // printf( "Calling ty_DrawChar() x:%d y:%d %c fg:%d bg:%d\n",
- // cx, cy, disChar, fgColor, bgColor );
-
- ty_OSD1.text[ TY_CC_Y_Offset + cy ][ cx ] = disChar;
- memset( &( ty_OSD1.text[ TY_CC_Y_Offset + cy ][ cx + 1 ] ), ' ',
- TY_CC_MAX_X - cx - 2 );
- ( *x )++;
-}
-
-static void ty_RollupBuf( int dest, int source, int numLines )
-{
- int index;
-
- // printf( "Calling ty_RollupBuf() dest:%d source %d, numLines %d\n",
- // dest, source, numLines );
- //
- if ( ( source + TY_CC_Y_Offset + numLines ) > SUB_MAX_TEXT )
- {
- ty_ClearOSD( 1 );
- return;
- }
-
- if ( ( source + TY_CC_Y_Offset + numLines ) < 0 )
- {
- ty_ClearOSD( 1 );
- return;
- }
-
- if ( numLines > SUB_MAX_TEXT )
- {
- ty_ClearOSD( 1 );
- return;
- }
-
- for ( index = 0 ; index < numLines ; index++ )
- {
- strcpy( ty_OSD1.text[ TY_CC_Y_Offset + dest ],
- ty_OSD1.text[ TY_CC_Y_Offset + source ] );
- dest++;
- source++;
- }
- memset( ty_OSD1.text[ TY_CC_Y_Offset + source - 1 ], ' ', TY_CC_MAX_X - 1 );
- ty_OSD1.text[ TY_CC_Y_Offset + source - 1 ][ TY_CC_MAX_X - 1 ] = 0;
-}
-
-static void ty_drawchar( char c )
-{
- if ( c < 2 ) return;
-
- if ( TY_OSD_flags & TY_OSD_MODE && TY_CC_stat != TY_CCNONE &&
- TY_CC_CUR_Y != -1 )
- ty_DrawChar( &TY_CC_CUR_X, &TY_CC_CUR_Y, c, 4, 13 );
-
- if ( TY_CC_ptr - TY_CC_buf > sizeof( TY_CC_buf ) - 1 )
- { // buffer overflow
- TY_CC_ptr = TY_CC_buf;
- memset( TY_CC_buf, 0, sizeof( TY_CC_buf ) );
- }
- *( TY_CC_ptr++ ) = ( c == 14 ) ? '/' : c; // swap a '/' for musical note
-}
-
-static void ty_draw(void)
-{
- if ( TY_CC_ptr != TY_CC_buf && TY_OSD_flags & TY_TEXT_MODE )
- {
- if ( *( TY_CC_ptr - 1 ) == '\n' ) *( TY_CC_ptr - 1 ) = 0;
-
- mp_msg( MSGT_DEMUX, MSGL_V, "CC: %s\n", TY_CC_buf );
- }
- TY_CC_lastcap = time( NULL );
-
- TY_CC_ptr = TY_CC_buf;
- memset( TY_CC_buf, 0, sizeof( TY_CC_buf) );
-
- if ( TY_OSD_flags & TY_OSD_MODE ) ty_DrawOSD();
- if ( TY_CC_TextItalic ) TY_CC_TextItalic = 0;
-}
-
-
-static int CC_last = 0;
-static char CC_mode = 0;
-static int CC_row[] =
-{
- 11, -1, 1, 2, 3, 4, 12, 13, 14, 15, 5, 6, 7, 8, 9, 10
-};
-
-// char specialchar[] = { '®', '°', '½', '¿', '*', '¢', '£', 14, 'à', ' ', 'è', 'â', 'ê', 'î', 'ô', 'û' };
-
-static int ty_CCdecode( char b1, char b2 )
-{
- int x;
- int data = ( b2 << 8 ) + b1;
-
- if ( b1 & 0x60 ) // text
- {
- if ( !TY_OSD_debug && TY_CC_stat == TY_CCNONE ) return 0;
- if ( TY_OSD_debug > 3 )
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "%c %c", b1, b2 );
- }
- ty_drawchar( b1 );
- ty_drawchar( b2 );
-
- if ( TY_CC_stat > 0 && TY_OSD_flags & TY_OSD_MODE ) ty_DrawOSD();
- }
- else if ( ( b1 & 0x10 ) && ( b2 > 0x1F ) && ( data != CC_last ) )
- {
- #define CURRENT ( ( b1 & 0x08 ) >> 3 )
-
- if ( CC_mode != CURRENT && TY_CC_stat != TY_CCNONE )
- {
- if ( TY_OSD_debug && TY_CC_ptr != TY_CC_buf ) ty_draw();
- TY_CC_stat = TY_CCNONE;
- return 0;
- }
-
- if ( TY_CC_stat == TY_CCNONE || TY_CC_CUR_Y == -1 )
- {
- if ( TY_CC_ptr != TY_CC_buf )
- {
- if ( TY_OSD_debug )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "(TY_OSD_debug) %s\n",
- TY_CC_buf );
- TY_CC_ptr = TY_CC_buf;
- memset(TY_CC_buf, 0, sizeof(TY_CC_buf));
- }
-
- if ( CC_mode != CURRENT ) return 0;
- }
-
- // preamble address code (row & indent)
- if ( b2 & 0x40 )
- {
- TY_CC_CUR_Y = CC_row[ ( ( b1 << 1 ) & 14 ) | ( ( b2 >> 5 ) & 1 ) ];
-
- // Offset into MPlayer's Buffer
- if ( ( TY_CC_CUR_Y >= 1 ) && ( TY_CC_CUR_Y <= 4 ) )
- {
- TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 1;
- }
- if ( ( TY_CC_CUR_Y >= 5 ) && ( TY_CC_CUR_Y <= 10 ) )
- {
- TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 5;
- }
- if ( ( TY_CC_CUR_Y >= 12 ) && ( TY_CC_CUR_Y <= 15 ) )
- {
- TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 12;
- }
-
- if ( TY_OSD_debug > 3 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "<< preamble %d >>\n", TY_CC_CUR_Y );
-
- // we still have something in the text buffer
- if (TY_CC_ptr != TY_CC_buf)
- {
- *(TY_CC_ptr++) = '\n';
- if ( TY_CC_TextItalic )
- {
- TY_CC_TextItalic = 0;
- }
- }
-
- TY_CC_CUR_X = 1;
- // row contains indent flag
- if ( b2 & 0x10 )
- {
- for ( x = 0 ; x < ( ( b2 & 0x0F ) << 1 ) ; x++ )
- {
- TY_CC_CUR_X++;
- *(TY_CC_ptr++) = ' ';
- }
- }
- }
- else
- // !(b2 & 0x40)
- {
- if ( TY_OSD_debug > 3 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "<< %02x >>\n", b1 & 0x7 );
- switch (b1 & 0x07)
- {
- case 0x00: // attribute
- {
- if ( TY_OSD_debug > 1 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "<<A: %d>>\n", b2 );
- break;
- }
- case 0x01: // midrow or char
- {
- switch (b2 & 0x70)
- {
- case 0x20: // midrow attribute change
- {
- switch (b2 & 0x0e)
- {
- case 0x00: // italics off
- {
- TY_CC_TextItalic = 0;
- *(TY_CC_ptr++) = ' ';
- break;
- }
- case 0x0e: // italics on
- {
- ty_drawchar(' ');
- TY_CC_TextItalic = 1;
- break;
- }
- default:
- {
- if ( TY_OSD_debug > 1 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "<<D: %d>>\n",
- b2 & 0x0e );
- }
- }
- if ( b2 & 0x01 )
- {
- // TextUnderline = 1;
- }
- else
- {
- // TextUnderline = 0;
- }
- break;
- }
- case 0x30: // special character..
- {
- // transparent space
- if ( ( b2 & 0x0f ) == 9 )
- {
- TY_CC_CUR_X++;
- *(TY_CC_ptr++) = ' ';
- }
- else
- {
- // ty_drawchar(specialchar[ b2 & 0x0f ] );
- ty_drawchar( ' ' );
- }
- break;
- }
- }
- break;
- }
-
- case 0x04: // misc
- case 0x05: // misc + F
- {
- if ( TY_OSD_debug > 3 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "<< misc %02x >>\n", b2 );
- switch ( b2 )
- {
- case 0x20: // resume caption (new caption)
- {
- if ( TY_OSD_flags & TY_OSD_MODE &&
- TY_CC_stat != TY_CCPOPUP )
- ty_ClearOSD( 1 );
- TY_CC_stat = TY_CCPOPUP;
- break;
- }
-
- case 0x21: // backspace
- {
- TY_CC_CUR_X--;
- break;
- }
-
- case 0x25: // 2-4 row captions
- case 0x26:
- case 0x27:
- {
- if ( TY_CC_stat == TY_CCPOPUP ) ty_ClearOSD( 1 );
- TY_CC_stat = b2 - 0x23;
- if ( TY_CC_CUR_Y < TY_CC_stat ) TY_CC_CUR_Y = TY_CC_stat;
- break;
- }
-
- case 0x29: // resume direct caption
- {
- TY_CC_stat = TY_CCPAINTON;
- break;
- }
-
- case 0x2A: // text restart
- {
- ty_draw();
- /* FALL */
- }
-
- case 0x2B: // resume text display
- {
- TY_CC_stat = TY_CCTEXTMODE;
- break;
- }
-
- case 0x2C: // erase displayed memory
- {
- TY_CC_lastcap = 0;
- if ( TY_OSD_flags & TY_OSD_MODE )
- {
- if ( TY_CC_stat > TY_CCPOPUP || TY_CC_ptr == TY_CC_buf )
- {
- ty_ClearOSD( 1 );
- ty_draw();
- }
- else
- {
- ty_ClearOSD( 1 );
-
- // CRW -
- // new buffer
- // Used to be a buffer swap here, dunno why
- }
- }
- break;
- }
-
- case 0x2D: // carriage return
- {
- ty_draw();
- TY_CC_CUR_X = 1;
- if ( TY_OSD_flags & TY_OSD_MODE )
- {
- if ( TY_CC_stat > TY_CCPAINTON )
- ty_RollupBuf
- (
- TY_CC_CUR_Y - TY_CC_stat + 1 ,
- TY_CC_CUR_Y - TY_CC_stat + 2,
- TY_CC_stat - 1
- );
- else
- TY_CC_CUR_Y++;
- }
- break;
- }
-
- case 0x2F: // end caption + swap memory
- {
- ty_draw();
- /* FALL THROUGH TO 0x2E */
- }
-
- case 0x2E: // erase non-displayed memory
- {
- if ( TY_OSD_debug && TY_CC_ptr != TY_CC_buf )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "(TY_OSD_debug) %s\n",
- TY_CC_buf );
- if ( TY_OSD_flags & TY_OSD_MODE ) ty_ClearOSD( 1 );
-
- TY_CC_CUR_X = 1;
- TY_CC_CUR_Y = -1;
-
- TY_CC_ptr = TY_CC_buf;
- memset( TY_CC_buf, 0, sizeof( TY_CC_buf ) );
- }
- }
- break;
- }
- case 0x07: // misc (TAB)
- {
- for ( x = 0 ; x < ( b2 - 0x20 ) ; x++ )
- TY_CC_CUR_X++;
- break;
- }
- }
- }
- }
- CC_last = data;
- return 0;
-}
-
-// ===========================================================================
-// Extended Data Service Decoding and OSD Presentation
-// ===========================================================================
-#define XDS_BUFFER_LENGTH ( 16 )
-#define XDS_DISPLAY_FRAMES ( 120 )
-static char *ty_XDS_Display[ XDS_BUFFER_LENGTH ];
-static int ty_XDSAddLine = -1;
-static int ty_XDSDisplayCount = -1;
-
-
-static void ty_AddXDSToDisplay( const char *format, ... )
-{
- char line[ 80 ];
- int index;
- va_list ap;
-
- if ( ty_XDSAddLine == -1 )
- {
- for( index = 0 ; index < XDS_BUFFER_LENGTH ; index++ )
- {
- ty_XDS_Display[ index ] = 0;
- }
- ty_XDSAddLine = 0;
- }
-
- va_start( ap, format );
- vsnprintf( line, 80, format, ap );
- va_end( ap );
- mp_msg( MSGT_DEMUX, MSGL_V, "XDS: %s\n", line );
-
- if ( ty_XDSAddLine == XDS_BUFFER_LENGTH )
- {
- mp_msg( MSGT_DEMUX, MSGL_ERR, "XDS Buffer would have been blown\n" );
- }
-
- if ( ty_XDS_Display[ ty_XDSAddLine ] != 0 )
- {
- free( ty_XDS_Display[ ty_XDSAddLine ] );
- ty_XDS_Display[ ty_XDSAddLine ] = 0;
- }
-
- ty_XDS_Display[ ty_XDSAddLine ] = malloc( strlen( line ) + 1 );
- strcpy( ty_XDS_Display[ ty_XDSAddLine ], line );
- ty_XDSAddLine++;
-}
-
-
-static void ty_DisplayXDSInfo(void)
-{
- int index;
- int size;
-
- if ( ty_XDSDisplayCount == -1 )
- {
- for( index = 0 ; index < XDS_BUFFER_LENGTH ; index++ )
- {
- if ( ty_XDS_Display[ index ] != 0 )
- {
- break;
- }
- }
- if ( index != XDS_BUFFER_LENGTH )
- {
- size = strlen( ty_XDS_Display[ index ] );
-
- // Right Justify the XDS Stuff
- memcpy( &( ty_OSD1.text[ 0 ][ TY_CC_MAX_X - size - 1 ] ),
- ty_XDS_Display[ index ], size );
- free( ty_XDS_Display[ index ] );
- ty_XDS_Display[ index ] = 0;
- ty_XDSDisplayCount = 0;
- tyOSDUpdate = 1;
-
- }
- else
- {
- // We cleaned out all the XDS stuff to be displayed
- ty_XDSAddLine = 0;
- }
- }
- else
- {
- // We displayed that piece of XDS information long enough
- // Let's move on
- ty_XDSDisplayCount++;
- if ( ty_XDSDisplayCount >= XDS_DISPLAY_FRAMES )
- {
- memset( ty_OSD1.text[ 0 ], ' ', TY_CC_MAX_X - 1 );
- ty_OSD1.text[ 0 ][ TY_CC_MAX_X - 1 ] = 0;
- ty_XDSDisplayCount = -1;
- tyOSDUpdate = 1;
- }
- }
-}
-
-
-static int TY_XDS_mode = 0;
-static int TY_XDS_type = 0;
-static int TY_XDS_length = 0;
-static char TY_XDS_checksum = 0;
-
-// Array of [ Mode ][ Type ][ Length ]
-static char TY_XDS [ 8 ][ 25 ][ 34 ];
-static char TY_XDS_new[ 8 ][ 25 ][ 34 ];
-
-// Array of [ MPAARating|TVRating ][ NumberRatings ]
-static const char * const TY_XDS_CHIP[ 2 ][ 8 ] =
-{
- { "(NOT APPLICABLE)", "G", "PG", "PG-13", "R", "NC-17", "X", "(NOT RATED)" },
- { "(NOT RATED)", "TV-Y", "TV-Y7", "TV-G", "TV-PG", "TV-14", "TV-MA",
- "(NOT RATED)" }
-};
-
-static const char * const TY_XDS_modes[] =
-{
- "CURRENT", // 01h-02h current program
- "FUTURE ", // 03h-04h future program
- "CHANNEL", // 05h-06h channel
- "MISC. ", // 07h-08h miscellaneous
- "PUBLIC ", // 09h-0Ah public service
- "RESERV.", // 0Bh-0Ch reserved
- "UNDEF. ",
- "INVALID",
- "INVALID",
- "INVALID"
-};
-
-static int ty_XDSdecode( char b1, char b2 )
-{
- char line[ 80 ];
-
- if ( b1 < 0x0F )
- { // start packet
- TY_XDS_length = 0;
- TY_XDS_mode = b1 >> 1; // every other mode is a resume
- TY_XDS_type = b2;
- TY_XDS_checksum = b1 + b2;
- return 0;
- }
-
- TY_XDS_checksum += b1 + b2;
-
- // eof (next byte is checksum)
- if ( b1 == 0x0F )
- {
- // validity check
- if ( !TY_XDS_length || TY_XDS_checksum & 0x7F )
- {
- if ( TY_OSD_debug > 3 && !TY_XDS_length )
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3,
- "%% TY_XDS CHECKSUM ERROR (ignoring)\n" );
- }
- else
- {
- TY_XDS_mode = 0;
- TY_XDS_type = 0;
- return 1;
- }
- }
-
- // check to see if the data has changed.
- if ( strncmp( TY_XDS[ TY_XDS_mode ][ TY_XDS_type ],
- TY_XDS_new[ TY_XDS_mode ][ TY_XDS_type ], TY_XDS_length - 1 ) )
- {
- char *TY_XDS_ptr = TY_XDS[ TY_XDS_mode ][ TY_XDS_type ];
-
- TY_XDS_ptr[ TY_XDS_length ] = 0;
- memcpy( TY_XDS[ TY_XDS_mode ][ TY_XDS_type ],
- TY_XDS_new[ TY_XDS_mode ][ TY_XDS_type ], TY_XDS_length );
-
- // nasty hack: only print time codes if seconds are 0
- if ( TY_XDS_mode == 3 && TY_XDS_type == 1 &&
- !( TY_XDS_new[ 3 ][ 1 ][ 3 ] & 0x20 ) )
- {
- return 0;
- }
- if ( TY_XDS_mode == 0 && TY_XDS_type == 2 &&
- ( TY_XDS_new[ 0 ][ 2 ][ 4 ] & 0x3f ) > 1 )
- {
- return 0;
- }
-
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "%% %s ", TY_XDS_modes[ TY_XDS_mode ] );
-
- line[ 0 ] = 0;
- // printf( "XDS Code %x\n",
- // ( TY_XDS_mode << 9 ) + TY_XDS_type + 0x100 );
- switch ( ( TY_XDS_mode << 9 ) + TY_XDS_type + 0x100 )
- {
- // cases are specified in 2 bytes hex representing mode, type.
- // TY_XDS_ptr will point to the current class buffer
- case 0x0101: // current
- case 0x0301: // future
- {
- char *mon[] =
- {
- "0", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
- "Aug", "Sep", "Oct", "Nov", "Dec", "13", "14", "15"
- };
- ty_AddXDSToDisplay( "AIR DATE: %s %2d %d:%02d:00",
- mon[ TY_XDS_ptr[ 3 ] & 0x0f ],
- TY_XDS_ptr[ 2 ] & 0x1f,
- TY_XDS_ptr[ 1 ] & 0x1f,
- TY_XDS_ptr[ 0 ] & 0x3f
- );
-
- // Program is tape delayed
- if ( TY_XDS_ptr[ 3 ] & 0x10 ) ty_AddXDSToDisplay( " TAPE" );
- }
- break;
-
- case 0x0102: // current program length
- case 0x0302: // future
- {
- ty_AddXDSToDisplay(
- "DURATION: %d:%02d:%02d of %d:%02d:%02d",
- TY_XDS_ptr[ 3 ] & 0x3f,
- TY_XDS_ptr[ 2 ] & 0x3f,
- TY_XDS_ptr[ 4 ] & 0x3f,
- TY_XDS_ptr[ 1 ] & 0x3f,
- TY_XDS_ptr[ 0 ] & 0x3f, 0);
- break;
- }
-
- case 0x0103: // current program name
- case 0x0303: // future
- {
- ty_AddXDSToDisplay( "TITLE: %s", TY_XDS_ptr );
- break;
- }
-
- case 0x0104: // current program type
- case 0x0304: // future
- {
- // for now just print out the raw data
- // requires a 127 string array to parse
- // properly and isn't worth it.
- sprintf ( line, "%sGENRE:", line );
- {
- int x;
- for ( x = 0 ; x < TY_XDS_length ; x++ )
- sprintf( line, "%s %02x", line, TY_XDS_ptr[ x ] );
- }
- ty_AddXDSToDisplay( line );
- break;
- }
-
- case 0x0105: // current program rating
- case 0x0305: // future
- {
- sprintf( line, "%sRATING: %s", line,
- TY_XDS_CHIP[ ( TY_XDS_ptr[ 0 ] & 0x08 ) >> 3 ]
- [ TY_XDS_ptr[ 1 ] & 0x07 ] );
- if ( TY_XDS_ptr[ 0 ] & 0x20 )
- sprintf( line, "%s DIALOGUE", line );
- if ( TY_XDS_ptr[ 1 ] & 0x08 )
- sprintf( line, "%s LANGUAGE", line );
- if ( TY_XDS_ptr[ 1 ] & 0x10 )
- sprintf( line, "%s SEXUAL", line );
- if ( TY_XDS_ptr[ 1 ] & 0x20 )
- sprintf( line, "%s VIOLENCE", line );
- ty_AddXDSToDisplay( line );
-
- // raw output for verification.
- if ( TY_OSD_debug > 1 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, " (%02x %02x)",
- TY_XDS_ptr[ 0 ], TY_XDS_ptr[ 1 ] );
- break;
- }
-
- case 0x0106: // current program audio services
- case 0x0306: // future
- {
- // requires table, never actually seen it used either
- ty_AddXDSToDisplay( "AUDIO: %02x %02x", TY_XDS_ptr[ 0 ],
- TY_XDS_ptr[ 1 ] );
- break;
- }
-
- case 0x0109: // current program aspect ratio
- case 0x0309: // future
- {
- // requires table, rare
- ty_AddXDSToDisplay( "ASPECT: %02x %02x",
- TY_XDS_ptr[ 0 ], TY_XDS_ptr[ 1 ] );
- break;
- }
-
- case 0x0110: // program description
- case 0x0111:
- case 0x0112:
- case 0x0113:
- case 0x0114:
- case 0x0115:
- case 0x0116:
- case 0x0117:
- {
- ty_AddXDSToDisplay( "DESCRIP: %s", TY_XDS_ptr );
- break;
- }
-
- case 0x0501: // channel network name
- {
- ty_AddXDSToDisplay( "NETWORK: %s", TY_XDS_ptr );
- break;
- }
-
- case 0x0502: // channel network call letters
- {
- ty_AddXDSToDisplay( "CALLSIGN: %s", TY_XDS_ptr );
- break;
- }
-
- case 0x0701: // misc. time of day
- {
-#define TIMEZONE ( TY_XDS[ 3 ][ 4 ][ 0 ] & 0x1f )
-#define DST ( ( TY_XDS[ 3 ][ 4 ][ 0 ] & 0x20 ) >> 5 )
- struct tm tm =
- {
- .tm_sec = 0, // sec
- .tm_min = ( TY_XDS_ptr[ 0 ] & 0x3F ), // min
- .tm_hour = ( TY_XDS_ptr[ 1 ] & 0x1F ), // hour
- .tm_mday = ( TY_XDS_ptr[ 2 ] & 0x1F ), // day
- .tm_mon = ( TY_XDS_ptr[ 3 ] & 0x1f ) - 1, // month
- .tm_year = ( TY_XDS_ptr[ 5 ] & 0x3f ) + 90, // year
- .tm_wday = 0, // day of week
- .tm_yday = 0, // day of year
- .tm_isdst = 0, // DST
- };
-
- time_t time_t = mktime( &tm );
- char *timestr;
-
- time_t -= ( ( TIMEZONE - DST ) * 60 * 60 );
- timestr = ctime( &time_t );
- timestr[ strlen( timestr ) - 1 ] = 0;
-
- sprintf( line, "%sCUR.TIME: %s ", line, timestr );
- if ( TY_XDS[ 3 ][ 4 ][ 0 ] )
- {
- sprintf( line, "%sUTC-%d", line, TIMEZONE );
- if (DST) sprintf( line, "%s DST", line );
- }
- else
- sprintf( line, "%sUTC", line );
-
- ty_AddXDSToDisplay( line );
-
- break;
- }
-
- case 0x0704: //misc. local time zone
- {
- sprintf( line, "%sTIMEZONE: UTC-%d",
- line, TY_XDS_ptr[ 0 ] & 0x1f );
- if ( TY_XDS_ptr[ 0 ] & 0x20 ) sprintf( line, "%s DST", line );
- ty_AddXDSToDisplay( line );
- break;
- }
-
- default:
- {
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "UNKNOWN CLASS %d TYPE %d",
- ( TY_XDS_mode << 1 ) + 1, TY_XDS_type );
- if ( TY_OSD_debug > 1 )
- {
- int x;
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "\nDUMP:\n" );
- for ( x = 0 ; x < TY_XDS_length ; x++ )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, " %02x %c",
- TY_XDS_ptr[ x ], TY_XDS_ptr[ x ] );
- mp_msg( MSGT_DEMUX, MSGL_DBG3, "\n" );
- }
- }
- }
- if ( TY_OSD_debug > 1 )
- mp_msg( MSGT_DEMUX, MSGL_DBG3, " (%d)", TY_XDS_length );
- }
- TY_XDS_mode = 0;
- TY_XDS_type = 0;
- }
- else if ( TY_XDS_length < 34 )
- {
- TY_XDS_new[ TY_XDS_mode ][ TY_XDS_type ][ TY_XDS_length++ ] = b1;
- TY_XDS_new[ TY_XDS_mode ][ TY_XDS_type ][ TY_XDS_length++ ] = b2;
- }
- return 0;
-}
-
-
-// ===========================================================================
-// Callback from Video Display Processing to put up the OSD
-// ===========================================================================
-void ty_processuserdata( const unsigned char* buf, int len )
-{
- int index;
-
- sub_justify = 1;
-
- if ( subcc_enabled )
- {
- if ( tyOSDInitialized == 0 )
- {
- for ( index = 0; index < SUB_MAX_TEXT ; index++ )
- {
- ty_OSD1.text[ index ] = malloc( TY_CC_MAX_X );
- ty_OSD2.text[ index ] = malloc( TY_CC_MAX_X );
- }
- ty_ClearOSD( 0 );
- ty_OSD1.lines = SUB_MAX_TEXT;
- ty_OSD2.lines = SUB_MAX_TEXT;
- ty_pOSD1 = &ty_OSD1;
- ty_pOSD2 = &ty_OSD2;
- tyOSDUpdate = 0;
- tyOSDInitialized = 1;
- }
-
- if ( buf[ 0 ] == 0x01 )
- {
- ty_CCdecode( buf[ 1 ], buf[ 2 ] );
- }
- if ( buf[ 0 ] == 0x02 )
- {
- ty_XDSdecode( buf[ 1 ], buf[ 2 ] );
- }
-
- ty_DisplayXDSInfo();
-
- if ( tyOSDUpdate )
- {
- // for ( index = 0; index < SUB_MAX_TEXT ; index++ )
- // {
- // printf( "OSD:%d:%s\n", index, ty_OSD1.text[ index ] );
- // }
- vo_sub = &ty_OSD1;
- vo_osd_changed( OSDTYPE_SUBTITLE );
- tyOSDUpdate = 0;
- }
- }
-}
diff --git a/libmpdemux/demux_ty_osd.h b/libmpdemux/demux_ty_osd.h
deleted file mode 100644
index ce0af05788..0000000000
--- a/libmpdemux/demux_ty_osd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_DEMUX_TY_OSD_H
-#define MPLAYER_DEMUX_TY_OSD_H
-
-void ty_ClearOSD(int start);
-void ty_processuserdata(const unsigned char *buf, int len);
-
-#endif /* MPLAYER_DEMUX_TY_OSD_H */
diff --git a/libmpdemux/demux_vqf.c b/libmpdemux/demux_vqf.c
deleted file mode 100644
index 051e912339..0000000000
--- a/libmpdemux/demux_vqf.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <libavutil/common.h>
-#include <libavutil/intreadwrite.h>
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-#include "libmpcodecs/vqf.h"
-
-static int demux_probe_vqf(demuxer_t* demuxer)
-{
- char buf[KEYWORD_BYTES];
- stream_t *s;
- s = demuxer->stream;
- if(stream_read(s,buf,KEYWORD_BYTES)!=KEYWORD_BYTES)
- return 0;
- if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return DEMUXER_TYPE_VQF; /*version: 97012000*/
- return 0;
-}
-
-static demuxer_t* demux_open_vqf(demuxer_t* demuxer) {
- sh_audio_t* sh_audio;
- WAVEFORMATEX* w;
- stream_t *s;
- headerInfo *hi;
-
- s = demuxer->stream;
-
- sh_audio = new_sh_audio(demuxer,0);
- sh_audio->wf = w = calloc(1, sizeof(*sh_audio->wf)+sizeof(headerInfo));
- hi = (headerInfo *)&w[1];
- w->wFormatTag = 0x1;
- sh_audio->format = mmioFOURCC('T','W','I','N'); /* TWinVQ */
- w->nChannels = sh_audio->channels = 2;
- w->nSamplesPerSec = sh_audio->samplerate = 44100;
- w->nAvgBytesPerSec = w->nSamplesPerSec*sh_audio->channels*2;
- w->nBlockAlign = 0;
- sh_audio->samplesize = 2;
- w->wBitsPerSample = 8*sh_audio->samplesize;
- w->cbSize = 0;
- strcpy(hi->ID,"TWIN");
- stream_read(s,hi->ID+KEYWORD_BYTES,VERSION_BYTES); /* fourcc+version_id */
- while(1)
- {
- char chunk_id[4];
- unsigned chunk_size;
- hi->size=chunk_size=stream_read_dword(s); /* include itself */
- stream_read(s,chunk_id,4);
- if (chunk_size < 8) return NULL;
- chunk_size -= 8;
- if(AV_RL32(chunk_id)==mmioFOURCC('C','O','M','M'))
- {
- char buf[BUFSIZ];
- unsigned i,subchunk_size;
- if (chunk_size > sizeof(buf) || chunk_size < 20) return NULL;
- if(stream_read(s,buf,chunk_size)!=chunk_size) return NULL;
- i=0;
- subchunk_size = AV_RB32(buf);
- hi->channelMode = AV_RB32(buf + 4);
- w->nChannels=sh_audio->channels=hi->channelMode+1; /*0-mono;1-stereo*/
- hi->bitRate = AV_RB32(buf + 8);
- sh_audio->i_bps=hi->bitRate*1000/8; /* bitrate kbit/s */
- w->nAvgBytesPerSec = sh_audio->i_bps;
- hi->samplingRate = AV_RB32(buf + 12);
- switch(hi->samplingRate){
- case 44:
- w->nSamplesPerSec=44100;
- break;
- case 22:
- w->nSamplesPerSec=22050;
- break;
- case 11:
- w->nSamplesPerSec=11025;
- break;
- default:
- w->nSamplesPerSec=hi->samplingRate*1000;
- break;
- }
- sh_audio->samplerate=w->nSamplesPerSec;
- hi->securityLevel = AV_RB32(buf + 16);
- w->nBlockAlign = 0;
- sh_audio->samplesize = 4;
- w->wBitsPerSample = 8*sh_audio->samplesize;
- w->cbSize = 0;
- if (subchunk_size > chunk_size - 4) continue;
- i+=subchunk_size+4;
- while(i + 8 < chunk_size)
- {
- unsigned slen,sid;
- char sdata[BUFSIZ];
- sid = AV_RL32(buf + i); i+=4;
- slen = AV_RB32(buf + i); i+=4;
- if (slen > sizeof(sdata) - 1 || slen > chunk_size - i) break;
- if(sid==mmioFOURCC('D','S','I','Z'))
- {
- hi->Dsiz=AV_RB32(buf + i);
- continue; /* describes the same info as size of DATA chunk */
- }
- memcpy(sdata,&buf[i],slen); sdata[slen]=0; i+=slen;
- if(sid==mmioFOURCC('N','A','M','E'))
- {
- memcpy(hi->Name,sdata,FFMIN(BUFSIZ,slen));
- demux_info_add(demuxer,"Title",sdata);
- }
- else
- if(sid==mmioFOURCC('A','U','T','H'))
- {
- memcpy(hi->Auth,sdata,FFMIN(BUFSIZ,slen));
- demux_info_add(demuxer,"Author",sdata);
- }
- else
- if(sid==mmioFOURCC('C','O','M','T'))
- {
- memcpy(hi->Comt,sdata,FFMIN(BUFSIZ,slen));
- demux_info_add(demuxer,"Comment",sdata);
- }
- else
- if(sid==mmioFOURCC('(','c',')',' '))
- {
- memcpy(hi->Cpyr,sdata,FFMIN(BUFSIZ,slen));
- demux_info_add(demuxer,"Copyright",sdata);
- }
- else
- if(sid==mmioFOURCC('F','I','L','E'))
- {
- memcpy(hi->File,sdata,FFMIN(BUFSIZ,slen));
- }
- else
- if(sid==mmioFOURCC('A','L','B','M')) demux_info_add(demuxer,"Album",sdata);
- else
- if(sid==mmioFOURCC('Y','E','A','R')) demux_info_add(demuxer,"Date",sdata);
- else
- if(sid==mmioFOURCC('T','R','A','C')) demux_info_add(demuxer,"Track",sdata);
- else
- if(sid==mmioFOURCC('E','N','C','D')) demux_info_add(demuxer,"Encoder",sdata);
- else
- mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled subchunk '%c%c%c%c'='%s'\n",((char *)&sid)[0],((char *)&sid)[1],((char *)&sid)[2],((char *)&sid)[3],sdata);
- /* rest not recognized due to untranslatable Japanese expressions */
- }
- }
- else
- if(AV_RL32(chunk_id)==mmioFOURCC('D','A','T','A'))
- {
- demuxer->movi_start=stream_tell(s);
- demuxer->movi_end=demuxer->movi_start+chunk_size;
- mp_msg(MSGT_DEMUX, MSGL_V, "Found data at %"PRIX64" size %"PRIu64"\n",demuxer->movi_start,demuxer->movi_end);
- /* Done! play it */
- break;
- }
- else
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled chunk '%c%c%c%c' %u bytes\n",chunk_id[0],chunk_id[1],chunk_id[2],chunk_id[3],chunk_size);
- stream_skip(s,chunk_size); /*unknown chunk type */
- }
- }
-
- demuxer->audio->id = 0;
- demuxer->audio->sh = sh_audio;
- sh_audio->ds = demuxer->audio;
- stream_seek(s,demuxer->movi_start);
- demuxer->seekable=0;
- return demuxer;
-}
-
-static int demux_vqf_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
- sh_audio_t* sh_audio = demuxer->audio->sh;
- int l = sh_audio->wf->nAvgBytesPerSec;
- off_t spos = stream_tell(demuxer->stream);
- demux_packet_t* dp;
-
- if(stream_eof(demuxer->stream))
- return 0;
-
- dp = new_demux_packet(l);
- ds->pts = spos / (float)(sh_audio->wf->nAvgBytesPerSec);
- ds->pos = spos;
-
- l=stream_read(demuxer->stream,dp->buffer,l);
- resize_demux_packet(dp,l);
- ds_add_packet(ds,dp);
-
- return 1;
-}
-
-static void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
-#if 0
- stream_t* s = demuxer->stream;
- sh_audio_t* sh_audio = demuxer->audio->sh;
- off_t base,pos;
-
- base = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s);
- if(flags & SEEK_FACTOR)
- pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs);
- else
- pos = base + (rel_seek_secs*sh_audio->i_bps);
-
- pos -= (pos % (sh_audio->channels * sh_audio->samplesize) );
- stream_seek(s,pos);
-#endif
-}
-
-static void demux_close_vqf(demuxer_t* demuxer) {}
-
-
-const demuxer_desc_t demuxer_desc_vqf = {
- "TwinVQ demuxer",
- "vqf",
- "VQF",
- "Nick Kurshev",
- "ported from MPlayerXP",
- DEMUXER_TYPE_VQF,
- 1, // safe autodetect
- demux_probe_vqf,
- demux_vqf_fill_buffer,
- demux_open_vqf,
- demux_close_vqf,
- demux_seek_vqf,
- NULL
-};
diff --git a/libmpdemux/demux_y4m.c b/libmpdemux/demux_y4m.c
deleted file mode 100644
index cf0f7cf7e6..0000000000
--- a/libmpdemux/demux_y4m.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Y4M file parser
- * copyright (c) 2001 Rik Snel
- * (using yuv4mpeg*.[ch] from mjpeg.sourceforge.net)
- * (derived from demux_viv.c)
- * older YUV4MPEG (used by xawtv) support by Alex Beregszaszi
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h> /* strtok */
-
-#include "config.h"
-#include "mp_msg.h"
-#include "yuv4mpeg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-typedef struct {
- int framenum;
- y4m_stream_info_t* si;
- int is_older;
-} y4m_priv_t;
-
-static int y4m_check_file(demuxer_t* demuxer){
- int orig_pos = stream_tell(demuxer->stream);
- char buf[10];
- y4m_priv_t* priv;
-
- mp_msg(MSGT_DEMUX, MSGL_V, "Checking for YUV4MPEG2\n");
-
- if(stream_read(demuxer->stream, buf, 9)!=9)
- return 0;
-
- buf[9] = 0;
-
- if (strncmp("YUV4MPEG2", buf, 9) && strncmp("YUV4MPEG ", buf, 9)) {
- return 0;
- }
-
- demuxer->priv = malloc(sizeof(y4m_priv_t));
- priv = demuxer->priv;
-
- priv->is_older = 0;
-
- if (!strncmp("YUV4MPEG ", buf, 9))
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "Found older YUV4MPEG format (used by xawtv)\n");
- priv->is_older = 1;
- }
-
- mp_msg(MSGT_DEMUX,MSGL_DBG2,"Success: YUV4MPEG2\n");
-
- stream_seek(demuxer->stream, orig_pos);
-
- return DEMUXER_TYPE_Y4M;
-}
-
-static void read_streaminfo(demuxer_t *demuxer);
-
-// return value:
-// 0 = EOF or no stream found
-// 1 = successfully read a packet
-static int demux_y4m_fill_buffer(demuxer_t *demux, demux_stream_t *dsds) {
- demux_stream_t *ds=demux->video;
- demux_packet_t *dp;
- y4m_priv_t *priv=demux->priv;
- y4m_frame_info_t fi;
- unsigned char *buf[3];
- int err, size;
- int nextc;
-
- // Concatenated stream check; only done if seekable so skip(-1) works
- if (demux->stream->flags & MP_STREAM_SEEK_BW) {
- nextc = stream_read_char(demux->stream);
- stream_skip(demux->stream, -1);
- if (nextc == 'Y') {
- read_streaminfo(demux);
- demux->seekable = 0;
- }
- }
-
- y4m_init_frame_info(&fi);
-
- demux->filepos=stream_tell(demux->stream);
-
- size = ((sh_video_t*)ds->sh)->disp_w*((sh_video_t*)ds->sh)->disp_h;
-
- dp = new_demux_packet(3*size/2);
-
- /* swap U and V components */
- buf[0] = dp->buffer;
- buf[1] = dp->buffer + 5*size/4;
- buf[2] = dp->buffer + size;
-
- if (priv->is_older)
- {
- int c;
-
- c = stream_read_char(demux->stream); /* F */
- if (c == -256)
- return 0; /* EOF */
- if (c != 'F')
- {
- mp_msg(MSGT_DEMUX, MSGL_V, "Bad frame at %d\n", (int)stream_tell(demux->stream)-1);
- return 0;
- }
- stream_skip(demux->stream, 5); /* RAME\n */
- stream_read(demux->stream, buf[0], size);
- stream_read(demux->stream, buf[1], size/4);
- stream_read(demux->stream, buf[2], size/4);
- }
- else
- {
- if ((err=y4m_read_frame(demux->stream, priv->si, &fi, buf)) != Y4M_OK) {
- mp_msg(MSGT_DEMUX, MSGL_ERR, "error reading frame %s\n", y4m_strerr(err));
- return 0;
- }
- }
-
- /* This seems to be the right way to calculate the presentation time stamp */
- dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps;
- priv->framenum++;
- dp->pos=demux->filepos;
- ds_add_packet(ds, dp);
-
- return 1;
-}
-
-static void read_streaminfo(demuxer_t *demuxer)
-{
- y4m_priv_t *priv = demuxer->priv;
- sh_video_t *sh = demuxer->video->sh;
- y4m_ratio_t ratio;
- int err;
-
- if (priv->is_older)
- {
- char buf[4];
- int frame_rate_code;
-
- stream_skip(demuxer->stream, 8); /* YUV4MPEG */
- stream_skip(demuxer->stream, 1); /* space */
- stream_read(demuxer->stream, (char *)&buf[0], 3);
- buf[3] = 0;
- sh->disp_w = atoi(buf);
- stream_skip(demuxer->stream, 1); /* space */
- stream_read(demuxer->stream, (char *)&buf[0], 3);
- buf[3] = 0;
- sh->disp_h = atoi(buf);
- stream_skip(demuxer->stream, 1); /* space */
- stream_read(demuxer->stream, (char *)&buf[0], 1);
- buf[1] = 0;
- frame_rate_code = atoi(buf);
- stream_skip(demuxer->stream, 1); /* new-line */
-
- if (!sh->fps)
- {
- /* values from xawtv */
- switch(frame_rate_code)
- {
- case 1:
- sh->fps = 23.976f;
- break;
- case 2:
- sh->fps = 24.0f;
- break;
- case 3:
- sh->fps = 25.0f;
- break;
- case 4:
- sh->fps = 29.97f;
- break;
- case 5:
- sh->fps = 30.0f;
- break;
- case 6:
- sh->fps = 50.0f;
- break;
- case 7:
- sh->fps = 59.94f;
- break;
- case 8:
- sh->fps = 60.0f;
- break;
- default:
- sh->fps = 25.0f;
- }
- }
- sh->frametime = 1.0f/sh->fps;
- }
- else
- {
- y4m_init_stream_info(priv->si);
- if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK)
- mp_msg(MSGT_DEMUXER, MSGL_FATAL, "error parsing YUV4MPEG header: %s\n", y4m_strerr(err));
-
- if(!sh->fps) {
- ratio = y4m_si_get_framerate(priv->si);
- if (ratio.d != 0)
- sh->fps=(float)ratio.n/(float)ratio.d;
- else
- sh->fps=15.0f;
- }
- sh->frametime=1.0f/sh->fps;
-
- ratio = y4m_si_get_sampleaspect(priv->si);
-
- sh->disp_w = y4m_si_get_width(priv->si);
- sh->disp_h = y4m_si_get_height(priv->si);
-
- if (ratio.d != 0 && ratio.n != 0)
- sh->aspect = (float)(sh->disp_w*ratio.n)/(float)(sh->disp_h*ratio.d);
-
- demuxer->seekable = 0;
- }
-
- sh->format = mmioFOURCC('Y', 'V', '1', '2');
-
- sh->bih->biSize=40;
- sh->bih->biWidth = sh->disp_w;
- sh->bih->biHeight = sh->disp_h;
- sh->bih->biPlanes=3;
- sh->bih->biBitCount=12;
- sh->bih->biCompression=sh->format;
- sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3/2; /* YV12 */
-
- mp_msg(MSGT_DEMUX, MSGL_INFO, "YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n",
- demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
- sh->bih->biHeight);
-}
-
-static demuxer_t* demux_open_y4m(demuxer_t* demuxer){
- y4m_priv_t* priv = demuxer->priv;
- sh_video_t* sh=new_sh_video(demuxer,0);
-
- priv->framenum = 0;
- priv->si = malloc(sizeof(y4m_stream_info_t));
-
- sh->bih=calloc(1, sizeof(*sh->bih));
-
- demuxer->video->sh=sh;
- sh->ds=demuxer->video;
- demuxer->video->id=0;
-
- read_streaminfo(demuxer);
-
- return demuxer;
-}
-
-static void demux_seek_y4m(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags) {
- sh_video_t* sh = demuxer->video->sh;
- y4m_priv_t* priv = demuxer->priv;
- int rel_seek_frames = sh->fps*rel_seek_secs;
- int size = 3*sh->disp_w*sh->disp_h/2;
- off_t curr_pos = stream_tell(demuxer->stream);
-
- if (priv->framenum + rel_seek_frames < 0) rel_seek_frames = -priv->framenum;
-
- //printf("seektoframe=%d rel_seek_secs=%f seektooffset=%ld\n", priv->framenum + rel_seek_frames, rel_seek_secs, curr_pos + rel_seek_frames*(size+6));
- //printf("framenum=%d, curr_pos=%ld, currpos/(size+6)=%f\n", priv->framenum, curr_pos, (float)curr_pos/(float)(size+6));
- priv->framenum += rel_seek_frames;
-
- if (priv->is_older) {
- /* Well this is easy: every frame takes up size+6 bytes
- * in the stream and we may assume that the stream pointer
- * is always at the beginning of a frame.
- * framenum is the number of the frame that is about to be
- * demuxed (counting from ONE (see demux_open_y4m)) */
- stream_seek(demuxer->stream, curr_pos + rel_seek_frames*(size+6));
- } else {
- /* should never come here, because seeking for YUV4MPEG2
- * is disabled. */
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Seeking for YUV4MPEG2 not yet implemented!\n");
- }
-}
-
-static void demux_close_y4m(demuxer_t *demuxer)
-{
- y4m_priv_t* priv = demuxer->priv;
-
- if(!priv)
- return;
- if (!priv->is_older)
- y4m_fini_stream_info(((y4m_priv_t*)demuxer->priv)->si);
- free(((y4m_priv_t*)demuxer->priv)->si);
- free(demuxer->priv);
- return;
-}
-
-
-const demuxer_desc_t demuxer_desc_y4m = {
- "YUV4MPEG2 demuxer",
- "y4m",
- "YUV4MPEG2",
- "Rik snel",
- "",
- DEMUXER_TYPE_Y4M,
- 1, // safe autodetect
- y4m_check_file,
- demux_y4m_fill_buffer,
- demux_open_y4m,
- demux_close_y4m,
- demux_seek_y4m,
- NULL
-};
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index 0cce5e8543..e77e32b942 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -58,41 +58,19 @@ extern const demuxer_desc_t demuxer_desc_rawvideo;
extern const demuxer_desc_t demuxer_desc_tv;
extern const demuxer_desc_t demuxer_desc_mf;
extern const demuxer_desc_t demuxer_desc_avi;
-extern const demuxer_desc_t demuxer_desc_y4m;
extern const demuxer_desc_t demuxer_desc_asf;
extern const demuxer_desc_t demuxer_desc_real;
-extern const demuxer_desc_t demuxer_desc_smjpeg;
extern const demuxer_desc_t demuxer_desc_matroska;
extern const demuxer_desc_t demuxer_desc_realaudio;
-extern const demuxer_desc_t demuxer_desc_vqf;
-extern const demuxer_desc_t demuxer_desc_mov;
extern const demuxer_desc_t demuxer_desc_vivo;
-extern const demuxer_desc_t demuxer_desc_fli;
-extern const demuxer_desc_t demuxer_desc_film;
-extern const demuxer_desc_t demuxer_desc_roq;
extern const demuxer_desc_t demuxer_desc_gif;
-extern const demuxer_desc_t demuxer_desc_ogg;
extern const demuxer_desc_t demuxer_desc_avs;
-extern const demuxer_desc_t demuxer_desc_pva;
-extern const demuxer_desc_t demuxer_desc_nsv;
-extern const demuxer_desc_t demuxer_desc_mpeg_ts;
-extern const demuxer_desc_t demuxer_desc_lmlm4;
-extern const demuxer_desc_t demuxer_desc_mpeg_ps;
-extern const demuxer_desc_t demuxer_desc_mpeg_pes;
-extern const demuxer_desc_t demuxer_desc_mpeg_es;
-extern const demuxer_desc_t demuxer_desc_mpeg_gxf;
-extern const demuxer_desc_t demuxer_desc_mpeg4_es;
-extern const demuxer_desc_t demuxer_desc_h264_es;
extern const demuxer_desc_t demuxer_desc_rawdv;
-extern const demuxer_desc_t demuxer_desc_mpc;
extern const demuxer_desc_t demuxer_desc_audio;
-extern const demuxer_desc_t demuxer_desc_mpeg_ty;
extern const demuxer_desc_t demuxer_desc_rtp;
extern const demuxer_desc_t demuxer_desc_rtp_nemesi;
extern const demuxer_desc_t demuxer_desc_lavf;
extern const demuxer_desc_t demuxer_desc_lavf_preferred;
-extern const demuxer_desc_t demuxer_desc_aac;
-extern const demuxer_desc_t demuxer_desc_nut;
extern const demuxer_desc_t demuxer_desc_mng;
/* Please do not add any new demuxers here. If you want to implement a new
@@ -110,39 +88,16 @@ const demuxer_desc_t *const demuxer_list[] = {
&demuxer_desc_mf,
&demuxer_desc_lavf_preferred,
&demuxer_desc_avi,
- &demuxer_desc_y4m,
&demuxer_desc_asf,
- &demuxer_desc_nsv,
- &demuxer_desc_real,
- &demuxer_desc_smjpeg,
&demuxer_desc_matroska,
&demuxer_desc_realaudio,
- &demuxer_desc_vqf,
- &demuxer_desc_mov,
- &demuxer_desc_vivo,
- &demuxer_desc_fli,
- &demuxer_desc_film,
- &demuxer_desc_roq,
#ifdef CONFIG_GIF
&demuxer_desc_gif,
#endif
-#ifdef CONFIG_OGGVORBIS
- &demuxer_desc_ogg,
-#endif
#ifdef CONFIG_WIN32DLL
&demuxer_desc_avs,
#endif
- &demuxer_desc_pva,
- &demuxer_desc_mpeg_ts,
- &demuxer_desc_lmlm4,
- &demuxer_desc_mpeg_ps,
- &demuxer_desc_mpeg_pes,
- &demuxer_desc_mpeg_es,
- &demuxer_desc_mpeg_gxf,
- &demuxer_desc_mpeg4_es,
- &demuxer_desc_h264_es,
&demuxer_desc_audio,
- &demuxer_desc_mpeg_ty,
#ifdef CONFIG_LIVE555
&demuxer_desc_rtp,
#endif
@@ -150,16 +105,9 @@ const demuxer_desc_t *const demuxer_list[] = {
&demuxer_desc_rtp_nemesi,
#endif
&demuxer_desc_lavf,
-#ifdef CONFIG_MUSEPACK
- &demuxer_desc_mpc,
-#endif
#ifdef CONFIG_LIBDV095
&demuxer_desc_rawdv,
#endif
- &demuxer_desc_aac,
-#ifdef CONFIG_LIBNUT
- &demuxer_desc_nut,
-#endif
#ifdef CONFIG_MNG
&demuxer_desc_mng,
#endif
@@ -1002,6 +950,22 @@ static struct demuxer *demux_open_stream(struct MPOpts *opts,
struct demuxer *demuxer = NULL;
const struct demuxer_desc *desc;
+ // Some code (e.g. dvd stuff, network code, or extension.c) explicitly
+ // request certain file formats. The list of formats are always handled by
+ // libavformat.
+ // Maybe attempts should be made to convert the mplayer format to the libav
+ // format, instead of reyling on libav to auto-detect the stream's format
+ // correctly.
+ switch (file_format) {
+ case DEMUXER_TYPE_MPEG_PS:
+ case DEMUXER_TYPE_MPEG_TS:
+ case DEMUXER_TYPE_Y4M:
+ case DEMUXER_TYPE_NSV:
+ case DEMUXER_TYPE_AAC:
+ case DEMUXER_TYPE_MPC:
+ file_format = DEMUXER_TYPE_LAVF;
+ }
+
// If somebody requested a demuxer check it
if (file_format) {
desc = get_demuxer_desc_from_type(file_format);
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index 3f9aa80b96..0e208d666e 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -44,47 +44,30 @@ struct MPOpts;
enum demuxer_type {
DEMUXER_TYPE_UNKNOWN = 0,
- DEMUXER_TYPE_MPEG_ES,
DEMUXER_TYPE_MPEG_PS,
DEMUXER_TYPE_AVI,
DEMUXER_TYPE_AVI_NI,
DEMUXER_TYPE_AVI_NINI,
DEMUXER_TYPE_ASF,
- DEMUXER_TYPE_MOV,
DEMUXER_TYPE_VIVO,
DEMUXER_TYPE_TV,
- DEMUXER_TYPE_FLI,
DEMUXER_TYPE_REAL,
DEMUXER_TYPE_Y4M,
- DEMUXER_TYPE_FILM,
- DEMUXER_TYPE_ROQ,
DEMUXER_TYPE_MF,
DEMUXER_TYPE_AUDIO,
- DEMUXER_TYPE_OGG,
DEMUXER_TYPE_RAWAUDIO,
DEMUXER_TYPE_RTP,
DEMUXER_TYPE_RAWDV,
- DEMUXER_TYPE_PVA,
- DEMUXER_TYPE_SMJPEG,
- DEMUXER_TYPE_XMMS,
DEMUXER_TYPE_RAWVIDEO,
- DEMUXER_TYPE_MPEG4_ES,
DEMUXER_TYPE_GIF,
DEMUXER_TYPE_MPEG_TS,
- DEMUXER_TYPE_H264_ES,
DEMUXER_TYPE_MATROSKA,
DEMUXER_TYPE_REALAUDIO,
- DEMUXER_TYPE_MPEG_TY,
- DEMUXER_TYPE_LMLM4,
DEMUXER_TYPE_LAVF,
DEMUXER_TYPE_NSV,
- DEMUXER_TYPE_VQF,
DEMUXER_TYPE_AVS,
DEMUXER_TYPE_AAC,
DEMUXER_TYPE_MPC,
- DEMUXER_TYPE_MPEG_PES,
- DEMUXER_TYPE_MPEG_GXF,
- DEMUXER_TYPE_NUT,
DEMUXER_TYPE_LAVF_PREFERRED,
DEMUXER_TYPE_RTP_NEMESI,
DEMUXER_TYPE_MNG,
diff --git a/libmpdemux/extension.c b/libmpdemux/extension.c
index 1d2ffb832e..8c4602bab4 100644
--- a/libmpdemux/extension.c
+++ b/libmpdemux/extension.c
@@ -38,9 +38,6 @@ static struct {
const char *extension;
int demuxer_type;
} extensions_table[] = {
-// { "mpeg", DEMUXER_TYPE_MPEG_PS },
-// { "mpg", DEMUXER_TYPE_MPEG_PS },
-// { "mpe", DEMUXER_TYPE_MPEG_PS },
{ "vob", DEMUXER_TYPE_MPEG_PS },
{ "m2v", DEMUXER_TYPE_MPEG_PS },
{ "avi", DEMUXER_TYPE_AVI },
@@ -58,16 +55,16 @@ static struct {
{ "wav", DEMUXER_TYPE_AUDIO },
{ "flac", DEMUXER_TYPE_AUDIO },
{ "fla", DEMUXER_TYPE_AUDIO },
- { "ogg", DEMUXER_TYPE_OGG },
- { "ogm", DEMUXER_TYPE_OGG },
+ { "ogg", DEMUXER_TYPE_LAVF },
+ { "ogm", DEMUXER_TYPE_LAVF },
// { "pls", DEMUXER_TYPE_PLAYLIST },
// { "m3u", DEMUXER_TYPE_PLAYLIST },
- { "xm", DEMUXER_TYPE_XMMS },
- { "mod", DEMUXER_TYPE_XMMS },
- { "s3m", DEMUXER_TYPE_XMMS },
- { "it", DEMUXER_TYPE_XMMS },
- { "mid", DEMUXER_TYPE_XMMS },
- { "midi", DEMUXER_TYPE_XMMS },
+ { "xm", DEMUXER_TYPE_LAVF },
+ { "mod", DEMUXER_TYPE_LAVF },
+ { "s3m", DEMUXER_TYPE_LAVF },
+ { "it", DEMUXER_TYPE_LAVF },
+ { "mid", DEMUXER_TYPE_LAVF },
+ { "midi", DEMUXER_TYPE_LAVF },
{ "nsv", DEMUXER_TYPE_NSV },
{ "nsa", DEMUXER_TYPE_NSV },
{ "mpc", DEMUXER_TYPE_MPC },
@@ -75,8 +72,8 @@ static struct {
{ "avs", DEMUXER_TYPE_AVS },
#endif
{ "302", DEMUXER_TYPE_LAVF },
- { "264", DEMUXER_TYPE_H264_ES },
- { "26l", DEMUXER_TYPE_H264_ES },
+ { "264", DEMUXER_TYPE_LAVF },
+ { "26l", DEMUXER_TYPE_LAVF },
{ "ac3", DEMUXER_TYPE_LAVF },
{ "ape", DEMUXER_TYPE_LAVF },
{ "apl", DEMUXER_TYPE_LAVF },
diff --git a/libmpdemux/mpeg_hdr.c b/libmpdemux/mpeg_hdr.c
deleted file mode 100644
index 0c368aa7a2..0000000000
--- a/libmpdemux/mpeg_hdr.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * based on libmpeg2/header.c by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-#include "mpeg_hdr.h"
-#include "libavutil/attributes.h"
-#include "mp_msg.h"
-
-static float frameratecode2framerate[16] = {
- 0,
- // Official mpeg1/2 framerates: (1-8)
- 24000.0/1001, 24,25,
- 30000.0/1001, 30,50,
- 60000.0/1001, 60,
- // Xing's 15fps: (9)
- 15,
- // libmpeg3's "Unofficial economy rates": (10-13)
- 5,10,12,15,
- // some invalid ones: (14-15)
- 0,0
-};
-
-
-int mp_header_process_sequence_header (mp_mpeg_header_t * picture, const unsigned char * buffer)
-{
- int height;
-
- if ((buffer[6] & 0x20) != 0x20){
- fprintf(stderr, "missing marker bit!\n");
- return 1; /* missing marker_bit */
- }
-
- height = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
-
- picture->display_picture_width = height >> 12;
- picture->display_picture_height = height & 0xfff;
-
- picture->aspect_ratio_information = buffer[3] >> 4;
- picture->frame_rate_code = buffer[3] & 15;
- picture->fps=frameratecode2framerate[picture->frame_rate_code];
- picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6);
- picture->mpeg1 = 1;
- picture->picture_structure = 3; //FRAME_PICTURE;
- picture->display_time=100;
- picture->frame_rate_extension_n = 1;
- picture->frame_rate_extension_d = 1;
- return 0;
-}
-
-static int header_process_sequence_extension (mp_mpeg_header_t * picture,
- unsigned char * buffer)
-{
- /* check chroma format, size extensions, marker bit */
-
- if ( ((buffer[1] & 0x06) == 0x00) ||
- ((buffer[1] & 0x01) != 0x00) || (buffer[2] & 0xe0) ||
- ((buffer[3] & 0x01) != 0x01) )
- return 1;
-
- picture->progressive_sequence = (buffer[1] >> 3) & 1;
- picture->frame_rate_extension_n = ((buffer[5] >> 5) & 3) + 1;
- picture->frame_rate_extension_d = (buffer[5] & 0x1f) + 1;
-
- picture->mpeg1 = 0;
- return 0;
-}
-
-static int header_process_picture_coding_extension (mp_mpeg_header_t * picture, unsigned char * buffer)
-{
- picture->picture_structure = buffer[2] & 3;
- picture->top_field_first = buffer[3] >> 7;
- picture->repeat_first_field = (buffer[3] >> 1) & 1;
- picture->progressive_frame = buffer[4] >> 7;
-
- // repeat_first implementation by A'rpi/ESP-team, based on libmpeg3:
- picture->display_time=100;
- if(picture->repeat_first_field){
- if(picture->progressive_sequence){
- if(picture->top_field_first)
- picture->display_time+=200;
- else
- picture->display_time+=100;
- } else
- if(picture->progressive_frame){
- picture->display_time+=50;
- }
- }
- //temopral hack. We calc time on every field, so if we have 2 fields
- // interlaced we'll end with double time for 1 frame
- if( picture->picture_structure!=3 ) picture->display_time/=2;
- return 0;
-}
-
-int mp_header_process_extension (mp_mpeg_header_t * picture, unsigned char * buffer)
-{
- switch (buffer[0] & 0xf0) {
- case 0x10: /* sequence extension */
- return header_process_sequence_extension (picture, buffer);
- case 0x80: /* picture coding extension */
- return header_process_picture_coding_extension (picture, buffer);
- }
- return 0;
-}
-
-float mpeg12_aspect_info(mp_mpeg_header_t *picture)
-{
- float aspect = 0.0;
-
- switch(picture->aspect_ratio_information) {
- case 2: // PAL/NTSC SVCD/DVD 4:3
- case 8: // PAL VCD 4:3
- case 12: // NTSC VCD 4:3
- aspect=4.0/3.0;
- break;
- case 3: // PAL/NTSC Widescreen SVCD/DVD 16:9
- case 6: // (PAL?)/NTSC Widescreen SVCD 16:9
- aspect=16.0/9.0;
- break;
- case 4: // according to ISO-138182-2 Table 6.3
- aspect=2.21;
- break;
- case 1: // VGA 1:1 - do not prescale
- case 9: // Movie Type ??? / 640x480
- aspect=0.0;
- break;
- default:
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Detected unknown aspect_ratio_information in mpeg sequence header.\n"
- "Please report the aspect value (%i) along with the movie type (VGA,PAL,NTSC,"
- "SECAM) and the movie resolution (720x576,352x240,480x480,...) to the MPlayer"
- " developers, so that we can add support for it!\nAssuming 1:1 aspect for now.\n",
- picture->aspect_ratio_information);
- }
-
- return aspect;
-}
-
-//MPEG4 HEADERS
-unsigned char mp_getbits(unsigned char *buffer, unsigned int from, unsigned char len)
-{
- unsigned int n;
- unsigned char m, u, l, y;
-
- n = from / 8;
- m = from % 8;
- u = 8 - m;
- l = (len > u ? len - u : 0);
-
- y = (buffer[n] << m);
- if(8 > len)
- y >>= (8-len);
- if(l)
- y |= (buffer[n+1] >> (8-l));
-
- //fprintf(stderr, "GETBITS(%d -> %d): bytes=0x%x 0x%x, n=%d, m=%d, l=%d, u=%d, Y=%d\n",
- // from, (int) len, (int) buffer[n],(int) buffer[n+1], n, (int) m, (int) l, (int) u, (int) y);
- return y;
-}
-
-static inline unsigned int mp_getbits16(unsigned char *buffer, unsigned int from, unsigned char len)
-{
- if(len > 8)
- return (mp_getbits(buffer, from, len - 8) << 8) | mp_getbits(buffer, from + len - 8, 8);
- else
- return mp_getbits(buffer, from, len);
-}
-
-#define getbits mp_getbits
-#define getbits16 mp_getbits16
-
-static int read_timeinc(mp_mpeg_header_t * picture, unsigned char * buffer, int n)
-{
- if(picture->timeinc_bits > 8) {
- picture->timeinc_unit = getbits(buffer, n, picture->timeinc_bits - 8) << 8;
- n += picture->timeinc_bits - 8;
- picture->timeinc_unit |= getbits(buffer, n, 8);
- n += 8;
- } else {
- picture->timeinc_unit = getbits(buffer, n, picture->timeinc_bits);
- n += picture->timeinc_bits;
- }
- //fprintf(stderr, "TIMEINC2: %d, bits: %d\n", picture->timeinc_unit, picture->timeinc_bits);
- return n;
-}
-
-int mp4_header_process_vol(mp_mpeg_header_t * picture, unsigned char * buffer)
-{
- unsigned int n, aspect=0, aspectw av_unused=0, aspecth av_unused=0, x=1, v;
-
- //begins with 0x0000012x
- picture->fps = 0;
- picture->timeinc_bits = picture->timeinc_resolution = picture->timeinc_unit = 0;
- n = 9;
- if(getbits(buffer, n, 1))
- n += 7;
- n++;
- aspect=getbits(buffer, n, 4);
- n += 4;
- if(aspect == 0x0f) {
- aspectw = getbits(buffer, n, 8);
- n += 8;
- aspecth = getbits(buffer, n, 8);
- n += 8;
- }
-
- if(getbits(buffer, n, 1)) {
- n += 4;
- if(getbits(buffer, n, 1))
- n += 79;
- n++;
- } else n++;
-
- n+=3;
-
- picture->timeinc_resolution = getbits(buffer, n, 8) << 8;
- n += 8;
- picture->timeinc_resolution |= getbits(buffer, n, 8);
- n += 8;
-
- picture->timeinc_bits = 0;
- v = picture->timeinc_resolution - 1;
- while(v && (x<16)) {
- v>>=1;
- picture->timeinc_bits++;
- }
- picture->timeinc_bits = (picture->timeinc_bits > 1 ? picture->timeinc_bits : 1);
-
- n++; //marker bit
-
- if(getbits(buffer, n++, 1)) { //fixed_vop_timeinc
- n += read_timeinc(picture, buffer, n);
-
- if(picture->timeinc_unit)
- picture->fps = (float) picture->timeinc_resolution / (float) picture->timeinc_unit;
- }
-
- n++; //marker bit
- picture->display_picture_width = getbits16(buffer, n, 13);
- n += 13;
- n++; //marker bit
- picture->display_picture_height = getbits16(buffer, n, 13);
- n += 13;
-
- //fprintf(stderr, "ASPECT: %d, PARW=%d, PARH=%d, TIMEINCRESOLUTION: %d, FIXED_TIMEINC: %d (number of bits: %d), FPS: %u\n",
- // aspect, aspectw, aspecth, picture->timeinc_resolution, picture->timeinc_unit, picture->timeinc_bits, picture->fps);
-
- return 0;
-}
-
-void mp4_header_process_vop(mp_mpeg_header_t * picture, unsigned char * buffer)
-{
- int n;
- n = 0;
- picture->picture_type = getbits(buffer, n, 2);
- n += 2;
- while(getbits(buffer, n, 1))
- n++;
- n++;
- getbits(buffer, n, 1);
- n++;
- n += read_timeinc(picture, buffer, n);
-}
-
-#define min(a, b) ((a) <= (b) ? (a) : (b))
-
-static unsigned int read_golomb(unsigned char *buffer, unsigned int *init)
-{
- unsigned int x, v = 0, v2 = 0, m, len = 0, n = *init;
-
- while(getbits(buffer, n++, 1) == 0)
- len++;
-
- x = len + n;
- while(n < x)
- {
- m = min(x - n, 8);
- v |= getbits(buffer, n, m);
- n += m;
- if(x - n > 8)
- v <<= 8;
- }
-
- v2 = 1;
- for(n = 0; n < len; n++)
- v2 <<= 1;
- v2 = (v2 - 1) + v;
-
- //fprintf(stderr, "READ_GOLOMB(%u), V=2^%u + %u-1 = %u\n", *init, len, v, v2);
- *init = x;
- return v2;
-}
-
-inline static int read_golomb_s(unsigned char *buffer, unsigned int *init)
-{
- unsigned int v = read_golomb(buffer, init);
- return (v & 1) ? ((v + 1) >> 1) : -(v >> 1);
-}
-
-static int h264_parse_vui(mp_mpeg_header_t * picture, unsigned char * buf, unsigned int n)
-{
- unsigned int overscan, vsp_color, chroma, timing, fixed_fps;
-
- if(getbits(buf, n++, 1))
- {
- picture->aspect_ratio_information = getbits(buf, n, 8);
- n += 8;
- if(picture->aspect_ratio_information == 255)
- {
- picture->display_picture_width = (getbits(buf, n, 8) << 8) | getbits(buf, n + 8, 8);
- n += 16;
-
- picture->display_picture_height = (getbits(buf, n, 8) << 8) | getbits(buf, n + 8, 8);
- n += 16;
- }
- }
-
- if((overscan=getbits(buf, n++, 1)))
- n++;
- if((vsp_color=getbits(buf, n++, 1)))
- {
- n += 4;
- if(getbits(buf, n++, 1))
- n += 24;
- }
- if((chroma=getbits(buf, n++, 1)))
- {
- read_golomb(buf, &n);
- read_golomb(buf, &n);
- }
- if((timing=getbits(buf, n++, 1)))
- {
- picture->timeinc_unit = (getbits(buf, n, 8) << 24) | (getbits(buf, n+8, 8) << 16) | (getbits(buf, n+16, 8) << 8) | getbits(buf, n+24, 8);
- n += 32;
-
- picture->timeinc_resolution = (getbits(buf, n, 8) << 24) | (getbits(buf, n+8, 8) << 16) | (getbits(buf, n+16, 8) << 8) | getbits(buf, n+24, 8);
- n += 32;
-
- fixed_fps = getbits(buf, n, 1);
-
- if(picture->timeinc_unit > 0 && picture->timeinc_resolution > 0)
- picture->fps = (float) picture->timeinc_resolution / (float) picture->timeinc_unit;
- if(fixed_fps)
- picture->fps /= 2;
- }
-
- //fprintf(stderr, "H264_PARSE_VUI, OVESCAN=%u, VSP_COLOR=%u, CHROMA=%u, TIMING=%u, DISPW=%u, DISPH=%u, TIMERES=%u, TIMEINC=%u, FIXED_FPS=%u\n", overscan, vsp_color, chroma, timing, picture->display_picture_width, picture->display_picture_height,
- // picture->timeinc_resolution, picture->timeinc_unit, picture->timeinc_unit, fixed_fps);
-
- return n;
-}
-
-static int mp_unescape03(unsigned char *buf, int len)
-{
- unsigned char *dest;
- int i, j, skip;
-
- dest = malloc(len);
- if(! dest)
- return 0;
-
- j = i = skip = 0;
- while(i <= len-3)
- {
- if(buf[i] == 0 && buf[i+1] == 0 && buf[i+2] == 3)
- {
- dest[j] = dest[j+1] = 0;
- j += 2;
- i += 3;
- skip++;
- }
- else
- {
- dest[j] = buf[i];
- j++;
- i++;
- }
- }
- dest[j] = buf[len-2];
- dest[j+1] = buf[len-1];
- len -= skip;
- memcpy(buf, dest, len);
- free(dest);
-
- return len;
-}
-
-int h264_parse_sps(mp_mpeg_header_t * picture, unsigned char * buf, int len)
-{
- unsigned int n = 0, v, i, k, mbh;
- int frame_mbs_only;
-
- len = mp_unescape03(buf, len);
-
- picture->fps = picture->timeinc_unit = picture->timeinc_resolution = 0;
- n = 24;
- read_golomb(buf, &n);
- if(buf[0] >= 100){
- if(read_golomb(buf, &n) == 3)
- n++;
- read_golomb(buf, &n);
- read_golomb(buf, &n);
- n++;
- if(getbits(buf, n++, 1)){
- for(i = 0; i < 8; i++)
- { // scaling list is skipped for now
- if(getbits(buf, n++, 1))
- {
- v = 8;
- for(k = (i < 6 ? 16 : 64); k && v; k--)
- v = (v + read_golomb_s(buf, &n)) & 255;
- }
- }
- }
- }
- read_golomb(buf, &n);
- v = read_golomb(buf, &n);
- if(v == 0)
- read_golomb(buf, &n);
- else if(v == 1)
- {
- getbits(buf, n++, 1);
- read_golomb(buf, &n);
- read_golomb(buf, &n);
- v = read_golomb(buf, &n);
- for(i = 0; i < v; i++)
- read_golomb(buf, &n);
- }
- read_golomb(buf, &n);
- getbits(buf, n++, 1);
- picture->display_picture_width = 16 *(read_golomb(buf, &n)+1);
- mbh = read_golomb(buf, &n)+1;
- frame_mbs_only = getbits(buf, n++, 1);
- picture->display_picture_height = 16 * (2 - frame_mbs_only) * mbh;
- if(!frame_mbs_only)
- getbits(buf, n++, 1);
- getbits(buf, n++, 1);
- if(getbits(buf, n++, 1))
- {
- read_golomb(buf, &n);
- read_golomb(buf, &n);
- read_golomb(buf, &n);
- read_golomb(buf, &n);
- }
- if(getbits(buf, n++, 1))
- n = h264_parse_vui(picture, buf, n);
-
- return n;
-}
-
-int mp_vc1_decode_sequence_header(mp_mpeg_header_t * picture, unsigned char * buf, int len)
-{
- int n, x;
-
- len = mp_unescape03(buf, len);
-
- picture->display_picture_width = picture->display_picture_height = 0;
- picture->fps = 0;
- n = 0;
- x = getbits(buf, n, 2);
- n += 2;
- if(x != 3) //not advanced profile
- return 0;
-
- getbits16(buf, n, 14);
- n += 14;
- picture->display_picture_width = getbits16(buf, n, 12) * 2 + 2;
- n += 12;
- picture->display_picture_height = getbits16(buf, n, 12) * 2 + 2;
- n += 12;
- getbits(buf, n, 6);
- n += 6;
- x = getbits(buf, n, 1);
- n += 1;
- if(x) //display info
- {
- getbits16(buf, n, 14);
- n += 14;
- getbits16(buf, n, 14);
- n += 14;
- if(getbits(buf, n++, 1)) //aspect ratio
- {
- x = getbits(buf, n, 4);
- n += 4;
- if(x == 15)
- {
- getbits16(buf, n, 16);
- n += 16;
- }
- }
-
- if(getbits(buf, n++, 1)) //framerates
- {
- int frexp=0, frnum=0, frden=0;
-
- if(getbits(buf, n++, 1))
- {
- frexp = getbits16(buf, n, 16);
- n += 16;
- picture->fps = (double) (frexp+1) / 32.0;
- }
- else
- {
- float frates[] = {0, 24000, 25000, 30000, 50000, 60000, 48000, 72000, 0};
- float frdivs[] = {0, 1000, 1001, 0};
-
- frnum = getbits(buf, n, 8);
- n += 8;
- frden = getbits(buf, n, 4);
- n += 4;
- if((frden == 1 || frden == 2) && (frnum < 8))
- picture->fps = frates[frnum] / frdivs[frden];
- }
- }
- }
-
- //free(dest);
- return 1;
-}
diff --git a/libmpdemux/mpeg_hdr.h b/libmpdemux/mpeg_hdr.h
deleted file mode 100644
index ccd84bcdb0..0000000000
--- a/libmpdemux/mpeg_hdr.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_MPEG_HDR_H
-#define MPLAYER_MPEG_HDR_H
-
-typedef struct {
- // video info:
- int mpeg1; // 0=mpeg2 1=mpeg1
- int display_picture_width;
- int display_picture_height;
- int aspect_ratio_information;
- int frame_rate_code;
- float fps;
- int frame_rate_extension_n;
- int frame_rate_extension_d;
- int bitrate; // 0x3FFFF==VBR
- // timing:
- int picture_structure;
- int progressive_sequence;
- int repeat_first_field;
- int progressive_frame;
- int top_field_first;
- int display_time; // secs*100
- //the following are for mpeg4
- unsigned int timeinc_resolution, timeinc_bits, timeinc_unit;
- int picture_type;
-} mp_mpeg_header_t;
-
-int mp_header_process_sequence_header (mp_mpeg_header_t * picture, const unsigned char * buffer);
-int mp_header_process_extension (mp_mpeg_header_t * picture, unsigned char * buffer);
-float mpeg12_aspect_info(mp_mpeg_header_t *picture);
-int mp4_header_process_vol(mp_mpeg_header_t * picture, unsigned char * buffer);
-void mp4_header_process_vop(mp_mpeg_header_t * picture, unsigned char * buffer);
-int h264_parse_sps(mp_mpeg_header_t * picture, unsigned char * buf, int len);
-int mp_vc1_decode_sequence_header(mp_mpeg_header_t * picture, unsigned char * buf, int len);
-
-unsigned char mp_getbits(unsigned char *buffer, unsigned int from, unsigned char len);
-
-#endif /* MPLAYER_MPEG_HDR_H */
diff --git a/libmpdemux/parse_es.c b/libmpdemux/parse_es.c
deleted file mode 100644
index 05507a495a..0000000000
--- a/libmpdemux/parse_es.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * MPEG-ES video parser
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "parse_es.h"
-
-//static unsigned char videobuffer[MAX_VIDEO_PACKET_SIZE];
-unsigned char* videobuffer=NULL;
-int videobuf_len=0;
-int next_nal = -1;
-///! legacy variable, 4 if stream is synced, 0 if not
-int videobuf_code_len=0;
-
-#define MAX_SYNCLEN (10 * 1024 * 1024)
-// sync video stream, and returns next packet code
-int sync_video_packet(demux_stream_t *ds){
- if (!videobuf_code_len) {
- int skipped=0;
- if (!demux_pattern_3(ds, NULL, MAX_SYNCLEN, &skipped, 0x100)) {
- if (skipped == MAX_SYNCLEN)
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "parse_es: could not sync video stream!\n");
- goto eof_out;
- }
- next_nal = demux_getc(ds);
- if (next_nal < 0)
- goto eof_out;
- videobuf_code_len = 4;
- if(skipped) mp_dbg(MSGT_PARSEES,MSGL_DBG2,"videobuf: %d bytes skipped (next: 0x1%02X)\n",skipped,next_nal);
- }
- return 0x100|next_nal;
-
-eof_out:
- next_nal = -1;
- videobuf_code_len = 0;
- return 0;
-}
-
-// return: packet length
-int read_video_packet(demux_stream_t *ds){
-int packet_start;
- int res, read;
-
- if (VIDEOBUFFER_SIZE - videobuf_len < 5)
- return 0;
- // SYNC STREAM
-// if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)
-
- // COPY STARTCODE:
- packet_start=videobuf_len;
- videobuffer[videobuf_len+0]=0;
- videobuffer[videobuf_len+1]=0;
- videobuffer[videobuf_len+2]=1;
- videobuffer[videobuf_len+3]=next_nal;
- videobuf_len+=4;
-
- // READ PACKET:
- res = demux_pattern_3(ds, &videobuffer[videobuf_len],
- VIDEOBUFFER_SIZE - videobuf_len, &read, 0x100);
- videobuf_len += read;
- if (!res)
- goto eof_out;
-
- videobuf_len-=3;
-
- mp_dbg(MSGT_PARSEES,MSGL_DBG2,"videobuf: packet 0x1%02X len=%d (total=%d)\n",videobuffer[packet_start+3],videobuf_len-packet_start,videobuf_len);
-
- // Save next packet code:
- next_nal = demux_getc(ds);
- if (next_nal < 0)
- goto eof_out;
- videobuf_code_len=4;
-
- return videobuf_len-packet_start;
-
-eof_out:
- next_nal = -1;
- videobuf_code_len = 0;
- return videobuf_len - packet_start;
-}
-
-// return: next packet code
-int skip_video_packet(demux_stream_t *ds){
-
- // SYNC STREAM
-// if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)
-
- videobuf_code_len=0; // force resync
-
- // SYNC AGAIN:
- return sync_video_packet(ds);
-}
-
-/* stripped down version of a52_syncinfo() from liba52
- * copyright belongs to Michel Lespinasse <walken@zoy.org>
- * and Aaron Holtzman <aholtzma@ess.engr.uvic.ca> */
-int mp_a52_framesize(uint8_t * buf, int *srate)
-{
- int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
- 128, 160, 192, 224, 256, 320, 384, 448,
- 512, 576, 640
- };
- uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
- int frmsizecod, bitrate, half;
-
- if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */
- return 0;
-
- if (buf[5] >= 0x60) /* bsid >= 12 */
- return 0;
-
- half = halfrate[buf[5] >> 3];
-
- frmsizecod = buf[4] & 63;
- if (frmsizecod >= 38)
- return 0;
-
- bitrate = rate[frmsizecod >> 1];
-
- switch (buf[4] & 0xc0) {
- case 0: /* 48 KHz */
- *srate = 48000 >> half;
- return 4 * bitrate;
- case 0x40: /* 44.1 KHz */
- *srate = 44100 >> half;
- return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
- case 0x80: /* 32 KHz */
- *srate = 32000 >> half;
- return 6 * bitrate;
- }
-
- return 0;
-}
diff --git a/libmpdemux/parse_es.h b/libmpdemux/parse_es.h
deleted file mode 100644
index ed76593e50..0000000000
--- a/libmpdemux/parse_es.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_PARSE_ES_H
-#define MPLAYER_PARSE_ES_H
-
-#include <stdint.h>
-
-#include "demuxer.h"
-
-#define MAX_VIDEO_PACKET_SIZE (224*1024+4)
-#define VIDEOBUFFER_SIZE 0x100000
-
-extern unsigned char* videobuffer;
-extern int videobuf_len;
-extern unsigned char videobuf_code[4];
-extern int videobuf_code_len;
-
-// sync video stream, and returns next packet code
-int sync_video_packet(demux_stream_t *ds);
-
-// return: packet length
-int read_video_packet(demux_stream_t *ds);
-
-// return: next packet code
-int skip_video_packet(demux_stream_t *ds);
-
-int mp_a52_framesize(uint8_t *buf, int *srate);
-
-#endif /* MPLAYER_PARSE_ES_H */
diff --git a/libmpdemux/parse_mp4.c b/libmpdemux/parse_mp4.c
deleted file mode 100644
index 137ec3e6e7..0000000000
--- a/libmpdemux/parse_mp4.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * MP4 file format parser code
- *
- * Copyright (C) 2002 Felix Buenemann <atmosfear at users.sourceforge.net>
- * Code inspired by libmp4 from http://mpeg4ip.sourceforge.net/.
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdlib.h>
-#include "parse_mp4.h"
-#include "mp_msg.h"
-#include "stream/stream.h"
-
-//#define MP4_DUMPATOM
-
-#define MP4_DL MSGL_V
-#define freereturn(a,b) free(a); return b
-
-static int mp4_read_descr_len(stream_t *s)
-{
- uint8_t b;
- uint8_t numBytes = 0;
- uint32_t length = 0;
-
- do {
- b = stream_read_char(s);
- numBytes++;
- length = (length << 7) | (b & 0x7F);
- } while ((b & 0x80) && numBytes < 4);
-
- //printf("MP4 read desc len: %d\n", length);
- return length;
-}
-
-/* parse the data part of MP4 esds atoms */
-int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) {
- /* create memory stream from data */
- stream_t *s = new_memory_stream(data, datalen);
- uint16_t len;
-#ifdef MP4_DUMPATOM
- {int i;
- printf("ESDS Dump (%dbyte):\n", datalen);
- for(i = 0; i < datalen; i++)
- printf("%02X ", data[i]);
- printf("\nESDS Dumped\n");}
-#endif
- memset(esds, 0, sizeof(esds_t));
-
- esds->version = stream_read_char(s);
- esds->flags = stream_read_int24(s);
- mp_msg(MSGT_DEMUX, MP4_DL,
- "ESDS MPEG4 version: %d flags: 0x%06X\n",
- esds->version, esds->flags);
-
- /* get and verify ES_DescrTag */
- if (stream_read_char(s) == MP4ESDescrTag) {
- /* read length */
- len = mp4_read_descr_len(s);
-
- esds->ESId = stream_read_word(s);
- esds->streamPriority = stream_read_char(s);
- mp_msg(MSGT_DEMUX, MP4_DL,
- "ESDS MPEG4 ES Descriptor (%dBytes):\n"
- " -> ESId: %d\n"
- " -> streamPriority: %d\n",
- len, esds->ESId, esds->streamPriority);
-
- if (len < (5 + 15)) {
- freereturn(s,1);
- }
- } else {
- esds->ESId = stream_read_word(s);
- mp_msg(MSGT_DEMUX, MP4_DL,
- "ESDS MPEG4 ES Descriptor (%dBytes):\n"
- " -> ESId: %d\n", 2, esds->ESId);
- }
-
- /* get and verify DecoderConfigDescrTab */
- if (stream_read_char(s) != MP4DecConfigDescrTag) {
- freereturn(s,1);
- }
-
- /* read length */
- len = mp4_read_descr_len(s);
-
- esds->objectTypeId = stream_read_char(s);
- esds->streamType = stream_read_char(s);
- esds->bufferSizeDB = stream_read_int24(s);
- esds->maxBitrate = stream_read_dword(s);
- esds->avgBitrate = stream_read_dword(s);
- mp_msg(MSGT_DEMUX, MP4_DL,
- "ESDS MPEG4 Decoder Config Descriptor (%dBytes):\n"
- " -> objectTypeId: %d\n"
- " -> streamType: 0x%02X\n"
- " -> bufferSizeDB: 0x%06X\n"
- " -> maxBitrate: %.3fkbit/s\n"
- " -> avgBitrate: %.3fkbit/s\n",
- len, esds->objectTypeId, esds->streamType,
- esds->bufferSizeDB, esds->maxBitrate/1000.0,
- esds->avgBitrate/1000.0);
-
- esds->decoderConfigLen=0;
-
- if (len < 15) {
- freereturn(s,0);
- }
-
- /* get and verify DecSpecificInfoTag */
- if (stream_read_char(s) != MP4DecSpecificDescrTag) {
- freereturn(s,0);
- }
-
- /* read length */
- esds->decoderConfigLen = len = mp4_read_descr_len(s);
-
- esds->decoderConfig = malloc(esds->decoderConfigLen);
- if (esds->decoderConfig) {
- stream_read(s, esds->decoderConfig, esds->decoderConfigLen);
- } else {
- esds->decoderConfigLen = 0;
- }
- mp_msg(MSGT_DEMUX, MP4_DL,
- "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len);
-
- /* get and verify SLConfigDescrTag */
- if(stream_read_char(s) != MP4SLConfigDescrTag) {
- freereturn(s,0);
- }
-
- /* Note: SLConfig is usually constant value 2, size 1Byte */
- esds->SLConfigLen = len = mp4_read_descr_len(s);
- esds->SLConfig = malloc(esds->SLConfigLen);
- if (esds->SLConfig) {
- stream_read(s, esds->SLConfig, esds->SLConfigLen);
- } else {
- esds->SLConfigLen = 0;
- }
- mp_msg(MSGT_DEMUX, MP4_DL,
- "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n"
- " -> predefined: %d\n", len, esds->SLConfig[0]);
-
- /* will skip the remainder of the atom */
- freereturn(s,0);
-
-}
-
-/* cleanup all mem occupied by mp4_parse_esds */
-void mp4_free_esds(esds_t *esds) {
- if(esds->decoderConfigLen)
- free(esds->decoderConfig);
- if(esds->SLConfigLen)
- free(esds->SLConfig);
-}
-
-#undef freereturn
-#undef MP4_DL
diff --git a/libmpdemux/parse_mp4.h b/libmpdemux/parse_mp4.h
deleted file mode 100644
index 27d4d44d7d..0000000000
--- a/libmpdemux/parse_mp4.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * MP4 file format parser code
- *
- * Copyright (C) 2002 Felix Buenemann <atmosfear at users.sourceforge.net>
- * Code inspired by libmp4 from http://mpeg4ip.sourceforge.net/.
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_PARSE_MP4_H
-#define MPLAYER_PARSE_MP4_H
-
-#include <inttypes.h>
-
-/* one byte tag identifiers */
-#define MP4ODescrTag 0x01
-#define MP4IODescrTag 0x02
-#define MP4ESDescrTag 0x03
-#define MP4DecConfigDescrTag 0x04
-#define MP4DecSpecificDescrTag 0x05
-#define MP4SLConfigDescrTag 0x06
-#define MP4ContentIdDescrTag 0x07
-#define MP4SupplContentIdDescrTag 0x08
-#define MP4IPIPtrDescrTag 0x09
-#define MP4IPMPPtrDescrTag 0x0A
-#define MP4IPMPDescrTag 0x0B
-#define MP4RegistrationDescrTag 0x0D
-#define MP4ESIDIncDescrTag 0x0E
-#define MP4ESIDRefDescrTag 0x0F
-#define MP4FileIODescrTag 0x10
-#define MP4FileODescrTag 0x11
-#define MP4ExtProfileLevelDescrTag 0x13
-#define MP4ExtDescrTagsStart 0x80
-#define MP4ExtDescrTagsEnd 0xFE
-
-/* object type identifiers in the ESDS */
-/* See http://gpac.sourceforge.net/tutorial/mediatypes.htm */
-/* BIFS stream version 1 */
-#define MP4OTI_MPEG4Systems1 0x01
-/* BIFS stream version 2 */
-#define MP4OTI_MPEG4Systems2 0x02
-/* MPEG-4 visual stream */
-#define MP4OTI_MPEG4Visual 0x20
-/* MPEG-4 audio stream */
-#define MP4OTI_MPEG4Audio 0x40
-/* MPEG-2 visual streams with various profiles */
-#define MP4OTI_MPEG2VisualSimple 0x60
-#define MP4OTI_MPEG2VisualMain 0x61
-#define MP4OTI_MPEG2VisualSNR 0x62
-#define MP4OTI_MPEG2VisualSpatial 0x63
-#define MP4OTI_MPEG2VisualHigh 0x64
-#define MP4OTI_MPEG2Visual422 0x65
-/* MPEG-2 audio stream part 7 ("AAC") with various profiles */
-#define MP4OTI_MPEG2AudioMain 0x66
-#define MP4OTI_MPEG2AudioLowComplexity 0x67
-#define MP4OTI_MPEG2AudioScaleableSamplingRate 0x68
-/* MPEG-2 audio part 3 ("MP3") */
-#define MP4OTI_MPEG2AudioPart3 0x69
-/* MPEG-1 visual visual stream */
-#define MP4OTI_MPEG1Visual 0x6A
-/* MPEG-1 audio stream part 3 ("MP3") */
-#define MP4OTI_MPEG1Audio 0x6B
-/* JPEG visual stream */
-#define MP4OTI_JPEG 0x6C
-/* 3GPP2 */
-#define MP4OTI_13kVoice 0xE1
-
-/* I define uint24 here for better understanding */
-#ifndef uint24_t
-#define uint24_t uint32_t
-#endif
-
-/* esds_t */
-typedef struct {
- uint8_t version;
- uint24_t flags;
-
- /* 0x03 ESDescrTag */
- uint16_t ESId;
- uint8_t streamPriority;
-
- /* 0x04 DecConfigDescrTag */
- uint8_t objectTypeId;
- uint8_t streamType;
- /* XXX: really streamType is
- * only 6bit, followed by:
- * 1bit upStream
- * 1bit reserved
- */
- uint24_t bufferSizeDB;
- uint32_t maxBitrate;
- uint32_t avgBitrate;
-
- /* 0x05 DecSpecificDescrTag */
- uint16_t decoderConfigLen;
- uint8_t *decoderConfig;
-
- /* 0x06 SLConfigDescrTag */
- uint8_t SLConfigLen;
- uint8_t *SLConfig;
-
- /* TODO: add the missing tags,
- * I currently have no specs
- * for them and doubt they
- * are currently needed ::atmos
- */
-
-} esds_t;
-
-int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds);
-void mp4_free_esds(esds_t *esds);
-
-#endif /* MPLAYER_PARSE_MP4_H */
diff --git a/libmpdemux/video.c b/libmpdemux/video.c
index e788818825..7bb1ade6e0 100644
--- a/libmpdemux/video.c
+++ b/libmpdemux/video.c
@@ -36,8 +36,6 @@
#include "demux_ty_osd.h"
#endif
#include "stheader.h"
-#include "parse_es.h"
-#include "mpeg_hdr.h"
/* sub_cc (closed captions)*/
#include "sub/sub_cc.h"
@@ -49,64 +47,9 @@
#include "demux_rtp.h"
#endif
-static mp_mpeg_header_t picture;
-
-static int telecine=0;
-static float telecine_cnt=-2.5;
-
-typedef enum {
- VIDEO_MPEG12,
- VIDEO_MPEG4,
- VIDEO_H264,
- VIDEO_VC1,
- VIDEO_OTHER
-} video_codec_t;
-
-static video_codec_t find_video_codec(sh_video_t *sh_video)
-{
- demux_stream_t *d_video=sh_video->ds;
- int fmt = d_video->demuxer->file_format;
-
- if(
- (fmt == DEMUXER_TYPE_PVA) ||
- (fmt == DEMUXER_TYPE_MPEG_ES) ||
- (fmt == DEMUXER_TYPE_MPEG_GXF) ||
- (fmt == DEMUXER_TYPE_MPEG_PES) ||
- (
- (fmt == DEMUXER_TYPE_MPEG_PS || fmt == DEMUXER_TYPE_MPEG_TS) &&
- ((! sh_video->format) || (sh_video->format==0x10000001) || (sh_video->format==0x10000002))
- ) ||
- (fmt == DEMUXER_TYPE_MPEG_TY)
-#ifdef CONFIG_LIVE555
- || ((fmt == DEMUXER_TYPE_RTP) && demux_is_mpeg_rtp_stream(d_video->demuxer))
-#endif
- )
- return VIDEO_MPEG12;
- else if((fmt == DEMUXER_TYPE_MPEG4_ES) ||
- ((fmt == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000004)) ||
- ((fmt == DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000004))
- )
- return VIDEO_MPEG4;
- else if((fmt == DEMUXER_TYPE_H264_ES) ||
- ((fmt == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000005)) ||
- ((fmt == DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000005))
- )
- return VIDEO_H264;
- else if((fmt == DEMUXER_TYPE_MPEG_PS || fmt == DEMUXER_TYPE_MPEG_TS) &&
- (sh_video->format==mmioFOURCC('W', 'V', 'C', '1')))
- return VIDEO_VC1;
- else if (fmt == DEMUXER_TYPE_ASF && sh_video->bih && sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' '))
- return VIDEO_MPEG12;
- else
- return VIDEO_OTHER;
-}
-
int video_read_properties(sh_video_t *sh_video){
demux_stream_t *d_video=sh_video->ds;
-video_codec_t video_codec = find_video_codec(sh_video);
-// Determine image properties:
-switch(video_codec){
- case VIDEO_OTHER: {
+
if((d_video->demuxer->file_format == DEMUXER_TYPE_ASF) || (d_video->demuxer->file_format == DEMUXER_TYPE_AVI)) {
// display info:
// in case no strf chunk has been seen in avi, we have no bitmap header
@@ -115,464 +58,22 @@ switch(video_codec){
sh_video->disp_w=sh_video->bih->biWidth;
sh_video->disp_h=abs(sh_video->bih->biHeight);
}
- break;
- }
- case VIDEO_MPEG4: {
- int pos = 0, vop_cnt=0, units[3];
- videobuf_len=0; videobuf_code_len=0;
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for Video Object Start code... ");
- while(1){
- int i=sync_video_packet(d_video);
- if(i<=0x11F) break; // found it!
- if(!i || !skip_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
- if(!videobuffer) {
- videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
- if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
- else {
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for Video Object Layer Start code... ");
- while(1){
- int i=sync_video_packet(d_video);
- mp_msg(MSGT_DECVIDEO,MSGL_V,"M4V: 0x%X\n",i);
- if(i>=0x120 && i<=0x12F) break; // found it!
- if(!i || !read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- return 0;
- }
- }
- pos = videobuf_len+4;
- if(!read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read Video Object Layer Header\n");
- return 0;
- }
- mp4_header_process_vol(&picture, &(videobuffer[pos]));
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK! FPS SEEMS TO BE %.3f\nSearching for Video Object Plane Start code... ", sh_video->fps);
- mp4_init:
- while(1){
- int i=sync_video_packet(d_video);
- if(i==0x1B6) break; // found it!
- if(!i || !read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- return 0;
- }
- }
- pos = videobuf_len+4;
- if(!read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read Video Object Plane Header\n");
- return 0;
- }
- mp4_header_process_vop(&picture, &(videobuffer[pos]));
- sh_video->disp_w = picture.display_picture_width;
- sh_video->disp_h = picture.display_picture_height;
- units[vop_cnt] = picture.timeinc_unit;
- vop_cnt++;
- //mp_msg(MSGT_DECVIDEO,MSGL_V, "TYPE: %d, unit: %d\n", picture.picture_type, picture.timeinc_unit);
- if(!picture.fps) {
- int i, mn, md, mx, diff;
- if(vop_cnt < 3)
- goto mp4_init;
-
- i=0;
- mn = mx = units[0];
- for(i=0; i<3; i++) {
- if(units[i] < mn)
- mn = units[i];
- if(units[i] > mx)
- mx = units[i];
- }
- md = mn;
- for(i=0; i<3; i++) {
- if((units[i] > mn) && (units[i] < mx))
- md = units[i];
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V, "MIN: %d, mid: %d, max: %d\n", mn, md, mx);
- if(mx - md > md - mn)
- diff = md - mn;
- else
- diff = mx - md;
- if(diff > 0){
- picture.fps = ((float)picture.timeinc_resolution) / diff;
- mp_msg(MSGT_DECVIDEO,MSGL_V, "FPS seems to be: %f, resolution: %d, delta_units: %d\n", picture.fps, picture.timeinc_resolution, diff);
- }
- }
- if(picture.fps) {
- sh_video->fps=picture.fps;
- sh_video->frametime=1.0/picture.fps;
- mp_msg(MSGT_DECVIDEO,MSGL_INFO, "FPS seems to be: %f\n", picture.fps);
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
- sh_video->format=0x10000004;
- break;
- }
- case VIDEO_H264: {
- int pos = 0;
- videobuf_len=0; videobuf_code_len=0;
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence parameter set... ");
- while(1){
- int i=sync_video_packet(d_video);
- if((i&~0x60) == 0x107 && i != 0x107) break; // found it!
- if(!i || !skip_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
- if(!videobuffer) {
- videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
- if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
- else {
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
- return 0;
- }
- }
- pos = videobuf_len+4;
- if(!read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read sequence parameter set\n");
- return 0;
- }
- h264_parse_sps(&picture, &(videobuffer[pos]), videobuf_len - pos);
- sh_video->disp_w=picture.display_picture_width;
- sh_video->disp_h=picture.display_picture_height;
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for picture parameter set... ");
- while(1){
- int i=sync_video_packet(d_video);
- mp_msg(MSGT_DECVIDEO,MSGL_V,"H264: 0x%X\n",i);
- if((i&~0x60) == 0x108 && i != 0x108) break; // found it!
- if(!i || !read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\nSearching for Slice... ");
- while(1){
- int i=sync_video_packet(d_video);
- if((i&~0x60) == 0x101 || (i&~0x60) == 0x102 || (i&~0x60) == 0x105) break; // found it!
- if(!i || !read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
- sh_video->format=0x10000005;
- if(picture.fps) {
- sh_video->fps=picture.fps;
- sh_video->frametime=1.0/picture.fps;
- mp_msg(MSGT_DECVIDEO,MSGL_INFO, "FPS seems to be: %f\n", picture.fps);
- }
- break;
- }
- case VIDEO_MPEG12: {
- if (d_video->demuxer->file_format == DEMUXER_TYPE_ASF) { // DVR-MS
- if(!sh_video->bih) return 0;
- sh_video->format=sh_video->bih->biCompression;
- }
-mpeg_header_parser:
- // Find sequence_header first:
- videobuf_len=0; videobuf_code_len=0;
- telecine=0; telecine_cnt=-2.5;
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence header... ");
- while(1){
- int i=sync_video_packet(d_video);
- if(i==0x1B3) break; // found it!
- if(!i || !skip_video_packet(d_video)){
- if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"MPEG: FATAL: EOF while searching for sequence header.\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
- // ========= Read & process sequence header & extension ============
- if(!videobuffer) {
- videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
- if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
- else {
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
- return 0;
- }
- }
-
- if(!read_video_packet(d_video)){
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"FATAL: Cannot read sequence header.\n");
- return 0;
- }
- if(mp_header_process_sequence_header (&picture, &videobuffer[4])) {
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"MPEG: bad sequence header\n");
- goto mpeg_header_parser;
- }
- if(sync_video_packet(d_video)==0x1B5){ // next packet is seq. ext.
- int pos=videobuf_len;
- if(!read_video_packet(d_video)){
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"FATAL: Cannot read sequence header extension.\n");
- return 0;
- }
- if(mp_header_process_extension (&picture, &videobuffer[pos+4])) {
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"MPEG: bad sequence header extension\n");
- return 0;
- }
- }
-
- // display info:
- sh_video->format=picture.mpeg1?0x10000001:0x10000002; // mpeg video
- sh_video->fps=picture.fps * picture.frame_rate_extension_n / picture.frame_rate_extension_d;
- if(!sh_video->fps){
- sh_video->frametime=0;
- } else {
- sh_video->frametime=1.0/sh_video->fps;
- }
- sh_video->disp_w=picture.display_picture_width;
- sh_video->disp_h=picture.display_picture_height;
- // bitrate:
- if(picture.bitrate!=0x3FFFF) // unspecified/VBR ?
- sh_video->i_bps=picture.bitrate * 400 / 8;
- // info:
- mp_dbg(MSGT_DECVIDEO,MSGL_DBG2,"mpeg bitrate: %d (%X)\n",picture.bitrate,picture.bitrate);
- mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: %s %dx%d (aspect %d) %5.3f fps %5.1f kbps (%4.1f kbyte/s)\n",
- picture.mpeg1?"MPEG1":"MPEG2",
- sh_video->disp_w,sh_video->disp_h,
- picture.aspect_ratio_information,
- sh_video->fps,
- sh_video->i_bps * 8 / 1000.0,
- sh_video->i_bps / 1000.0 );
- break;
- }
- case VIDEO_VC1: {
- // Find sequence_header:
- videobuf_len=0;
- videobuf_code_len=0;
- mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Searching for VC1 sequence header... ");
- while(1){
- int i=sync_video_packet(d_video);
- if(i==0x10F) break; // found it!
- if(!i || !skip_video_packet(d_video)){
- if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
- mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Couldn't find VC-1 sequence header\n");
- return 0;
- }
- }
- mp_msg(MSGT_DECVIDEO,MSGL_INFO,"found\n");
- if(!videobuffer) {
- videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
- if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
- else {
- mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
- return 0;
- }
- }
- if(!read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Couldn't read VC-1 sequence header!\n");
- return 0;
- }
-
- while(1) {
- int i=sync_video_packet(d_video);
- if(i==0x10E) break; // found it!
- if(!i || !skip_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Couldn't find VC-1 entry point sync-code:(\n");
- return 0;
- }
- }
- if(!read_video_packet(d_video)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"Couldn't read VC-1 entry point sync-code:(\n");
- return 0;
- }
-
- if(mp_vc1_decode_sequence_header(&picture, &videobuffer[4], videobuf_len-4)) {
- sh_video->bih = calloc(1, sizeof(*sh_video->bih) + videobuf_len);
- if(sh_video->bih == NULL) {
- mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Couldn't alloc %zu bytes for VC-1 extradata!\n", sizeof(*sh_video->bih) + videobuf_len);
- return 0;
- }
- sh_video->bih->biSize= sizeof(*sh_video->bih) + videobuf_len;
- memcpy(sh_video->bih + 1, videobuffer, videobuf_len);
- sh_video->bih->biCompression = sh_video->format;
- sh_video->bih->biWidth = sh_video->disp_w = picture.display_picture_width;
- sh_video->bih->biHeight = sh_video->disp_h = picture.display_picture_height;
- if(picture.fps > 0) {
- sh_video->frametime=1.0/picture.fps;
- sh_video->fps = picture.fps;
- }
- mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: VC-1 %dx%d, %5.3f fps, header len: %d\n",
- sh_video->disp_w, sh_video->disp_h, sh_video->fps, videobuf_len);
- }
- break;
- }
-} // switch(file_format)
return 1;
}
-static void process_userdata(const unsigned char* buf,int len){
- int i;
- /* if the user data starts with "CC", assume it is a CC info packet */
- if(len>2 && buf[0]=='C' && buf[1]=='C'){
-// mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"video.c: process_userdata() detected Closed Captions!\n");
- subcc_process_data(buf+2,len-2);
- }
-#ifdef DEMUX_TY_OSD
- if( len > 2 && buf[ 0 ] == 'T' && buf[ 1 ] == 'Y' )
- {
- ty_processuserdata( buf + 2, len - 2 );
- return;
- }
-#endif
- if(verbose<2) return;
- fprintf(stderr, "user_data: len=%3d %02X %02X %02X %02X '",
- len, buf[0], buf[1], buf[2], buf[3]);
- for(i=0;i<len;i++)
-// if(buf[i]>=32 && buf[i]<127) fputc(buf[i], stderr);
- if(buf[i]&0x60) fputc(buf[i]&0x7F, stderr);
- fprintf(stderr, "'\n");
-}
-
int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char** start,int force_fps){
demux_stream_t *d_video=sh_video->ds;
demuxer_t *demuxer=d_video->demuxer;
float frame_time=1;
float pts1=d_video->pts;
- float pts=0;
- float fps;
- int picture_coding_type=0;
int in_size=0;
- video_codec_t video_codec = find_video_codec(sh_video);
*start=NULL;
- if(video_codec == VIDEO_MPEG12){
- int in_frame=0;
- //float newfps;
- //videobuf_len=0;
- while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
- int i=sync_video_packet(d_video);
- //void* buffer=&videobuffer[videobuf_len+4];
- int start=videobuf_len+4;
- if(in_frame){
- if(i<0x101 || i>=0x1B0){ // not slice code -> end of frame
- if(!i) return -1; // EOF
- break;
- }
- } else {
- if(i==0x100){
- pts=d_video->pts;
- d_video->pts=0;
- }
- if(i>=0x101 && i<0x1B0) in_frame=1; // picture startcode
- else if(!i) return -1; // EOF
- }
- if(!read_video_packet(d_video)) return -1; // EOF
- // process headers:
- switch(i){
- case 0x1B3: mp_header_process_sequence_header (&picture, &videobuffer[start]);break;
- case 0x1B5: mp_header_process_extension (&picture, &videobuffer[start]);break;
- case 0x1B2: process_userdata (&videobuffer[start], videobuf_len-start);break;
- case 0x100: picture_coding_type=(videobuffer[start+1] >> 3) & 7;break;
- }
- }
- fps = picture.fps * picture.frame_rate_extension_n / picture.frame_rate_extension_d;
-
- *start=videobuffer; in_size=videobuf_len;
-
- // get mpeg fps:
- if(sh_video->fps!=fps) if(!force_fps && !telecine){
- mp_msg(MSGT_CPLAYER,MSGL_WARN,"Warning! FPS changed %5.3f -> %5.3f (%f) [%d] \n",sh_video->fps,fps,sh_video->fps-fps,picture.frame_rate_code);
- sh_video->fps=fps;
- sh_video->frametime=1.0/fps;
- }
-
- // fix mpeg2 frametime:
- frame_time=(picture.display_time)*0.01f;
- picture.display_time=100;
- videobuf_len=0;
-
- telecine_cnt*=0.9; // drift out error
- telecine_cnt+=frame_time-5.0/4.0;
- mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"\r telecine = %3.1f %5.3f \n",frame_time,telecine_cnt);
-
- if(telecine){
- frame_time=1;
- if(telecine_cnt<-1.5 || telecine_cnt>1.5){
- mp_tmsg(MSGT_DECVIDEO,MSGL_INFO,"\ndemux_mpg: 30000/1001fps NTSC content detected, switching framerate.\n");
- telecine=0;
- }
- } else
- if(telecine_cnt>-0.5 && telecine_cnt<0.5 && !force_fps){
- sh_video->fps=sh_video->fps*4/5;
- sh_video->frametime=sh_video->frametime*5/4;
- mp_tmsg(MSGT_DECVIDEO,MSGL_INFO,"\ndemux_mpg: 24000/1001fps progressive NTSC content detected, switching framerate.\n");
- telecine=1;
- }
- } else if(video_codec == VIDEO_MPEG4){
- while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
- int i=sync_video_packet(d_video);
- if(!i) return -1;
- if(!read_video_packet(d_video)) return -1; // EOF
- if(i==0x1B6) break;
- }
- *start=videobuffer; in_size=videobuf_len;
- videobuf_len=0;
- } else if(video_codec == VIDEO_H264){
- int in_picture = 0;
- while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
- int i=sync_video_packet(d_video);
- int pos = videobuf_len+4;
- if(!i) return -1;
- if(!read_video_packet(d_video)) return -1; // EOF
- if((i&~0x60) == 0x107 && i != 0x107) {
- h264_parse_sps(&picture, &(videobuffer[pos]), videobuf_len - pos);
- if(picture.fps > 0) {
- sh_video->fps=picture.fps;
- sh_video->frametime=1.0/picture.fps;
- }
- i=sync_video_packet(d_video);
- if(!i) return -1;
- if(!read_video_packet(d_video)) return -1; // EOF
- }
-
- // here starts the access unit end detection code
- // see the mail on MPlayer-dev-eng for details:
- // Date: Sat, 17 Sep 2005 11:24:06 +0200
- // Subject: Re: [MPlayer-dev-eng] [RFC] h264 ES parser problems
- // Message-ID: <20050917092406.GA7699@rz.uni-karlsruhe.de>
- if((i&~0x60) == 0x101 || (i&~0x60) == 0x102 || (i&~0x60) == 0x105)
- // found VCL NAL with slice header i.e. start of current primary coded
- // picture, so start scanning for the end now
- in_picture = 1;
- if (in_picture) {
- i = sync_video_packet(d_video) & ~0x60; // code of next packet
- if(i == 0x106 || i == 0x109) break; // SEI or access unit delim.
- if(i == 0x101 || i == 0x102 || i == 0x105) {
- // assuming arbitrary slice ordering is not allowed, the
- // first_mb_in_slice (golomb encoded) value should be 0 then
- // for the first VCL NAL in a picture
- if (demux_peekc(d_video) & 0x80)
- break;
- }
- }
- }
- *start=videobuffer; in_size=videobuf_len;
- videobuf_len=0;
- } else if(video_codec == VIDEO_VC1) {
- while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE) {
- int i=sync_video_packet(d_video);
- if(!i) return -1;
- if(!read_video_packet(d_video)) return -1; // EOF
- if(i==0x10D) break;
- }
- *start=videobuffer;
- in_size=videobuf_len;
- videobuf_len=0;
- } else {
// frame-based file formats: (AVI,ASF,MOV)
in_size=ds_get_packet(d_video,start);
if(in_size<0) return -1; // EOF
- }
//------------------------ frame decoded. --------------------
@@ -592,10 +93,7 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
frame_time=d_video->pts-pts1;
break;
case DEMUXER_TYPE_TV:
- case DEMUXER_TYPE_MOV:
- case DEMUXER_TYPE_FILM:
case DEMUXER_TYPE_VIVO:
- case DEMUXER_TYPE_OGG:
case DEMUXER_TYPE_ASF: {
double next_pts = ds_get_next_pts(d_video);
double d= (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts-pts1;
@@ -633,21 +131,8 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
break;
}
- if(video_codec == VIDEO_MPEG12){
- sh_video->pts+=frame_time;
- if(picture_coding_type==1)
- d_video->keyframe = true;
- if(picture_coding_type<=2 && sh_video->i_pts){
- sh_video->pts=sh_video->i_pts;
- sh_video->i_pts=pts;
- } else {
- if(pts){
- if(picture_coding_type<=2) sh_video->i_pts=pts;
- else sh_video->pts=pts;
- }
- }
- } else
- sh_video->pts=d_video->pts;
+
+ sh_video->pts=d_video->pts;
if(frame_time_ptr) *frame_time_ptr=frame_time;
return in_size;
diff --git a/mplayer.c b/mplayer.c
index 96e549745e..261fbea109 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -4237,10 +4237,6 @@ goto_enable_cache:
mpctx->d_video = mpctx->demuxer->video;
mpctx->d_sub = mpctx->demuxer->sub;
- if (ts_prog) {
- int tmp = ts_prog;
- mp_property_do("switch_program", M_PROPERTY_SET, &tmp, mpctx);
- }
// select audio stream
for (int i = 0; i < mpctx->num_sources; i++)
select_audio(mpctx->sources[i].demuxer->audio->demuxer, opts->audio_id,
@@ -4288,7 +4284,7 @@ goto_enable_cache:
while (!ds->eof) {
unsigned char *start;
int in_size = ds_get_packet(ds, &start);
- if ((mpctx->demuxer->file_format == DEMUXER_TYPE_AVI || mpctx->demuxer->file_format == DEMUXER_TYPE_ASF || mpctx->demuxer->file_format == DEMUXER_TYPE_MOV)
+ if ((mpctx->demuxer->file_format == DEMUXER_TYPE_AVI || mpctx->demuxer->file_format == DEMUXER_TYPE_ASF)
&& stream_dump_type == 2)
fwrite(&in_size, 1, 4, f);
if (in_size > 0) {
diff --git a/stream/network.c b/stream/network.c
index 0961c8d12b..b1212ab5e2 100644
--- a/stream/network.c
+++ b/stream/network.c
@@ -65,23 +65,8 @@ int network_ipv4_only_proxy = 0;
const mime_struct_t mime_type_table[] = {
- // Flash Video
- { "video/x-flv", DEMUXER_TYPE_LAVF_PREFERRED},
- // do not force any demuxer in this case!
- // we want the lavf demuxer to be tried first (happens automatically anyway),
- // but for mov reference files to work we must also try
- // the native demuxer if lavf fails.
- { "video/quicktime", 0 },
// MP3 streaming, some MP3 streaming server answer with audio/mpeg
{ "audio/mpeg", DEMUXER_TYPE_AUDIO },
- // MPEG streaming
- { "video/mpeg", DEMUXER_TYPE_UNKNOWN },
- { "video/x-mpeg", DEMUXER_TYPE_UNKNOWN },
- { "video/x-mpeg2", DEMUXER_TYPE_UNKNOWN },
- // AVI ??? => video/x-msvideo
- { "video/x-msvideo", DEMUXER_TYPE_AVI },
- // MOV => video/quicktime
- { "video/quicktime", DEMUXER_TYPE_MOV },
// ASF
{ "audio/x-ms-wax", DEMUXER_TYPE_ASF },
{ "audio/x-ms-wma", DEMUXER_TYPE_ASF },
@@ -91,7 +76,6 @@ const mime_struct_t mime_type_table[] = {
{ "video/x-ms-wma", DEMUXER_TYPE_ASF },
{ "application/x-mms-framed", DEMUXER_TYPE_ASF },
{ "application/vnd.ms.wms-hdr.asfv1", DEMUXER_TYPE_ASF },
- { "application/octet-stream", DEMUXER_TYPE_UNKNOWN },
// Playlists
{ "video/x-ms-wmx", DEMUXER_TYPE_PLAYLIST },
{ "video/x-ms-wvx", DEMUXER_TYPE_PLAYLIST },
@@ -100,11 +84,6 @@ const mime_struct_t mime_type_table[] = {
{ "audio/x-pls", DEMUXER_TYPE_PLAYLIST },
// Real Media
// { "audio/x-pn-realaudio", DEMUXER_TYPE_REAL },
- // OGG Streaming
- { "application/x-ogg", DEMUXER_TYPE_OGG },
- // NullSoft Streaming Video
- { "video/nsv", DEMUXER_TYPE_NSV},
- { "misc/ultravox", DEMUXER_TYPE_NSV},
{ NULL, DEMUXER_TYPE_UNKNOWN},
};