#
PLUGINS_DIR := ac3_adec \
ac3_spdif \
+ access \
alsa \
arts \
beos \
PLUGINS_TARGETS := ac3_adec/ac3_adec \
ac3_spdif/ac3_spdif \
+ access/file \
+ access/udp \
+ access/http \
alsa/alsa \
arts/arts \
beos/beos \
mpeg_system/mpeg_ts \
mpeg_adec/mpeg_adec \
mpeg_vdec/mpeg_vdec \
+ network/ipv4 \
qnx/qnx \
qt/qt \
sdl/sdl \
# C Objects
#
INTERFACE := main interface intf_msg intf_playlist intf_eject
-INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system
+INPUT := input input_ext-plugins input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system
VIDEO_OUTPUT := video_output video_text vout_pictures vout_subpictures
AUDIO_OUTPUT := audio_output aout_ext-dec aout_pcm aout_spdif
MISC := mtime modules configuration netutils iso_lang
;;
esac
-BUILTINS="${BUILTINS} mpeg_es mpeg_ps mpeg_ts memcpy idct idctclassic motion imdct downmix chroma_i420_rgb chroma_i420_yuy2 chroma_i422_yuy2 chroma_i420_ymga mpeg_adec ac3_adec mpeg_vdec"
+BUILTINS="${BUILTINS} mpeg_es mpeg_ps mpeg_ts file udp http ipv4 memcpy idct idctclassic motion imdct downmix chroma_i420_rgb chroma_i420_yuy2 chroma_i422_yuy2 chroma_i420_ymga mpeg_adec ac3_adec mpeg_vdec"
PLUGINS="${PLUGINS} lpcm_adec ac3_spdif spudec filter_deinterlace filter_invert filter_wall filter_transform filter_distort fx_scope"
MMX_MODULES="memcpymmx idctmmx motionmmx chroma_i420_rgb_mmx chroma_i420_yuy2_mmx chroma_i422_yuy2_mmx chroma_i420_ymga_mmx"
case "x${withval}" in
xlocal-static|xyes)
# local libdvdcss, statically linked
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
if test x${CAN_BUILD_LIBDVDCSS} = x1
then
NEED_LIBDVDCSS=1
;;
xlocal-shared)
# local libdvdcss, dynamically linked
- PLUGINS="${PLUGINS} dvd"
+ #PLUGINS="${PLUGINS} dvd"
if test x${CAN_BUILD_LIBDVDCSS} = x1
then
NEED_LIBDVDCSS=1
;;
xno)
# don't use libdvdcss at all, build a DVD module that can dlopen() it
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
DUMMY_LIBDVDCSS=1
SRC_DVD_EXTRA="${SRC_DVD_EXTRA} dummy_dvdcss.c"
CFLAGS_DVD="${CFLAGS_DVD} -DGOD_DAMN_DMCA"
;;
*)
# existing libdvdcss
- PLUGINS="${PLUGINS} dvd"
+ #PLUGINS="${PLUGINS} dvd"
if test "x$withval" != "xyes"
then
LIB_DVD="${LIB_DVD} -L"$withval"/lib"
# if libdvdcss is in the archive, or to use the dummy replacement otherwise.
if test x${CAN_BUILD_LIBDVDCSS} = x1
then
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
NEED_LIBDVDCSS=1
STATIC_LIBDVDCSS=1
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} lib/libdvdcss.a ${LIB_LIBDVDCSS}"
else
# XXX: no check for libdl is done, don't try this at home !
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
DUMMY_LIBDVDCSS=1
SRC_DVD_EXTRA="${SRC_DVD_EXTRA} dummy_dvdcss.c"
CFLAGS_DVD="${CFLAGS_DVD} -DGOD_DAMN_DMCA"
x)
if test x${STATIC_LIBDVDREAD} = x1
then
- BUILTINS="${BUILTINS} dvdread"
+ #BUILTINS="${BUILTINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} ${CFLAGS_DVD} -I../../extras/libdvdread"
LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a ${LIB_DVD}"
else
- PLUGINS="${PLUGINS} dvdread"
+ #PLUGINS="${PLUGINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} -I../../extras/libdvdread ${CFLAGS_DVD}"
LIB_DVDREAD="${LIB_DVDREAD} -Llib -ldvdread ${LIB_DVD}"
fi
then
{ echo "configure: error: Can't link shared dvdread with static dvdcss" 1>&2; exit 1; }
else
- PLUGINS="${PLUGINS} dvdread"
+ #PLUGINS="${PLUGINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} ${CFLAGS_DVD}"
LIB_DVDREAD="${LIB_DVDREAD} -ldvdread ${LIB_DVD}"
fi
egrep "cdrom_msf0" >/dev/null 2>&1; then
rm -rf conftest*
- BUILTINS="${BUILTINS} vcd"
+ #BUILTINS="${BUILTINS} vcd"
fi
rm -f conftest*
if test x$enable_vcd != xno -a "${SYS}" = "bsdi"
then
- BUILTINS="${BUILTINS} vcd"
+ #BUILTINS="${BUILTINS} vcd"
+true #delete me
fi
if test x$enable_vcd != xno -a "${SYS}" = "darwin"
then
- BUILTINS="${BUILTINS} vcd"
+ #BUILTINS="${BUILTINS} vcd"
LIB_VCD="${LIB_VCD} -framework IOKit"
fi
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6609: checking for $ac_hdr" >&5
+echo "configure:6610: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6614 "configure"
+#line 6615 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6619: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6620: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
done
echo $ac_n "checking for mad_bit_init in -lmad""... $ac_c" 1>&6
-echo "configure:6649: checking for mad_bit_init in -lmad" >&5
+echo "configure:6650: checking for mad_bit_init in -lmad" >&5
ac_lib_var=`echo mad'_'mad_bit_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lmad $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6657 "configure"
+#line 6658 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
mad_bit_init()
; return 0; }
EOF
-if { (eval echo configure:6668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6725: checking for $ac_hdr" >&5
+echo "configure:6726: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6730 "configure"
+#line 6731 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6735: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
PLUGINS="${PLUGINS} dsp"
echo $ac_n "checking for main in -lossaudio""... $ac_c" 1>&6
-echo "configure:6758: checking for main in -lossaudio" >&5
+echo "configure:6759: checking for main in -lossaudio" >&5
ac_lib_var=`echo ossaudio'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lossaudio $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6766 "configure"
+#line 6767 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:6773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
# Extract the first word of "esd-config", so it can be a program name with args.
set dummy esd-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6809: checking for $ac_word" >&5
+echo "configure:6810: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_ESD_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "artsc-config", so it can be a program name with args.
set dummy artsc-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6860: checking for $ac_word" >&5
+echo "configure:6861: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_ARTS_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6918: checking for $ac_hdr" >&5
+echo "configure:6919: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6923 "configure"
+#line 6924 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6928: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6929: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6973: checking for $ac_hdr" >&5
+echo "configure:6974: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6978 "configure"
+#line 6979 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6983: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6984: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7026: checking for $ac_hdr" >&5
+echo "configure:7027: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7031 "configure"
+#line 7032 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7036: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
# Extract the first word of "sdl12-config", so it can be a program name with args.
set dummy sdl12-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7124: checking for $ac_word" >&5
+echo "configure:7125: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SDL12_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "sdl11-config", so it can be a program name with args.
set dummy sdl11-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7164: checking for $ac_word" >&5
+echo "configure:7165: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SDL11_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "sdl-config", so it can be a program name with args.
set dummy sdl-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7205: checking for $ac_word" >&5
+echo "configure:7206: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SDL_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7251: checking for $ac_hdr" >&5
+echo "configure:7252: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7256 "configure"
+#line 7257 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7261: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7262: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7331: checking for $ac_hdr" >&5
+echo "configure:7332: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7336 "configure"
+#line 7337 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7342: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
else
echo $ac_n "checking for directX headers in ${withval}""... $ac_c" 1>&6
-echo "configure:7370: checking for directX headers in ${withval}" >&5
+echo "configure:7371: checking for directX headers in ${withval}" >&5
if test -f ${withval}/ddraw.h
then
PLUGINS="${PLUGINS} directx"
# Extract the first word of "gnome-config", so it can be a program name with args.
set dummy gnome-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7479: checking for $ac_word" >&5
+echo "configure:7480: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GNOME_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7524: checking for $ac_hdr" >&5
+echo "configure:7525: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7529 "configure"
+#line 7530 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7534: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7535: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
# Extract the first word of "gtk12-config", so it can be a program name with args.
set dummy gtk12-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7594: checking for $ac_word" >&5
+echo "configure:7595: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GTK12_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "gtk-config", so it can be a program name with args.
set dummy gtk-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7633: checking for $ac_word" >&5
+echo "configure:7634: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7683: checking for $ac_hdr" >&5
+echo "configure:7684: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7688 "configure"
+#line 7689 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7693: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7694: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7751: checking for $ac_hdr" >&5
+echo "configure:7752: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7756 "configure"
+#line 7757 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7761: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7762: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7814: checking for $ac_hdr" >&5
+echo "configure:7815: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7819 "configure"
+#line 7820 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7824: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7825: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
saved_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -L$x_libraries -lX11 -lXext"
echo $ac_n "checking for XvSetPortAttribute in -lXv_pic""... $ac_c" 1>&6
-echo "configure:7848: checking for XvSetPortAttribute in -lXv_pic" >&5
+echo "configure:7849: checking for XvSetPortAttribute in -lXv_pic" >&5
ac_lib_var=`echo Xv_pic'_'XvSetPortAttribute | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lXv_pic $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7856 "configure"
+#line 7857 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
XvSetPortAttribute()
; return 0; }
EOF
-if { (eval echo configure:7867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
then
ac_safe=`echo "lirc/lirc_client.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for lirc/lirc_client.h""... $ac_c" 1>&6
-echo "configure:7914: checking for lirc/lirc_client.h" >&5
+echo "configure:7915: checking for lirc/lirc_client.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7919 "configure"
+#line 7920 "configure"
#include "confdefs.h"
#include <lirc/lirc_client.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7924: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7925: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for lirc_init in -llirc_client""... $ac_c" 1>&6
-echo "configure:7941: checking for lirc_init in -llirc_client" >&5
+echo "configure:7942: checking for lirc_init in -llirc_client" >&5
ac_lib_var=`echo lirc_client'_'lirc_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-llirc_client $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7949 "configure"
+#line 7950 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
lirc_init()
; return 0; }
EOF
-if { (eval echo configure:7960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
then
ac_safe=`echo "alsa/asoundlib.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for alsa/asoundlib.h""... $ac_c" 1>&6
-echo "configure:8000: checking for alsa/asoundlib.h" >&5
+echo "configure:8001: checking for alsa/asoundlib.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8005 "configure"
+#line 8006 "configure"
#include "confdefs.h"
#include <alsa/asoundlib.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8010: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8011: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6
-echo "configure:8027: checking for main in -lasound" >&5
+echo "configure:8028: checking for main in -lasound" >&5
ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lasound $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8035 "configure"
+#line 8036 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:8042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
dnl
dnl default modules
dnl
-BUILTINS="${BUILTINS} mpeg_es mpeg_ps mpeg_ts memcpy idct idctclassic motion imdct downmix chroma_i420_rgb chroma_i420_yuy2 chroma_i422_yuy2 chroma_i420_ymga mpeg_adec ac3_adec mpeg_vdec"
+BUILTINS="${BUILTINS} mpeg_es mpeg_ps mpeg_ts file udp http ipv4 memcpy idct idctclassic motion imdct downmix chroma_i420_rgb chroma_i420_yuy2 chroma_i422_yuy2 chroma_i420_ymga mpeg_adec ac3_adec mpeg_vdec"
PLUGINS="${PLUGINS} lpcm_adec ac3_spdif spudec filter_deinterlace filter_invert filter_wall filter_transform filter_distort fx_scope"
dnl
[ case "x${withval}" in
xlocal-static|xyes)
# local libdvdcss, statically linked
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
if test x${CAN_BUILD_LIBDVDCSS} = x1
then
NEED_LIBDVDCSS=1
;;
xlocal-shared)
# local libdvdcss, dynamically linked
- PLUGINS="${PLUGINS} dvd"
+ #PLUGINS="${PLUGINS} dvd"
if test x${CAN_BUILD_LIBDVDCSS} = x1
then
NEED_LIBDVDCSS=1
;;
xno)
# don't use libdvdcss at all, build a DVD module that can dlopen() it
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
DUMMY_LIBDVDCSS=1
SRC_DVD_EXTRA="${SRC_DVD_EXTRA} dummy_dvdcss.c"
CFLAGS_DVD="${CFLAGS_DVD} -DGOD_DAMN_DMCA"
;;
*)
# existing libdvdcss
- PLUGINS="${PLUGINS} dvd"
+ #PLUGINS="${PLUGINS} dvd"
if test "x$withval" != "xyes"
then
LIB_DVD="${LIB_DVD} -L"$withval"/lib"
# if libdvdcss is in the archive, or to use the dummy replacement otherwise.
[ if test x${CAN_BUILD_LIBDVDCSS} = x1
then
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
NEED_LIBDVDCSS=1
STATIC_LIBDVDCSS=1
CFLAGS_DVD="${CFLAGS_DVD} -I../../extras/libdvdcss"
LIB_DVD="${LIB_DVD} lib/libdvdcss.a ${LIB_LIBDVDCSS}"
else
# XXX: no check for libdl is done, don't try this at home !
- BUILTINS="${BUILTINS} dvd"
+ #BUILTINS="${BUILTINS} dvd"
DUMMY_LIBDVDCSS=1
SRC_DVD_EXTRA="${SRC_DVD_EXTRA} dummy_dvdcss.c"
CFLAGS_DVD="${CFLAGS_DVD} -DGOD_DAMN_DMCA"
x)
if test x${STATIC_LIBDVDREAD} = x1
then
- BUILTINS="${BUILTINS} dvdread"
+ #BUILTINS="${BUILTINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} ${CFLAGS_DVD} -I../../extras/libdvdread"
LIB_DVDREAD="${LIB_DVDREAD} lib/libdvdread.a ${LIB_DVD}"
else
- PLUGINS="${PLUGINS} dvdread"
+ #PLUGINS="${PLUGINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} -I../../extras/libdvdread ${CFLAGS_DVD}"
LIB_DVDREAD="${LIB_DVDREAD} -Llib -ldvdread ${LIB_DVD}"
fi
then
AC_MSG_ERROR([Can't link shared dvdread with static dvdcss])
else
- PLUGINS="${PLUGINS} dvdread"
+ #PLUGINS="${PLUGINS} dvdread"
CFLAGS_DVDREAD="${CFLAGS_DVDREAD} ${CFLAGS_DVD}"
LIB_DVDREAD="${LIB_DVDREAD} -ldvdread ${LIB_DVD}"
fi
if test x$enable_vcd != xno
then
AC_EGREP_HEADER(cdrom_msf0,linux/cdrom.h,[
- BUILTINS="${BUILTINS} vcd"
+ #BUILTINS="${BUILTINS} vcd"
])
fi
if test x$enable_vcd != xno -a "${SYS}" = "bsdi"
then
- BUILTINS="${BUILTINS} vcd"
+ #BUILTINS="${BUILTINS} vcd"
+true #delete me
fi
if test x$enable_vcd != xno -a "${SYS}" = "darwin"
then
- BUILTINS="${BUILTINS} vcd"
+ #BUILTINS="${BUILTINS} vcd"
LIB_VCD="${LIB_VCD} -framework IOKit"
fi
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.79 2002/02/27 03:47:56 sam Exp $
+ * $Id: common.h,v 1.80 2002/03/01 00:33:17 massiot Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
struct pes_packet_s;
struct input_area_s;
struct bit_stream_s;
+struct input_buffers_s;
+struct network_socket_s;
struct intf_subscription_s;
/*****************************************************************************
struct data_packet_s *,
struct es_descriptor_s *,
boolean_t, boolean_t );
-
int ( * input_ClockManageControl ) ( struct input_thread_s *,
struct pgrm_descriptor_s *,
mtime_t );
+ void ( * input_FDSeek ) ( struct input_thread_s *, off_t );
+ void ( * input_FDClose ) ( struct input_thread_s * );
+ ssize_t ( * input_FDRead ) ( struct input_thread_s *, byte_t *,
+ size_t );
+ ssize_t ( * input_FDNetworkRead ) ( struct input_thread_s *, byte_t *,
+ size_t );
+ void * ( * input_BuffersInit )( void );
+ void ( * input_BuffersEnd )( struct input_buffers_s * );
+ struct data_buffer_s * ( * input_NewBuffer )( struct input_buffers_s *, size_t );
+ void ( * input_ReleaseBuffer )( struct input_buffers_s *, struct data_buffer_s * );
+ struct data_packet_s * ( * input_ShareBuffer )( struct input_buffers_s *,
+ struct data_buffer_s * );
+ struct data_packet_s * ( * input_NewPacket )( struct input_buffers_s *, size_t );
+ void ( * input_DeletePacket )( struct input_buffers_s *, struct data_packet_s * );
+ struct pes_packet_s * ( * input_NewPES )( struct input_buffers_s * );
+ void ( * input_DeletePES )( struct input_buffers_s *, struct pes_packet_s * );
+ ssize_t ( * input_FillBuffer )( struct input_thread_s * );
+ ssize_t ( * input_Peek )( struct input_thread_s *, byte_t **, size_t );
+ ssize_t ( * input_SplitBuffer )( struct input_thread_s *, struct data_packet_s **, size_t );
+ int ( * input_AccessInit )( struct input_thread_s * );
+ void ( * input_AccessReinit )( struct input_thread_s * );
+ void ( * input_AccessEnd )( struct input_thread_s * );
struct aout_fifo_s * ( * aout_CreateFifo ) ( int, int, int, int, void * );
void ( * aout_DestroyFifo ) ( struct aout_fifo_s * );
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_ext-dec.h,v 1.52 2002/01/21 23:57:46 massiot Exp $
+ * $Id: input_ext-dec.h,v 1.53 2002/03/01 00:33:17 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
*****************************************************************************
* Describe a data packet.
*****************************************************************************/
-#define DATA_PACKET \
- /* start of the PS or TS packet */ \
- byte_t * p_demux_start; \
- /* start of the PES payload in this packet */ \
- byte_t * p_payload_start; \
- byte_t * p_payload_end; /* guess ? :-) */ \
- /* is the packet messed up ? */ \
- boolean_t b_discard_payload;
-
typedef struct data_packet_s
{
/* Used to chain the packets that carry data for a same PES or PSI */
struct data_packet_s * p_next;
- DATA_PACKET
+ /* start of the PS or TS packet */
+ byte_t * p_demux_start;
+ /* start of the PES payload in this packet */
+ byte_t * p_payload_start;
+ byte_t * p_payload_end; /* guess ? :-) */
+ /* is the packet messed up ? */
+ boolean_t b_discard_payload;
- /* Please note that at least one buffer allocator (in particular, the
- * Next Generation Buffer Allocator) extends this structure with
- * private data after DATA_PACKET. */
+ /* pointer to the real data */
+ struct data_buffer_s * p_buffer;
} data_packet_t;
/*****************************************************************************
/* Communication interface between input and decoders */
boolean_t b_die; /* the decoder should return now */
boolean_t b_error; /* the decoder is in an error loop */
- void * p_packets_mgt; /* packets management services
- * data (netlist...) */
- void (* pf_delete_pes)( void *, pes_packet_t * );
- /* function to use when releasing a PES */
+ struct input_buffers_s *p_packets_mgt; /* packets management services
+ * data */
} decoder_fifo_t;
/*****************************************************************************
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.60 2002/02/24 21:36:20 jobi Exp $
+ * $Id: input_ext-intf.h,v 1.61 2002/03/01 00:33:17 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
vlc_thread_t thread_id; /* id for thread functions */
int i_status; /* status flag */
- /* Input module */
- struct module_s * p_input_module;
-
- /* Init/End */
- int (* pf_probe)( struct input_thread_s * );
- void (* pf_init)( struct input_thread_s * );
- void (* pf_open)( struct input_thread_s * );
+ /* Access module */
+ struct module_s * p_access_module;
+ int (* pf_open)( struct input_thread_s * );
void (* pf_close)( struct input_thread_s * );
- void (* pf_end)( struct input_thread_s * );
-
- /* Read & Demultiplex */
- int (* pf_read)( struct input_thread_s *,
- struct data_packet_s ** );
- void (* pf_demux)( struct input_thread_s *,
- struct data_packet_s * );
-
- /* Packet management facilities */
- struct data_packet_s *(*pf_new_packet)( void *, size_t );
- struct pes_packet_s *(* pf_new_pes)( void * );
- void (* pf_delete_packet)( void *,
- struct data_packet_s * );
- void (* pf_delete_pes)( void *, struct pes_packet_s * );
-
- /* Stream control capabilities */
+ ssize_t (* pf_read) ( struct input_thread_s *,
+ byte_t *, size_t );
int (* pf_set_program)( struct input_thread_s *,
struct pgrm_descriptor_s * );
int (* pf_set_area)( struct input_thread_s *,
struct input_area_s * );
+ void (* pf_seek)( struct input_thread_s *, off_t );
+ void * p_access_data;
+ size_t i_mtu;
+
+ /* Demux module */
+ struct module_s * p_demux_module;
+ int (* pf_init)( struct input_thread_s * );
+ void (* pf_end)( struct input_thread_s * );
+ int (* pf_demux)( struct input_thread_s * );
int (* pf_rewind)( struct input_thread_s * );
/* NULL if we don't support going *
* backwards (it's gonna be fun) */
- void (* pf_seek)( struct input_thread_s *, off_t );
+ void * p_demux_data; /* data of the demux */
- char * p_source;
-
- int i_handle; /* socket or file descriptor */
- FILE * p_stream; /* if applicable */
- void * p_handle; /* if i_handle isn't suitable */
- void * p_method_data; /* data of the packet manager */
- void * p_plugin_data; /* data of the plugin */
+ /* Buffer manager */
+ struct input_buffers_s *p_method_data; /* data of the packet manager */
+ struct data_buffer_s * p_data_buffer;
+ byte_t * p_current_data;
+ byte_t * p_last_data;
+ size_t i_bufsize;
/* General stream description */
- stream_descriptor_t stream; /* PAT tables */
+ stream_descriptor_t stream;
+
+ /* Playlist item */
+ char * psz_source;
+ char * psz_access;
+ char * psz_demux;
+ char * psz_name;
count_t c_loops;
} input_thread_t;
* input_ext-plugins.h: structures of the input not exported to other modules,
* but exported to plug-ins
*****************************************************************************
- * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_ext-plugins.h,v 1.17 2002/02/15 13:32:52 sam Exp $
+ * Copyright (C) 1999-2002 VideoLAN
+ * $Id: input_ext-plugins.h,v 1.18 2002/03/01 00:33:17 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* of data loss (this should be < 188). */
#define PADDING_PACKET_NUMBER 10 /* Number of padding packets top insert to
* escape a decoder. */
+#define INPUT_DEFAULT_BUFSIZE 65536 /* Default buffer size to use when none
+ * is natural. */
#define NO_SEEK -1
/*****************************************************************************
* Prototypes from input_dec.c
*****************************************************************************/
#ifndef PLUGIN
+//decoder_capabilities_s * input_ProbeDecoder( void );
vlc_thread_t input_RunDecoder( struct input_thread_s *,
struct es_descriptor_s * );
void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * );
# define input_ClockManageControl p_symbols->input_ClockManageControl
#endif
+/*****************************************************************************
+ * Prototypes from input_ext-plugins.h (buffers management)
+ *****************************************************************************/
+#ifndef PLUGIN
+void * input_BuffersInit( void );
+void input_BuffersEnd( struct input_buffers_s * );
+struct data_buffer_s * input_NewBuffer( struct input_buffers_s *, size_t );
+void input_ReleaseBuffer( struct input_buffers_s *, struct data_buffer_s * );
+struct data_packet_s * input_ShareBuffer( struct input_buffers_s *,
+ struct data_buffer_s * );
+struct data_packet_s * input_NewPacket( struct input_buffers_s *, size_t );
+void input_DeletePacket( struct input_buffers_s *, struct data_packet_s * );
+struct pes_packet_s * input_NewPES( struct input_buffers_s * );
+void input_DeletePES( struct input_buffers_s *, struct pes_packet_s * );
+ssize_t input_FillBuffer( struct input_thread_s * );
+ssize_t input_Peek( struct input_thread_s *, byte_t **, size_t );
+ssize_t input_SplitBuffer( struct input_thread_s *, data_packet_t **, size_t );
+int input_AccessInit( struct input_thread_s * );
+void input_AccessReinit( struct input_thread_s * );
+void input_AccessEnd( struct input_thread_s * );
+#else
+# define input_BuffersInit p_symbols->input_BuffersInit
+# define input_BuffersEnd p_symbols->input_BuffersEnd
+# define input_NewBuffer p_symbols->input_NewBuffer
+# define input_ReleaseBuffer p_symbols->input_ReleaseBuffer
+# define input_ShareBuffer p_symbols->input_ShareBuffer
+# define input_NewPacket p_symbols->input_NewPacket
+# define input_DeletePacket p_symbols->input_DeletePacket
+# define input_NewPES p_symbols->input_NewPES
+# define input_DeletePES p_symbols->input_DeletePES
+# define input_FillBuffer p_symbols->input_FillBuffer
+# define input_Peek p_symbols->input_Peek
+# define input_SplitBuffer p_symbols->input_SplitBuffer
+# define input_AccessInit p_symbols->input_AccessInit
+# define input_AccessReinit p_symbols->input_AccessReinit
+# define input_AccessEnd p_symbols->input_AccessEnd
+#endif
+
/*****************************************************************************
* Create a NULL packet for padding in case of a data loss
*****************************************************************************/
data_packet_t * p_pad_data;
pes_packet_t * p_pes;
- if( (p_pad_data = p_input->pf_new_packet(
- p_input->p_method_data,
+ if( (p_pad_data = input_NewPacket( p_input->p_method_data,
PADDING_PACKET_SIZE )) == NULL )
{
intf_ErrMsg("Out of memory");
}
else
{
- if( (p_pes = p_input->pf_new_pes( p_input->p_method_data )) == NULL )
+ if( (p_pes = input_NewPES( p_input->p_method_data )) == NULL )
{
intf_ErrMsg("Out of memory");
p_input->b_error = 1;
}
-/*
- * Optional Next Generation buffer manager
- *
- * Either buffers can only be used in one data packet (PS case), or buffers
- * contain several data packets (DVD case). In the first case, buffers are
- * embedded into data packets, otherwise they are allocated separately and
- * shared with a refcount. --Meuuh
- */
-
-/* Number of buffers for the calculation of the mean */
-#define INPUT_BRESENHAM_NB 50
-
-/* Flags */
-#define BUFFERS_NOFLAGS 0
-#define BUFFERS_UNIQUE_SIZE 1 /* Only with NB_LIFO == 1 */
-
-/*****************************************************************************
- * _input_buffers_t: defines a LIFO per data type to keep
- *****************************************************************************/
-#define PACKETS_LIFO( TYPE, NAME ) \
-struct \
-{ \
- TYPE * p_stack; \
- unsigned int i_depth; \
-} NAME;
-
-#define BUFFERS_LIFO( TYPE, NAME ) \
-struct \
-{ \
- TYPE * p_stack; /* First item in the LIFO */ \
- unsigned int i_depth; /* Number of items in the LIFO */ \
- unsigned int i_average_size; /* Average size of the items (Bresenham) */\
-} NAME;
-
-#define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \
-typedef struct _input_buffers_s \
-{ \
- vlc_mutex_t lock; \
- PACKETS_LIFO( pes_packet_t, pes ) \
- BUFFERS_LIFO( _data_packet_t, data[NB_LIFO] ) \
- size_t i_allocated; \
-} _input_buffers_t;
-
-#define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \
-typedef struct _input_buffers_s \
-{ \
- vlc_mutex_t lock; \
- PACKETS_LIFO( pes_packet_t, pes ) \
- PACKETS_LIFO( _data_packet_t, data ) \
- BUFFERS_LIFO( _data_buffer_t, buffers[NB_LIFO] ) \
- size_t i_allocated; \
-} _input_buffers_t;
-
-/* Data buffer, used in case the buffer can be shared between several data
- * packets */
-typedef struct _data_buffer_s
-{
- struct _data_buffer_s * p_next;
-
- /* number of data packets this buffer is referenced from - when it falls
- * down to 0, the buffer is freed */
- int i_refcount;
-
- struct /* for compatibility with _data_packet_t */
- {
- /* size of the current buffer (starting right thereafter) */
- unsigned int i_size;
- } _private;
-} _data_buffer_t;
-
-/* We overload the data_packet_t type to add private members */
-typedef struct _data_packet_s
-{
- struct _data_packet_s * p_next;
-
- DATA_PACKET
-
- union
- {
- struct _data_buffer_s * p_buffer; /* in case of shared buffers */
- /* size of the embedded buffer (starting right thereafter) */
- unsigned int i_size;
- } _private;
-} _data_packet_t;
-
-
-/*****************************************************************************
- * input_BuffersInit: initialize the cache structures, return a pointer to it
- *****************************************************************************/
-#define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ) \
-static void * input_BuffersInit( void ) \
-{ \
- _input_buffers_t * p_buffers = malloc( sizeof( _input_buffers_t ) ); \
- \
- if( p_buffers == NULL ) \
- { \
- return( NULL ); \
- } \
- \
- memset( p_buffers, 0, sizeof( _input_buffers_t ) ); \
- vlc_mutex_init( &p_buffers->lock ); \
- \
- return (void *)p_buffers; \
-}
-
-/*****************************************************************************
- * input_BuffersEnd: free all cached structures
- *****************************************************************************/
-#define BUFFERS_END_STAT_BUFFERS_LOOP( STRUCT ) \
- for( i = 0; i < NB_LIFO; i++ ) \
- { \
- if( FLAGS & BUFFERS_UNIQUE_SIZE ) \
- { \
- intf_StatMsg( \
- "input buffers stats: " #STRUCT "[%d]: %d packets", \
- i, p_buffers->STRUCT[i].i_depth ); \
- } \
- else \
- { \
- intf_StatMsg( \
- "input buffers stats: " #STRUCT "[%d]: %d bytes, %d packets", \
- i, p_buffers->STRUCT[i].i_average_size, \
- p_buffers->STRUCT[i].i_depth ); \
- } \
- }
-
-#define BUFFERS_END_STAT( FLAGS, NB_LIFO ) \
- BUFFERS_END_STAT_BUFFERS_LOOP( data );
-
-#define BUFFERS_END_STAT_SHARED( FLAGS, NB_LIFO ) \
- intf_StatMsg( "input buffers stats: data: %d packets", \
- p_buffers->data.i_depth ); \
- BUFFERS_END_STAT_BUFFERS_LOOP( buffers );
-
-
-#define BUFFERS_END_BUFFERS_LOOP \
- while( p_buf != NULL ) \
- { \
- p_next = p_buf->p_next; \
- p_buffers->i_allocated -= p_buf->_private.i_size; \
- free( p_buf ); \
- p_buf = p_next; \
- }
-
-#define BUFFERS_END_PACKETS_LOOP \
- while( p_packet != NULL ) \
- { \
- p_next = p_packet->p_next; \
- free( p_packet ); \
- p_packet = p_next; \
- }
-
-#define BUFFERS_END_LOOP( FLAGS, NB_LIFO ) \
- for( i = 0; i < NB_LIFO; i++ ) \
- { \
- _data_packet_t * p_next; \
- _data_packet_t * p_buf = p_buffers->data[i].p_stack; \
- BUFFERS_END_BUFFERS_LOOP; \
- } \
-
-#define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO ) \
- { \
- /* Free data packets */ \
- _data_packet_t * p_next; \
- _data_packet_t * p_packet = p_buffers->data.p_stack; \
- BUFFERS_END_PACKETS_LOOP; \
- } \
- \
- for( i = 0; i < NB_LIFO; i++ ) \
- { \
- _data_buffer_t * p_next; \
- _data_buffer_t * p_buf = p_buffers->buffers[i].p_stack; \
- BUFFERS_END_BUFFERS_LOOP; \
- } \
-
-#define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP ) \
-static void input_BuffersEnd( void * _p_buffers ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- \
- if( _p_buffers != NULL ) \
- { \
- int i; \
- \
- if( p_main->b_stats ) \
- { \
- int i; \
- intf_StatMsg( "input buffers stats: pes: %d packets", \
- p_buffers->pes.i_depth ); \
- STAT_LOOP( FLAGS, NB_LIFO ); \
- } \
- \
- { \
- /* Free PES */ \
- pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack; \
- BUFFERS_END_PACKETS_LOOP; \
- } \
- \
- LOOP( FLAGS, NB_LIFO ); \
- \
- if( p_buffers->i_allocated ) \
- { \
- intf_ErrMsg( "input buffers error: %d bytes have not been" \
- " freed, expect memory leak", \
- p_buffers->i_allocated ); \
- } \
- \
- vlc_mutex_destroy( &p_buffers->lock ); \
- free( _p_buffers ); \
- } \
-}
-
-#define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
- BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP );
-
-#define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO ) \
- BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED, \
- BUFFERS_END_LOOP_SHARED );
-
-/*****************************************************************************
- * input_NewPacket: return a pointer to a data packet of the appropriate size
- *****************************************************************************/
-#define BUFFERS_NEWPACKET_EXTRA_DECLARATION( FLAGS, NB_LIFO ) \
- _data_packet_t ** pp_data = &p_buf;
-
-#define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO ) \
- _data_packet_t * p_data; \
- _data_packet_t ** pp_data = &p_data;
-
-#define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO )
-
-#define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO ) \
- /* Find a data packet */ \
- if( p_buffers->data.p_stack != NULL ) \
- { \
- p_data = p_buffers->data.p_stack; \
- p_buffers->data.p_stack = p_data->p_next; \
- p_buffers->data.i_depth--; \
- } \
- else \
- { \
- p_data = malloc( sizeof( _data_packet_t ) ); \
- if( p_data == NULL ) \
- { \
- intf_ErrMsg( "Out of memory" ); \
- vlc_mutex_unlock( &p_buffers->lock ); \
- return( NULL ); \
- } \
- } \
- \
- if( i_size == 0 ) \
- { \
- /* Warning : in that case, the data packet is left partly \
- * uninitialized ; theorically only input_ShareBuffer may call \
- * this. */ \
- p_data->p_next = NULL; \
- p_data->b_discard_payload = 0; \
- return( (data_packet_t *)p_data ); \
- }
-
-#define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO, TYPE ) \
- (*pp_data)->p_demux_start = (byte_t *)*pp_data + sizeof( TYPE );
-
-#define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO, TYPE ) \
- (*pp_data)->_private.p_buffer = p_buf; \
- (*pp_data)->p_demux_start = (byte_t *)(*pp_data)->_private.p_buffer \
- + sizeof( TYPE ); \
- /* Initialize refcount */ \
- p_buf->i_refcount = 1;
-
-#define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION, \
- EXTRA, END ) \
-/* This one doesn't take p_buffers->lock. */ \
-static __inline__ data_packet_t * _input_NewPacket( void * _p_buffers, \
- size_t i_size ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- int i_select; \
- TYPE * p_buf; \
- EXTRA_DECLARATION( FLAGS, NB_LIFO ); \
- \
- /* Safety check */ \
- if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
- { \
- intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
- p_buffers->i_allocated ); \
- return NULL; \
- } \
- \
- EXTRA( FLAGS, NB_LIFO ); \
- \
- for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
- { \
- if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size \
- + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
- { \
- break; \
- } \
- } \
- \
- if( p_buffers->NAME[i_select].p_stack != NULL ) \
- { \
- /* Take the packet from the cache */ \
- p_buf = p_buffers->NAME[i_select].p_stack; \
- p_buffers->NAME[i_select].p_stack = p_buf->p_next; \
- p_buffers->NAME[i_select].i_depth--; \
- \
- /* Reallocate the packet if it is too small or too large */ \
- if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && \
- (p_buf->_private.i_size < i_size \
- || p_buf->_private.i_size > 3 * i_size) ) \
- { \
- p_buffers->i_allocated -= p_buf->_private.i_size; \
- p_buf = realloc( p_buf, sizeof( TYPE ) + i_size ); \
- if( p_buf == NULL ) \
- { \
- intf_ErrMsg( "Out of memory" ); \
- return NULL; \
- } \
- p_buf->_private.i_size = i_size; \
- p_buffers->i_allocated += i_size; \
- } \
- } \
- else \
- { \
- /* Allocate a new packet */ \
- p_buf = malloc( sizeof( TYPE ) + i_size ); \
- if( p_buf == NULL ) \
- { \
- intf_ErrMsg( "Out of memory" ); \
- return NULL; \
- } \
- p_buf->_private.i_size = i_size; \
- p_buffers->i_allocated += i_size; \
- } \
- \
- /* Initialize data */ \
- END( FLAGS, NB_LIFO, TYPE ); \
- (*pp_data)->p_next = NULL; \
- (*pp_data)->b_discard_payload = 0; \
- (*pp_data)->p_payload_start = (*pp_data)->p_demux_start; \
- (*pp_data)->p_payload_end = (*pp_data)->p_payload_start + i_size; \
- \
- return( (data_packet_t *)*pp_data ); \
-} \
- \
-static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- data_packet_t * p_data; \
- \
- /* Safety check */ \
- if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE ) \
- { \
- intf_ErrMsg( "Packet too big (%d)", i_size ); \
- return NULL; \
- } \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- p_data = _input_NewPacket( _p_buffers, i_size ); \
- vlc_mutex_unlock( &p_buffers->lock ); \
- return( p_data ); \
-}
-
-#define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \
- BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_packet_t, data, \
- BUFFERS_NEWPACKET_EXTRA_DECLARATION, BUFFERS_NEWPACKET_EXTRA, \
- BUFFERS_NEWPACKET_END )
-
-#define DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO ) \
- BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_buffer_t, buffers, \
- BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED, \
- BUFFERS_NEWPACKET_EXTRA_SHARED, BUFFERS_NEWPACKET_END_SHARED )
-
-/*****************************************************************************
- * input_DeletePacket: put a packet back into the cache
- *****************************************************************************/
-#define BUFFERS_DELETEPACKET_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
- _data_packet_t * p_buf = p_data;
-
-#define BUFFERS_DELETEPACKET_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )\
- _data_buffer_t * p_buf = (_data_buffer_t *)p_data->_private.p_buffer; \
- \
- /* Get rid of the data packet */ \
- if( p_buffers->data.i_depth < DATA_CACHE_SIZE ) \
- { \
- /* Cache not full : store the packet in it */ \
- p_data->p_next = p_buffers->data.p_stack; \
- p_buffers->data.p_stack = p_data; \
- p_buffers->data.i_depth++; \
- } \
- else \
- { \
- free( p_data ); \
- } \
- \
- /* Decrement refcount */ \
- p_buf->i_refcount--; \
- if( p_buf->i_refcount > 0 ) \
- { \
- return; \
- }
-
-#define BUFFERS_DELETEPACKETSTACK_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- _data_packet_t * p_first = (_data_packet_t *)_p_first; \
- _data_packet_t ** pp_last = (_data_packet_t **)_pp_last; \
- \
- /* Small hopeless optimization */ \
- if( (FLAGS & BUFFERS_UNIQUE_SIZE) \
- && p_buffers->data[0].i_depth < DATA_CACHE_SIZE ) \
- { \
- p_buffers->data[0].i_depth += i_nb; \
- *pp_last = p_buffers->data[0].p_stack; \
- p_buffers->data[0].p_stack = p_first; \
- } \
- else /* No semicolon after this or you will die */
-
-#define BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED( FLAGS, NB_LIFO, \
- DATA_CACHE_SIZE )
-
-#define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE, \
- NAME, EXTRA, EXTRA_STACK ) \
-/* This one doesn't take p_buffers->lock. */ \
-static __inline__ void _input_DeletePacket( void * _p_buffers, \
- data_packet_t * _p_data ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- _data_packet_t * p_data = (_data_packet_t *)_p_data; \
- int i_select; \
- \
- while( p_data != NULL ) \
- { \
- _data_packet_t * p_next = p_data->p_next; \
- \
- EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \
- \
- for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
- { \
- if( p_buf->_private.i_size <= \
- (2 * p_buffers->NAME[i_select].i_average_size \
- + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
- { \
- break; \
- } \
- } \
- \
- if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE ) \
- { \
- /* Cache not full : store the packet in it */ \
- p_buf->p_next = p_buffers->NAME[i_select].p_stack; \
- p_buffers->NAME[i_select].p_stack = p_buf; \
- p_buffers->NAME[i_select].i_depth++; \
- \
- if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \
- { \
- /* Update Bresenham mean (very approximative) */ \
- p_buffers->NAME[i_select].i_average_size = \
- ( p_buf->_private.i_size \
- + p_buffers->NAME[i_select].i_average_size \
- * (INPUT_BRESENHAM_NB - 1) ) \
- / INPUT_BRESENHAM_NB; \
- } \
- } \
- else \
- { \
- p_buffers->i_allocated -= p_buf->_private.i_size; \
- free( p_buf ); \
- } \
- \
- p_data = p_next; \
- } \
-} \
- \
-static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- _input_DeletePacket( _p_buffers, p_data ); \
- vlc_mutex_unlock( &p_buffers->lock ); \
-} \
- \
-/* Delete a chained list of i_nb data packets. -- needed by DeletePES */ \
-static __inline__ void _input_DeletePacketStack( void * _p_buffers, \
- data_packet_t * _p_first, \
- data_packet_t ** _pp_last, \
- unsigned int i_nb ) \
-{ \
- /* Do not add code before, EXTRA_STACK makes its own declarations. */ \
- EXTRA_STACK( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
- /* No semicolon - PLEASE */ \
- { \
- _input_DeletePacket( _p_buffers, _p_first ); \
- } \
-}
-
-#define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
- BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_packet_t, \
- data, BUFFERS_DELETEPACKET_EXTRA, \
- BUFFERS_DELETEPACKETSTACK_EXTRA )
-
-#define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, \
- DATA_CACHE_SIZE ) \
- BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_buffer_t, \
- buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED, \
- BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED )
-
-/*****************************************************************************
- * input_DeletePacketStack: optimize deleting of a stack of packets when
- * knowing much information
- *****************************************************************************/
-/* AFAIK, this isn't used by anyone - it is here for completion.
- * _input_DeletePacketStack is declared in DeletePacket because it is needed
- * by DeletePES. */
-#define DECLARE_BUFFERS_DELETEPACKETSTACK( FLAGS, NB_LIFO ) \
-static void input_DeletePacketStack( void * _p_buffers, \
- data_packet_t * p_first, \
- data_packet_t ** pp_last, \
- unsigned int i_nb ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- _input_DeletePacketStack( _p_buffers, p_first, pp_last, i_nb ); \
- vlc_mutex_unlock( &p_buffers->lock ); \
-}
-
-/*****************************************************************************
- * input_NewPES: return a pointer to a new PES packet
- *****************************************************************************/
-#define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ) \
-static pes_packet_t * input_NewPES( void * _p_buffers ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- pes_packet_t * p_pes; \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- \
- if( p_buffers->pes.p_stack != NULL ) \
- { \
- p_pes = p_buffers->pes.p_stack; \
- p_buffers->pes.p_stack = p_pes->p_next; \
- p_buffers->pes.i_depth--; \
- } \
- else \
- { \
- p_pes = malloc( sizeof( pes_packet_t ) ); \
- if( p_pes == NULL ) \
- { \
- intf_ErrMsg( "Out of memory" ); \
- vlc_mutex_unlock( &p_buffers->lock ); \
- return( NULL ); \
- } \
- } \
- \
- vlc_mutex_unlock( &p_buffers->lock ); \
- \
- /* Initialize data */ \
- p_pes->p_next = NULL; \
- p_pes->b_data_alignment = p_pes->b_discontinuity = \
- p_pes->i_pts = p_pes->i_dts = 0; \
- p_pes->i_pes_size = 0; \
- p_pes->p_first = p_pes->p_last = NULL; \
- p_pes->i_nb_data = 0; \
- \
- return( p_pes ); \
-}
-
-/*****************************************************************************
- * input_DeletePES: put a pes and all data packets back into the cache
- *****************************************************************************/
-#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \
-static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- \
- while( p_pes != NULL ) \
- { \
- pes_packet_t * p_next = p_pes->p_next; \
- \
- /* Delete all data packets */ \
- if( p_pes->p_first != NULL ) \
- { \
- _input_DeletePacketStack( _p_buffers, p_pes->p_first, \
- &p_pes->p_last->p_next, \
- p_pes->i_nb_data ); \
- } \
- \
- if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \
- { \
- /* Cache not full : store the packet in it */ \
- p_pes->p_next = p_buffers->pes.p_stack; \
- p_buffers->pes.p_stack = p_pes; \
- p_buffers->pes.i_depth++; \
- } \
- else \
- { \
- free( p_pes ); \
- } \
- \
- p_pes = p_next; \
- } \
- \
- vlc_mutex_unlock( &p_buffers->lock ); \
-}
-
-/*****************************************************************************
- * input_BuffersToIO: return an IO vector (only with BUFFERS_UNIQUE_SIZE)
- *****************************************************************************/
-#define DECLARE_BUFFERS_TOIO( FLAGS, BUFFER_SIZE ) \
-static data_packet_t * input_BuffersToIO( void * _p_buffers, \
- struct iovec * p_iovec, int i_nb )\
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- data_packet_t * p_data = NULL; \
- int i; \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- \
- for( i = i_nb - 1; i >= 0; i-- ) \
- { \
- data_packet_t * p_next = _input_NewPacket( _p_buffers, \
- BUFFER_SIZE /* UNIQUE_SIZE */ ); \
- if( p_next == NULL ) \
- { \
- _input_DeletePacket( _p_buffers, p_data ); \
- return( NULL ); \
- } \
- \
- p_iovec[i].iov_base = p_next->p_demux_start; \
- p_iovec[i].iov_len = BUFFER_SIZE; \
- p_next->p_next = p_data; \
- p_data = p_next; \
- } \
- \
- vlc_mutex_unlock( &p_buffers->lock ); \
- \
- return( p_data ); \
-}
-
-/*****************************************************************************
- * input_ShareBuffer: return a new data_packet to the same buffer
- *****************************************************************************/
-#define DECLARE_BUFFERS_SHAREBUFFER( FLAGS ) \
-static data_packet_t * input_ShareBuffer( void * _p_buffers, \
- data_packet_t * _p_shared_data ) \
-{ \
- _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
- _data_packet_t * p_shared_data = (_data_packet_t *)_p_shared_data; \
- _data_packet_t * p_data; \
- _data_buffer_t * p_buf = p_shared_data->_private.p_buffer; \
- \
- vlc_mutex_lock( &p_buffers->lock ); \
- \
- /* Get new data_packet_t, without a buffer through a special backdoor \
- * in _input_NewPacket. */ \
- p_data = (_data_packet_t *)_input_NewPacket( _p_buffers, 0 ); \
- \
- /* Finish initialization of p_data */ \
- p_data->_private.p_buffer = p_shared_data->_private.p_buffer; \
- p_data->p_demux_start = p_data->p_payload_start \
- = (byte_t *)p_shared_data->_private.p_buffer \
- + sizeof( _data_buffer_t ); \
- p_data->p_payload_end = p_data->p_demux_start + p_buf->_private.i_size; \
- \
- /* Update refcount */ \
- p_buf->i_refcount++; \
- \
- vlc_mutex_unlock( &p_buffers->lock ); \
- \
- return( (data_packet_t *)p_data ); \
-}
-
-
/*
* Optional MPEG demultiplexing
*/
# define input_DemuxPSI p_symbols->input_DemuxPSI
#endif
+
+/*
+ * Optional standard file descriptor operations (input_ext-plugins.h)
+ */
+
+/*****************************************************************************
+ * input_socket_t: private access plug-in data
+ *****************************************************************************/
+typedef struct input_socket_s
+{
+ /* Unbuffered file descriptor */
+ int i_handle;
+} input_socket_t;
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+#ifndef PLUGIN
+void input_FDClose( struct input_thread_s * );
+ssize_t input_FDRead( input_thread_t *, byte_t *, size_t );
+int input_FDNetworkRead( input_thread_t *, byte_t *, size_t );
+void input_FDSeek( struct input_thread_s *, off_t );
+#else
+# define input_FDClose p_symbols->input_FDClose
+# define input_FDRead p_symbols->input_FDRead
+# define input_FDNetworkRead p_symbols->input_FDNetworkRead
+# define input_FDSeek p_symbols->input_FDSeek
+#endif
+
* modules.h : Module management functions.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: modules.h,v 1.43 2002/02/24 22:06:50 sam Exp $
+ * $Id: modules.h,v 1.44 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#define MODULE_CAPABILITY_INTF 1 /* Interface */
"access",
#define MODULE_CAPABILITY_ACCESS 2 /* Input */
- "input",
-#define MODULE_CAPABILITY_INPUT 3 /* Input */
- "decaps",
-#define MODULE_CAPABILITY_DECAPS 4 /* Decaps */
+ "demux",
+#define MODULE_CAPABILITY_DEMUX 3 /* Input */
+ "network",
+#define MODULE_CAPABILITY_NETWORK 4 /* Network */
"decoder",
#define MODULE_CAPABILITY_DECODER 5 /* Audio or video decoder */
"motion",
void ( * pf_run ) ( struct intf_thread_s * );
} intf;
- /* Input plugin */
+ /* Access plugin */
struct
{
- int ( * pf_probe )( struct input_thread_s * );
- void ( * pf_init ) ( struct input_thread_s * );
- void ( * pf_open ) ( struct input_thread_s * );
+ int ( * pf_open ) ( struct input_thread_s * );
void ( * pf_close )( struct input_thread_s * );
- void ( * pf_end ) ( struct input_thread_s * );
- void ( * pf_init_bit_stream ) ( struct bit_stream_s *,
- struct decoder_fifo_s *,
- void (* pf_bitstream_callback)( struct bit_stream_s *,
- boolean_t ),
- void * );
-
- int ( * pf_read ) ( struct input_thread_s *,
- struct data_packet_s ** );
- void ( * pf_demux )( struct input_thread_s *,
- struct data_packet_s * );
-
- struct data_packet_s * ( * pf_new_packet ) ( void *, size_t );
- struct pes_packet_s * ( * pf_new_pes ) ( void * );
- void ( * pf_delete_packet ) ( void *, struct data_packet_s * );
- void ( * pf_delete_pes ) ( void *, struct pes_packet_s * );
-
+ ssize_t ( * pf_read ) ( struct input_thread_s *, byte_t *, size_t );
+ void ( * pf_seek ) ( struct input_thread_s *, off_t );
int ( * pf_set_program ) ( struct input_thread_s *,
- struct pgrm_descriptor_s * );
-
+ struct pgrm_descriptor_s * );
int ( * pf_set_area ) ( struct input_thread_s *,
struct input_area_s * );
+ } access;
+
+ /* Demux plugin */
+ struct
+ {
+ int ( * pf_init ) ( struct input_thread_s * );
+ void ( * pf_end ) ( struct input_thread_s * );
+ int ( * pf_demux )( struct input_thread_s * );
int ( * pf_rewind ) ( struct input_thread_s * );
- void ( * pf_seek ) ( struct input_thread_s *, off_t );
- } input;
+ } demux;
+
+ /* Network plugin */
+ struct
+ {
+ int ( * pf_open )( struct network_socket_s * );
+ } network;
/* Audio output plugin */
struct
/* XXX: The order here has to be the same as above for the #defines */
function_list_t intf;
function_list_t access;
- function_list_t input;
- function_list_t decaps;
+ function_list_t demux;
+ function_list_t network;
function_list_t dec;
function_list_t motion;
function_list_t idct;
/*****************************************************************************
- * input_es.h: thread structure of the ES plugin
+ * network.h: interface to communicate with network plug-ins
*****************************************************************************
- * Copyright (C) 2001 VideoLAN
- * $Id: input_es.h,v 1.3 2001/12/27 03:47:09 massiot Exp $
+ * Copyright (C) 2002 VideoLAN
+ * $Id: network.h,v 1.1 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-#define ES_PACKET_SIZE 2048
-#define ES_READ_ONCE 50
-#define MAX_PACKETS_IN_FIFO 50
+/*****************************************************************************
+ * network_socket_t: structure passed to a network plug-in to define the
+ * kind of socket we want
+ *****************************************************************************/
+typedef struct network_socket_s
+{
+ unsigned int i_type;
+
+ char * psz_bind_addr;
+ int i_bind_port;
+
+ char * psz_server_addr;
+ int i_server_port;
+
+ /* Return values */
+ int i_handle;
+ size_t i_mtu;
+} network_socket_t;
+
+/* Socket types */
+#define NETWORK_UDP 1
+#define NETWORK_TCP 2
+
* This header provides a portable threads implementation.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: threads.h,v 1.36 2002/02/27 03:47:56 sam Exp $
+ * $Id: threads.h,v 1.37 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) /* pthreads (like Linux & BSD) */
# include <pthread.h>
+# ifdef DEBUG
+/* Needed for pthread_cond_timedwait */
+# include <errno.h>
+# endif
/* This is not prototyped under Linux, though it exists. */
int pthread_mutexattr_setkind_np( pthread_mutexattr_t *attr, int kind );
timeout.tv_sec = now.tv_sec + THREAD_COND_TIMEOUT;
timeout.tv_nsec = now.tv_usec * 1000;
- if( (i_result = pthread_cond_timedwait( p_condvar, p_mutex, &timeout )) )
+ i_result = pthread_cond_timedwait( p_condvar, p_mutex, &timeout );
+
+ if( i_result == ETIMEDOUT )
{
intf_WarnMsg( 1, "thread %d warning: Possible deadlock detected in cond_wait at %s:%d (%s)",
pthread_self(), psz_file, i_line, strerror(i_result) );
+ continue;
}
- else
+
+ if( i_result )
{
- return i_result;
+ intf_ErrMsg( "thread %d error: cond_wait failed at %s:%d (%s)",
+ pthread_self(), psz_file, i_line, strerror(i_result) );
}
+ return( i_result );
}
#endif
* includes all common video types and constants.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: video.h,v 1.43 2002/02/19 00:50:19 sam Exp $
+ * $Id: video.h,v 1.44 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
boolean_t b_repeat_first_field; /* RFF bit */
boolean_t b_top_field_first; /* which field is first */
- /* Macroblock counter - the decoder uses it to verify if it has
- * decoded all the macroblocks of the picture */
- int i_deccount;
- vlc_mutex_t lock_deccount;
-
/* Private data - the video output plugin might want to put stuff here to
* keep track of the picture */
struct picture_sys_s *p_sys;
--- /dev/null
+.dep
+*.lo
+*.o.*
+*.lo.*
--- /dev/null
+file_SOURCES = file.c
+udp_SOURCES = udp.c
+http_SOURCES = http.c
--- /dev/null
+/*****************************************************************************
+ * file.c: file input (file: access plug-in)
+ *****************************************************************************
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: file.c,v 1.1 2002/03/01 00:33:18 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <videolan/vlc.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#elif defined( _MSC_VER ) && defined( _WIN32 )
+# include <io.h>
+#endif
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * );
+static int FileOpen ( struct input_thread_s * );
+static int FileSetProgram ( struct input_thread_s * , pgrm_descriptor_t * );
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+MODULE_CONFIG_STOP
+
+MODULE_INIT_START
+ SET_DESCRIPTION( "Standard filesystem file reading" )
+ ADD_CAPABILITY( ACCESS, 50 )
+ ADD_SHORTCUT( "file" )
+ ADD_SHORTCUT( "stream" )
+MODULE_INIT_STOP
+
+MODULE_ACTIVATE_START
+ input_getfunctions( &p_module->p_functions->access );
+MODULE_ACTIVATE_STOP
+
+MODULE_DEACTIVATE_START
+MODULE_DEACTIVATE_STOP
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.access
+ input.pf_open = FileOpen;
+ input.pf_read = input_FDRead;
+ input.pf_close = input_FDClose;
+ input.pf_set_program = FileSetProgram;
+ input.pf_set_area = NULL;
+ input.pf_seek = input_FDSeek;
+#undef input
+}
+
+/*****************************************************************************
+ * FileOpen: open the file
+ *****************************************************************************/
+static int FileOpen( input_thread_t * p_input )
+{
+ char * psz_name = p_input->psz_name;
+ int i_stat;
+ struct stat stat_info;
+ input_socket_t * p_access_data;
+ boolean_t b_stdin;
+
+ p_input->i_mtu = 0;
+
+ b_stdin = ( strlen( p_input->psz_name ) == 1 )
+ && *p_input->psz_name == '-';
+
+ if( !b_stdin && (i_stat = stat( psz_name, &stat_info )) == (-1) )
+ {
+ intf_ErrMsg( "input error: cannot stat() file `%s' (%s)",
+ psz_name, strerror(errno));
+ return( -1 );
+ }
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+
+ if( p_input->psz_access != NULL
+ && !strncmp( p_input->psz_access, "stream", 7 ) )
+ {
+ /* stream:%s */
+ p_input->stream.b_pace_control = 0;
+ p_input->stream.b_seekable = 0;
+ p_input->stream.p_selected_area->i_size = 0;
+ }
+ else
+ {
+ /* file:%s or %s */
+ p_input->stream.b_pace_control = 1;
+
+ if( b_stdin )
+ {
+ p_input->stream.b_seekable = 0;
+ p_input->stream.p_selected_area->i_size = 0;
+ }
+ else if( S_ISREG(stat_info.st_mode) || S_ISCHR(stat_info.st_mode)
+ || S_ISBLK(stat_info.st_mode) )
+ {
+ p_input->stream.b_seekable = 1;
+ p_input->stream.p_selected_area->i_size = stat_info.st_size;
+ }
+ else if( S_ISFIFO(stat_info.st_mode)
+#if !defined( SYS_BEOS ) && !defined( WIN32 )
+ || S_ISSOCK(stat_info.st_mode)
+#endif
+ )
+ {
+ p_input->stream.b_seekable = 0;
+ p_input->stream.p_selected_area->i_size = 0;
+ }
+ else
+ {
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ intf_ErrMsg( "input error: unknown file type for `%s'",
+ psz_name );
+ return( -1 );
+ }
+ }
+
+ p_input->stream.p_selected_area->i_tell = 0;
+ p_input->stream.i_method = INPUT_METHOD_FILE;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ intf_WarnMsg( 2, "input: opening file `%s'", psz_name );
+ p_access_data = malloc( sizeof(input_socket_t) );
+ p_input->p_access_data = (void *)p_access_data;
+ if( p_access_data == NULL )
+ {
+ intf_ErrMsg( "input error: Out of memory" );
+ return( -1 );
+ }
+
+ if( b_stdin )
+ {
+ p_access_data->i_handle = 0;
+ }
+ else if( (p_access_data->i_handle = open( psz_name,
+ /*O_NONBLOCK | O_LARGEFILE*/ 0 )) == (-1) )
+ {
+ intf_ErrMsg( "input error: cannot open file %s (%s)", psz_name,
+ strerror(errno) );
+ free( p_access_data );
+ return( -1 );
+ }
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * FileSetProgram: Do nothing
+ *****************************************************************************/
+static int FileSetProgram( input_thread_t * p_input,
+ pgrm_descriptor_t * p_program )
+{
+ return( 0 );
+}
+
--- /dev/null
+/*****************************************************************************
+ * http.c: HTTP access plug-in
+ *****************************************************************************
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: http.c,v 1.1 2002/03/01 00:33:18 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <videolan/vlc.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#elif defined( _MSC_VER ) && defined( _WIN32 )
+# include <io.h>
+#endif
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
+#include "network.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * );
+static int HTTPOpen ( struct input_thread_s * );
+static int HTTPSetProgram ( struct input_thread_s * , pgrm_descriptor_t * );
+static void HTTPSeek ( struct input_thread_s *, off_t );
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+MODULE_CONFIG_STOP
+
+MODULE_INIT_START
+ SET_DESCRIPTION( "HTTP access plug-in" )
+ ADD_CAPABILITY( ACCESS, 0 )
+ ADD_SHORTCUT( "http" )
+ ADD_SHORTCUT( "http4" )
+ ADD_SHORTCUT( "http6" )
+MODULE_INIT_STOP
+
+MODULE_ACTIVATE_START
+ input_getfunctions( &p_module->p_functions->access );
+MODULE_ACTIVATE_STOP
+
+MODULE_DEACTIVATE_START
+MODULE_DEACTIVATE_STOP
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.access
+ input.pf_open = HTTPOpen;
+ input.pf_read = input_FDNetworkRead;
+ input.pf_close = input_FDClose;
+ input.pf_set_program = HTTPSetProgram;
+ input.pf_set_area = NULL;
+ input.pf_seek = HTTPSeek;
+#undef input
+}
+
+/*****************************************************************************
+ * _input_socket_t: private access plug-in data, modified to add private
+ * fields
+ *****************************************************************************/
+typedef struct _input_socket_s
+{
+ input_socket_t _socket;
+
+ char * psz_network;
+ network_socket_t socket_desc;
+ char psz_buffer[256];
+} _input_socket_t;
+
+/*****************************************************************************
+ * HTTPConnect: connect to the server and seek to i_tell
+ *****************************************************************************/
+static int HTTPConnect( input_thread_t * p_input, off_t i_tell )
+{
+ _input_socket_t * p_access_data = p_input->p_access_data;
+ struct module_s * p_network;
+ char psz_buffer[256];
+ byte_t * psz_parser;
+
+ /* Find an appropriate network module */
+ p_network = module_Need( MODULE_CAPABILITY_NETWORK,
+ p_access_data->psz_network,
+ &p_access_data->socket_desc );
+ if( p_network == NULL )
+ {
+ free( p_access_data );
+ return( -1 );
+ }
+ module_Unneed( p_network );
+
+ p_access_data->_socket.i_handle = p_access_data->socket_desc.i_handle;
+
+# define HTTP_USERAGENT "User-Agent: " COPYRIGHT_MESSAGE "\r\n"
+# define HTTP_END "\r\n"
+
+ snprintf( psz_buffer, sizeof(psz_buffer),
+ "%s"
+ "Range: bytes=%lld-\r\n"
+ HTTP_USERAGENT HTTP_END,
+ p_access_data->psz_buffer, i_tell );
+ psz_buffer[sizeof(psz_buffer) - 1] = '\0';
+
+ /* Send GET ... */
+ if( write( p_access_data->_socket.i_handle, psz_buffer,
+ strlen( psz_buffer ) ) == (-1) )
+ {
+ intf_ErrMsg( "http error: cannot send request (%s)", strerror(errno) );
+ input_FDClose( p_input );
+ return( -1 );
+ }
+
+ /* Prepare the input thread for reading. */
+ p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
+ /* FIXME: we shouldn't have to do that ! */
+ p_input->pf_read = input_FDRead;
+
+ while( !input_FillBuffer( p_input ) )
+ {
+ if( p_input->b_die || p_input->b_error )
+ {
+ input_FDClose( p_input );
+ return( -1 );
+ }
+ }
+
+ /* Parse HTTP header. */
+#define MAX_LINE 1024
+ for( ; ; )
+ {
+ if( input_Peek( p_input, &psz_parser, MAX_LINE ) <= 0 )
+ {
+ intf_ErrMsg( "http error: not enough data" );
+ input_FDClose( p_input );
+ return( -1 );
+ }
+
+ if( psz_parser[0] == '\r' && psz_parser[1] == '\n' )
+ {
+ /* End of header. */
+ p_input->p_current_data += 2;
+ break;
+ }
+
+ if( !strncmp( psz_parser, "Content-Length: ",
+ strlen("Content-Length: ") ) )
+ {
+ psz_parser += strlen("Content-Length: ");
+ /* FIXME : this won't work for 64-bit lengths */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.p_selected_area->i_size = atoi( psz_parser )
+ + i_tell;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+
+ while( *psz_parser != '\r' && psz_parser < p_input->p_last_data )
+ {
+ psz_parser++;
+ }
+ p_input->p_current_data = psz_parser + 2;
+ }
+
+ if( p_input->stream.p_selected_area->i_size )
+ {
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.p_selected_area->i_tell = i_tell
+ + (p_input->p_last_data - p_input->p_current_data);
+ p_input->stream.b_seekable = 1;
+ p_input->stream.b_changed = 1;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * HTTPOpen: parse URL and open the remote file at the beginning
+ *****************************************************************************/
+static int HTTPOpen( input_thread_t * p_input )
+{
+ _input_socket_t * p_access_data;
+ char * psz_parser = p_input->psz_name;
+ char * psz_server_addr = NULL;
+ char * psz_server_port = NULL;
+ char * psz_path = NULL;
+ char * psz_proxy;
+ int i_server_port = 0;
+
+ p_access_data = p_input->p_access_data = malloc( sizeof(_input_socket_t) );
+ if( p_access_data == NULL )
+ {
+ intf_ErrMsg( "http error: Out of memory" );
+ return( -1 );
+ }
+
+ p_access_data->psz_network = NULL;
+ if( p_input->psz_access != NULL )
+ {
+ /* Find out which shortcut was used */
+ if( !strncmp( p_input->psz_access, "http6", 5 ) )
+ {
+ p_access_data->psz_network = "ipv6";
+ }
+ else if( !strncmp( p_input->psz_access, "http4", 5 ) )
+ {
+ p_access_data->psz_network = "ipv4";
+ }
+ }
+
+ /* Parse psz_name syntax :
+ * //<hostname>[:<port>][/<path>] */
+ while( *psz_parser == '/' )
+ {
+ psz_parser++;
+ }
+ psz_server_addr = psz_parser;
+
+ while( *psz_parser && *psz_parser != ':' && *psz_parser != '/' )
+ {
+ psz_parser++;
+ }
+
+ if ( *psz_parser == ':' )
+ {
+ *psz_parser = '\0';
+ psz_parser++;
+ psz_server_port = psz_parser;
+
+ while( *psz_parser && *psz_parser != '/' )
+ {
+ psz_parser++;
+ }
+ }
+
+ if( *psz_parser == '/' )
+ {
+ *psz_parser = '\0';
+ psz_parser++;
+ psz_path = psz_parser;
+ }
+
+ /* Convert port format */
+ if( psz_server_port != NULL )
+ {
+ i_server_port = strtol( psz_server_port, &psz_parser, 10 );
+ if( *psz_parser )
+ {
+ intf_ErrMsg( "input error: cannot parse server port near %s",
+ psz_parser );
+ free( p_input->p_access_data );
+ return( -1 );
+ }
+ }
+
+ if( i_server_port == 0 )
+ {
+ i_server_port = 80;
+ }
+
+ if( psz_server_addr == NULL )
+ {
+ intf_ErrMsg( "input error: no server given" );
+ free( p_input->p_access_data );
+ return( -1 );
+ }
+
+ /* Check proxy */
+ if( (psz_proxy = getenv( "http_proxy" )) != NULL )
+ {
+ /* http://myproxy.mydomain:myport/ */
+ int i_proxy_port = 0;
+
+ /* Skip the protocol name */
+ while( *psz_proxy && *psz_proxy != ':' )
+ {
+ psz_proxy++;
+ }
+
+ /* Skip the "://" part */
+ while( *psz_proxy && (*psz_proxy == ':' || *psz_proxy == '/') )
+ {
+ psz_proxy++;
+ }
+
+ /* Found a proxy name */
+ if( *psz_proxy )
+ {
+ char *psz_port = psz_proxy;
+
+ /* Skip the hostname part */
+ while( *psz_port && *psz_port != ':' && *psz_port != '/' )
+ {
+ psz_port++;
+ }
+
+ /* Found a port name */
+ if( *psz_port )
+ {
+ char * psz_junk;
+
+ /* Replace ':' with '\0' */
+ *psz_port = '\0';
+ psz_port++;
+
+ psz_junk = psz_port;
+ while( *psz_junk && *psz_junk != '/' )
+ {
+ psz_junk++;
+ }
+
+ if( *psz_junk )
+ {
+ *psz_junk = '\0';
+ }
+
+ if( *psz_port != '\0' )
+ {
+ i_proxy_port = atoi( psz_port );
+ }
+ }
+ }
+ else
+ {
+ intf_ErrMsg( "input error: http_proxy environment variable is invalid !" );
+ free( p_input->p_access_data );
+ return( -1 );
+ }
+
+ p_access_data->socket_desc.i_type = NETWORK_TCP;
+ p_access_data->socket_desc.psz_server_addr = psz_proxy;
+ p_access_data->socket_desc.i_server_port = i_proxy_port;
+
+ snprintf( p_access_data->psz_buffer, sizeof(p_access_data->psz_buffer),
+ "GET http://%s:%d/%s HTTP/1.1\r\n",
+ psz_server_addr, i_server_port, psz_path );
+ }
+ else
+ {
+ /* No proxy, direct connection. */
+ p_access_data->socket_desc.i_type = NETWORK_TCP;
+ p_access_data->socket_desc.psz_server_addr = psz_server_addr;
+ p_access_data->socket_desc.i_server_port = i_server_port;
+
+ snprintf( p_access_data->psz_buffer, sizeof(p_access_data->psz_buffer),
+ "GET /%s HTTP/1.1\r\nHost: %s\r\n",
+ psz_path, psz_server_addr );
+ }
+ p_access_data->psz_buffer[sizeof(p_access_data->psz_buffer) - 1] = '\0';
+
+ intf_WarnMsg( 2, "input: opening server=%s port=%d path=%s",
+ psz_server_addr, i_server_port, psz_path );
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.b_pace_control = 1;
+ p_input->stream.b_seekable = 0;
+ p_input->stream.p_selected_area->i_tell = 0;
+ p_input->stream.p_selected_area->i_size = 0;
+ p_input->stream.i_method = INPUT_METHOD_NETWORK;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ p_input->i_mtu = 0;
+
+ return( HTTPConnect( p_input, 0 ) );
+}
+
+/*****************************************************************************
+ * HTTPSetProgram: do nothing
+ *****************************************************************************/
+static int HTTPSetProgram( input_thread_t * p_input,
+ pgrm_descriptor_t * p_program )
+{
+ return( 0 );
+}
+
+/*****************************************************************************
+ * HTTPSeek: close and re-open a connection at the right place
+ *****************************************************************************/
+static void HTTPSeek( input_thread_t * p_input, off_t i_pos )
+{
+ _input_socket_t * p_access_data = p_input->p_access_data;
+ close( p_access_data->_socket.i_handle );
+ intf_WarnMsg( 2, "http: seeking to position %lld", i_pos );
+ HTTPConnect( p_input, i_pos );
+}
+
--- /dev/null
+/*****************************************************************************
+ * udp.c: raw UDP access plug-in
+ *****************************************************************************
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: udp.c,v 1.1 2002/03/01 00:33:18 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <videolan/vlc.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#elif defined( _MSC_VER ) && defined( _WIN32 )
+# include <io.h>
+#endif
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
+#include "network.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * );
+static int UDPOpen ( struct input_thread_s * );
+static int UDPSetProgram ( struct input_thread_s * , pgrm_descriptor_t * );
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+MODULE_CONFIG_STOP
+
+MODULE_INIT_START
+ SET_DESCRIPTION( "Raw UDP access plug-in" )
+ ADD_CAPABILITY( ACCESS, 0 )
+ ADD_SHORTCUT( "udp" )
+ ADD_SHORTCUT( "udpstream" )
+ ADD_SHORTCUT( "udp4" )
+ ADD_SHORTCUT( "udp6" )
+MODULE_INIT_STOP
+
+MODULE_ACTIVATE_START
+ input_getfunctions( &p_module->p_functions->access );
+MODULE_ACTIVATE_STOP
+
+MODULE_DEACTIVATE_START
+MODULE_DEACTIVATE_STOP
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.access
+ input.pf_open = UDPOpen;
+ input.pf_read = input_FDNetworkRead;
+ input.pf_close = input_FDClose;
+ input.pf_set_program = UDPSetProgram;
+ input.pf_set_area = NULL;
+ input.pf_seek = NULL;
+#undef input
+}
+
+/*****************************************************************************
+ * UDPOpen: open the socket
+ *****************************************************************************/
+static int UDPOpen( input_thread_t * p_input )
+{
+ input_socket_t * p_access_data;
+ struct module_s * p_network;
+ char * psz_network = NULL;
+ char * psz_parser = p_input->psz_name;
+ char * psz_server_addr = NULL;
+ char * psz_server_port = NULL;
+ char * psz_bind_addr = NULL;
+ char * psz_bind_port = NULL;
+ int i_bind_port = 0, i_server_port = 0;
+ network_socket_t socket_desc;
+
+ if( p_input->psz_access != NULL )
+ {
+ /* Find out which shortcut was used */
+ if( !strncmp( p_input->psz_access, "udp6", 5 ) )
+ {
+ psz_network = "ipv6";
+ }
+ else if( !strncmp( p_input->psz_access, "udp4", 5 ) )
+ {
+ psz_network = "ipv4";
+ }
+ }
+
+ /* Parse psz_name syntax :
+ * [serveraddr[:serverport]][@[bindaddr]:[bindport]] */
+
+ if( *psz_parser && *psz_parser != '@' )
+ {
+ /* Found server */
+ psz_server_addr = psz_parser;
+
+ while( *psz_parser && *psz_parser != ':' && *psz_parser != '@' )
+ {
+ psz_parser++;
+ }
+
+ if( *psz_parser == ':' )
+ {
+ /* Found server port */
+ *psz_parser = '\0'; /* Terminate server name */
+ psz_parser++;
+ psz_server_port = psz_parser;
+
+ while( *psz_parser && *psz_parser != '@' )
+ {
+ psz_parser++;
+ }
+ }
+ }
+
+ if( *psz_parser == '@' )
+ {
+ /* Found bind address or bind port */
+ *psz_parser = '\0'; /* Terminate server port or name if necessary */ psz_parser++;
+
+ if( *psz_parser && *psz_parser != ':' )
+ {
+ /* Found bind address */
+ psz_bind_addr = psz_parser;
+
+ while( *psz_parser && *psz_parser != ':' )
+ {
+ psz_parser++;
+ }
+ }
+
+ if( *psz_parser == ':' )
+ {
+ /* Found bind port */
+ *psz_parser = '\0'; /* Terminate bind address if necessary */
+ psz_parser++;
+
+ psz_bind_port = psz_parser;
+ }
+ }
+
+ /* Convert ports format */
+ if( psz_server_port != NULL )
+ {
+ i_server_port = strtol( psz_server_port, &psz_parser, 10 );
+ if( *psz_parser )
+ {
+ intf_ErrMsg( "input error: cannot parse server port near %s",
+ psz_parser );
+ return( -1 );
+ }
+ }
+
+ if( psz_bind_port != NULL )
+ {
+ i_bind_port = strtol( psz_bind_port, &psz_parser, 10 );
+ if( *psz_parser )
+ {
+ intf_ErrMsg( "input error: cannot parse bind port near %s",
+ psz_parser );
+ return( -1 );
+ }
+ }
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.b_pace_control = 0;
+ p_input->stream.b_seekable = 0;
+ p_input->stream.p_selected_area->i_tell = 0;
+ p_input->stream.i_method = INPUT_METHOD_NETWORK;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ intf_WarnMsg( 2, "input: opening server=%s:%d local=%s:%d",
+ psz_server_addr, i_server_port, psz_bind_addr, i_bind_port );
+
+ /* Prepare the network_socket_t structure */
+ socket_desc.i_type = NETWORK_UDP;
+ socket_desc.psz_bind_addr = psz_bind_addr;
+ socket_desc.i_bind_port = i_bind_port;
+ socket_desc.psz_server_addr = psz_server_addr;
+ socket_desc.i_server_port = i_server_port;
+
+ /* Find an appropriate network module */
+ p_network = module_Need( MODULE_CAPABILITY_NETWORK, psz_network,
+ &socket_desc );
+ if( p_network == NULL )
+ {
+ return( -1 );
+ }
+ module_Unneed( p_network );
+
+
+ p_access_data = p_input->p_access_data = malloc( sizeof(input_socket_t) );
+ if( p_access_data == NULL )
+ {
+ intf_ErrMsg( "input error: Out of memory" );
+ return( -1 );
+ }
+
+ p_access_data->i_handle = socket_desc.i_handle;
+ p_input->i_mtu = socket_desc.i_mtu;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * UDPSetProgram: Do nothing
+ *****************************************************************************/
+static int UDPSetProgram( input_thread_t * p_input,
+ pgrm_descriptor_t * p_program )
+{
+ return( 0 );
+}
+
* dummy.c : dummy plugin for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
- * $Id: dummy.c,v 1.16 2002/02/27 03:47:56 sam Exp $
+ * $Id: dummy.c,v 1.17 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
/*****************************************************************************
* Capabilities defined in the other files.
*****************************************************************************/
-void _M( input_getfunctions ) ( function_list_t * p_function_list );
+void _M( access_getfunctions ) ( function_list_t * p_function_list );
+void _M( demux_getfunctions ) ( function_list_t * p_function_list );
void _M( aout_getfunctions ) ( function_list_t * p_function_list );
void _M( vout_getfunctions ) ( function_list_t * p_function_list );
void _M( intf_getfunctions ) ( function_list_t * p_function_list );
SET_DESCRIPTION( "dummy functions module" )
/* Capability score set to 0 because we don't want to be spawned
* unless explicitly requested to */
- ADD_CAPABILITY( AOUT, 1 )
- ADD_CAPABILITY( VOUT, 1 )
- ADD_CAPABILITY( INTF, 1 )
- /* This one is ok. */
- ADD_CAPABILITY( INPUT, 100 )
+ ADD_CAPABILITY( AOUT, 0 )
+ ADD_CAPABILITY( VOUT, 0 )
+ ADD_CAPABILITY( INTF, 0 )
+ ADD_CAPABILITY( ACCESS, 0 )
+ ADD_CAPABILITY( DEMUX, 0 )
ADD_SHORTCUT( "dummy" )
+ ADD_SHORTCUT( "vlc" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
- _M( input_getfunctions )( &p_module->p_functions->input );
+ _M( access_getfunctions )( &p_module->p_functions->access );
+ _M( demux_getfunctions )( &p_module->p_functions->demux );
_M( aout_getfunctions )( &p_module->p_functions->aout );
_M( vout_getfunctions )( &p_module->p_functions->vout );
_M( intf_getfunctions )( &p_module->p_functions->intf );
/*****************************************************************************
* input_dummy.c: dummy input plugin, to manage "vlc:***" special options
*****************************************************************************
- * Copyright (C) 2001 VideoLAN
- * $Id: input_dummy.c,v 1.15 2002/02/15 13:32:53 sam Exp $
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: input_dummy.c,v 1.16 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#include <videolan/vlc.h>
-#ifdef STRNCASECMP_IN_STRINGS_H
-# include <strings.h>
-#endif
-
#include "interface.h"
#include "intf_playlist.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int DummyProbe ( struct input_thread_s * );
-static void DummyInit ( struct input_thread_s * );
-static void DummyOpen ( struct input_thread_s * );
+static int DummyInit ( struct input_thread_s * );
+static int DummyOpen ( struct input_thread_s * );
static void DummyClose ( struct input_thread_s * );
static void DummyEnd ( struct input_thread_s * );
-static int DummyRead ( struct input_thread_s *, data_packet_t ** );
+static int DummyDemux ( struct input_thread_s * );
/*****************************************************************************
- * dummy_data_t: private input data
+ * access_sys_t: private input data
*****************************************************************************/
-typedef struct dummy_data_s
+struct demux_sys_s
{
/* The real command */
int i_command;
/* Used for the pause command */
mtime_t expiration;
-
-} dummy_data_t;
+};
#define COMMAND_NOP 0
#define COMMAND_QUIT 1
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list )
+void _M( access_getfunctions )( function_list_t * p_function_list )
{
-#define input p_function_list->functions.input
- input.pf_probe = DummyProbe;
- input.pf_init = DummyInit;
+#define input p_function_list->functions.access
input.pf_open = DummyOpen;
+ input.pf_read = NULL;
input.pf_close = DummyClose;
- input.pf_end = DummyEnd;
+ input.pf_set_program = NULL;
input.pf_set_area = NULL;
- input.pf_read = DummyRead;
- input.pf_demux = NULL;
- input.pf_new_packet = NULL;
- input.pf_new_pes = NULL;
- input.pf_delete_packet = NULL;
- input.pf_delete_pes = NULL;
- input.pf_rewind = NULL;
input.pf_seek = NULL;
#undef input
}
-/*****************************************************************************
- * DummyProbe: verifies that the input is a vlc command
- *****************************************************************************/
-static int DummyProbe( input_thread_t *p_input )
+void _M( demux_getfunctions )( function_list_t * p_function_list )
{
- char *psz_name = p_input->p_source;
-
- if( ( strlen(psz_name) > 4 ) && !strncasecmp( psz_name, "vlc:", 4 ) )
- {
- /* If the user specified "vlc:" then it's probably a special command */
- return 0;
- }
-
- return -1;
+#define input p_function_list->functions.demux
+ input.pf_init = DummyInit;
+ input.pf_end = DummyEnd;
+ input.pf_demux = DummyDemux;
+ input.pf_rewind = NULL;
+#undef input
}
/*****************************************************************************
* DummyOpen: open the target, ie. do nothing
*****************************************************************************/
-static void DummyOpen( input_thread_t * p_input )
+static int DummyOpen( input_thread_t * p_input )
{
p_input->stream.i_method = INPUT_METHOD_NONE;
+ /* Force dummy demux plug-in */
+ p_input->psz_demux = "vlc";
+ return( 0 );
}
/*****************************************************************************
*****************************************************************************/
static void DummyClose( input_thread_t * p_input )
{
- ;
}
/*****************************************************************************
- * DummyOpen: initialize the target, ie. parse the command
+ * DummyInit: initialize the target, ie. parse the command
*****************************************************************************/
-static void DummyInit( struct input_thread_s *p_input )
+static int DummyInit( struct input_thread_s *p_input )
{
- dummy_data_t* p_method;
- char *psz_name = p_input->p_source;
- int i_len = strlen( psz_name );
+ char * psz_name = p_input->psz_name;
+ int i_len = strlen( psz_name );
+ struct demux_sys_s * p_method;
int i_arg;
p_input->stream.b_seekable = 0;
- if( ( i_len <= 4 ) || strncasecmp( psz_name, "vlc:", 4 ) )
- {
- /* If the command doesn't start with "vlc:" then it's not for us */
- p_input->b_error = 1;
- return;
- }
-
- /* We don't need the "vlc:" stuff any more */
- psz_name += 4;
- i_len -= 4;
-
- p_method = malloc( sizeof( dummy_data_t ) );
+ p_method = malloc( sizeof( struct demux_sys_s ) );
if( p_method == NULL )
{
intf_ErrMsg( "input: out of memory" );
- p_input->b_error = 1;
- return;
+ return( -1 );
}
- p_input->p_plugin_data = (void *)p_method;
+ p_input->p_demux_data = p_method;
p_input->stream.p_demux_data = NULL;
/* Check for a "vlc:nop" command */
{
intf_WarnMsg( 2, "input: command `nop'" );
p_method->i_command = COMMAND_NOP;
- return;
+ return( 0 );
}
/* Check for a "vlc:quit" command */
{
intf_WarnMsg( 2, "input: command `quit'" );
p_method->i_command = COMMAND_QUIT;
- return;
+ return( 0 );
}
/* Check for a "vlc:loop" command */
{
intf_WarnMsg( 2, "input: command `loop'" );
p_method->i_command = COMMAND_LOOP;
- return;
+ return( 0 );
}
/* Check for a "vlc:pause:***" command */
intf_WarnMsg( 2, "input: command `pause %i'", i_arg );
p_method->i_command = COMMAND_PAUSE;
p_method->expiration = mdate() + (mtime_t)i_arg * (mtime_t)1000000;
- return;
+ return( 0 );
}
intf_ErrMsg( "input error: unknown command `%s'", psz_name );
- free( p_input->p_plugin_data );
+ free( p_input->p_demux_data );
p_input->b_error = 1;
- return;
+ return( -1 );
}
/*****************************************************************************
*****************************************************************************/
static void DummyEnd( struct input_thread_s *p_input )
{
- free( p_input->p_plugin_data );
+ free( p_input->p_demux_data );
}
/*****************************************************************************
- * DummyRead: do what the command says
+ * DummyDemux: do what the command says
*****************************************************************************/
-static int DummyRead( struct input_thread_s *p_input, data_packet_t **pp_data )
+static int DummyDemux( struct input_thread_s *p_input )
{
- dummy_data_t* p_method = (dummy_data_t *)p_input->p_plugin_data;
+ struct demux_sys_s * p_method = p_input->p_demux_data;
switch( p_method->i_command )
{
case COMMAND_QUIT:
- p_main->p_intf->b_die = 1;
- p_input->b_eof = 1;
+ p_input->b_die = 1;
break;
case COMMAND_LOOP:
break;
}
- *pp_data = NULL;
-
- return 0;
+ return 1;
}
* dvd.c : DVD input module for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: dvd.c,v 1.20 2002/02/26 01:17:13 stef Exp $
+ * $Id: dvd.c,v 1.21 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
/*****************************************************************************
* Capabilities defined in the other files.
*****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list );
+void _M( access_getfunctions )( function_list_t * p_function_list );
+void _M( demux_getfunctions )( function_list_t * p_function_list );
/*****************************************************************************
* Local prototypes.
MODULE_INIT_START
#ifdef GOD_DAMN_DMCA
SET_DESCRIPTION( "DVD input module, uses libdvdcss if present" )
- ADD_CAPABILITY( INPUT, 90 )
#else
SET_DESCRIPTION( "DVD input module, linked with libdvdcss" )
- ADD_CAPABILITY( INPUT, 100 )
#endif
+ ADD_CAPABILITY( ACCESS, 0 )
+ ADD_CAPABILITY( DEMUX, 0 )
ADD_SHORTCUT( "dvd" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
- _M( input_getfunctions )( &p_module->p_functions->input );
+ _M( access_getfunctions )( &p_module->p_functions->access );
+ _M( demux_getfunctions )( &p_module->p_functions->demux );
#ifdef GOD_DAMN_DMCA
ProbeLibDVDCSS();
#endif
* gtk_display.c: Gtk+ tools for main interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: gtk_display.c,v 1.15 2002/02/24 21:36:20 jobi Exp $
+ * $Id: gtk_display.c,v 1.16 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stéphane Borel <stef@via.ecp.fr>
p_intf->p_sys->p_window ),
"label_status" );
gtk_label_set_text( GTK_LABEL( p_label ),
- p_input_bank->pp_input[0]->p_source );
+ p_input_bank->pp_input[0]->psz_source );
break;
case INPUT_METHOD_DISC:
//intf_WarnMsg( 2, "intf info: disc method" );
p_intf->p_sys->p_window ),
"network_address_label" );
gtk_label_set_text( GTK_LABEL( p_label ),
- p_input_bank->pp_input[0]->p_source );
+ p_input_bank->pp_input[0]->psz_source );
p_channel = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "network_channel_box" ) );
if( config_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR ) )
p_intf->p_sys->p_window ),
"label_status" );
gtk_label_set_text( GTK_LABEL( p_label ),
- p_input_bank->pp_input[0]->p_source );
+ p_input_bank->pp_input[0]->psz_source );
break;
}
-mpeg_es_SOURCES = mpeg_es.c input_es.c
-mpeg_ps_SOURCES = mpeg_ps.c input_ps.c
-mpeg_ts_SOURCES = mpeg_ts.c input_ts.c
+mpeg_es_SOURCES = mpeg_es.c
+mpeg_ps_SOURCES = mpeg_ps.c
+mpeg_ts_SOURCES = mpeg_ts.c
+++ /dev/null
-/*****************************************************************************
- * input_es.c: Elementary Stream demux and packet management
- *****************************************************************************
- * Copyright (C) 2001 VideoLAN
- * $Id: input_es.c,v 1.13 2002/02/15 13:32:53 sam Exp $
- *
- * Author: Christophe Massiot <massiot@via.ecp.fr>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include <videolan/vlc.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include <fcntl.h>
-
-#if defined( WIN32 )
-# include <io.h> /* read() */
-#else
-# include <sys/uio.h> /* struct iovec */
-#endif
-
-#if defined( WIN32 )
-# include "input_iovec.h"
-#endif
-
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-
-#include "input_es.h"
-
-#include "debug.h"
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int ESProbe ( struct input_thread_s * );
-static int ESRead ( struct input_thread_s *, data_packet_t ** );
-static void ESInit ( struct input_thread_s * );
-static void ESEnd ( struct input_thread_s * );
-static void ESSeek ( struct input_thread_s *, off_t );
-static int ESSetProgram ( struct input_thread_s *, pgrm_descriptor_t * );
-static void ESDemux ( struct input_thread_s *,
- struct data_packet_s * );
-
-/*****************************************************************************
- * Declare a buffer manager
- *****************************************************************************/
-#define FLAGS BUFFERS_UNIQUE_SIZE
-#define NB_LIFO 1
-DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_END( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, 150 );
-DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
-DECLARE_BUFFERS_TOIO( FLAGS, ES_PACKET_SIZE );
-
-/*****************************************************************************
- * Functions exported as capabilities. They are declared as static so that
- * we don't pollute the namespace too much.
- *****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list )
-{
-#define input p_function_list->functions.input
- input.pf_probe = ESProbe;
- input.pf_init = ESInit;
- input.pf_open = NULL;
- input.pf_close = NULL;
- input.pf_end = ESEnd;
- input.pf_set_area = NULL;
- input.pf_set_program = ESSetProgram;
- input.pf_read = ESRead;
- input.pf_demux = ESDemux;
- input.pf_new_packet = input_NewPacket;
- input.pf_new_pes = input_NewPES;
- input.pf_delete_packet = input_DeletePacket;
- input.pf_delete_pes = input_DeletePES;
- input.pf_rewind = NULL;
- input.pf_seek = ESSeek;
-#undef input
-}
-
-/*
- * Data reading functions
- */
-
-/*****************************************************************************
- * ESProbe: verifies that the stream is a ES stream
- *****************************************************************************/
-static int ESProbe( input_thread_t *p_input )
-{
- return 0;
-}
-
-/*****************************************************************************
- * ESInit: initializes ES structures
- *****************************************************************************/
-static void ESInit( input_thread_t * p_input )
-{
- es_descriptor_t * p_es;
-
- p_input->p_method_data = NULL;
-
- if( (p_input->p_method_data = input_BuffersInit()) == NULL )
- {
- p_input->b_error = 1;
- return;
- }
-
- /* FIXME : detect if InitStream failed */
- input_InitStream( p_input, 0 );
- input_AddProgram( p_input, 0, 0 );
- p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
- vlc_mutex_lock( &p_input->stream.stream_lock );
- p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xE0, 0 );
- p_es->i_stream_id = 0xE0;
- p_es->i_type = MPEG1_VIDEO_ES;
- p_es->i_cat = VIDEO_ES;
- input_SelectES( p_input, p_es );
- p_input->stream.p_selected_area->i_tell = 0;
- p_input->stream.p_selected_program->b_is_ok = 1;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-}
-
-/*****************************************************************************
- * ESEnd: frees unused data
- *****************************************************************************/
-static void ESEnd( input_thread_t * p_input )
-{
- input_BuffersEnd( p_input->p_method_data );
-}
-
-/*****************************************************************************
- * ESRead: reads data packets
- *****************************************************************************
- * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
- * packets.
- *****************************************************************************/
-static int ESRead( input_thread_t * p_input,
- data_packet_t ** pp_data )
-{
- int i_read;
- struct iovec p_iovec[ES_READ_ONCE];
- data_packet_t * p_data;
-
- /* Get iovecs */
- *pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
- ES_READ_ONCE );
-
- if ( p_data == NULL )
- {
- return( -1 );
- }
-
- i_read = readv( p_input->i_handle, p_iovec, ES_READ_ONCE );
- if( i_read == -1 )
- {
- intf_ErrMsg( "input error: ES readv error" );
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
- return( -1 );
- }
- p_input->stream.p_selected_area->i_tell += i_read;
- i_read /= ES_PACKET_SIZE;
-
- if( i_read != ES_READ_ONCE )
- {
- /* We got fewer packets than wanted. Give remaining packets
- * back to the buffer allocator. */
- int i_loop;
-
- for( i_loop = 0; i_loop < i_read; i_loop++ )
- {
- pp_data = &(*pp_data)->p_next;
- }
-
- p_input->pf_delete_packet( p_input->p_method_data, *pp_data );
- *pp_data = NULL;
- }
-
- return( i_read );
-}
-
-/*****************************************************************************
- * ESSeek: changes the stream position indicator
- *****************************************************************************/
-static void ESSeek( input_thread_t * p_input, off_t i_position )
-{
- lseek( p_input->i_handle, i_position, SEEK_SET );
-
- p_input->stream.p_selected_area->i_tell = i_position;
-}
-
-
-/*****************************************************************************
- * ESSetProgram: Does nothing
- *****************************************************************************/
-static int ESSetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
-{
- return( 0 );
-}
-
-/*****************************************************************************
- * ESDemux: fakes a demultiplexer
- *****************************************************************************/
-static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
-{
- pes_packet_t * p_pes = p_input->pf_new_pes( p_input->p_method_data );
- decoder_fifo_t * p_fifo =
- p_input->stream.p_selected_program->pp_es[0]->p_decoder_fifo;
-
- if( p_pes == NULL )
- {
- intf_ErrMsg("Out of memory");
- p_input->b_error = 1;
- return;
- }
-
- p_pes->i_rate = p_input->stream.control.i_rate;
- p_pes->p_first = p_pes->p_last = p_data;
- p_pes->i_nb_data = 1;
-
- vlc_mutex_lock( &p_input->stream.stream_lock );
- if( p_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
- {
- /* Wait for the decoder. */
- vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
- }
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
- if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
- | (input_ClockManageControl( p_input,
- p_input->stream.p_selected_program,
- (mtime_t)0 ) == PAUSE_S) )
- {
- intf_WarnMsg( 2, "synchro reinit" );
- p_pes->i_pts = mdate() + DEFAULT_PTS_DELAY;
- p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
- }
-
- input_DecodePES( p_fifo, p_pes );
-}
-
+++ /dev/null
-/*****************************************************************************
- * input_ps.c: PS demux and packet management
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ps.c,v 1.13 2002/02/24 20:51:10 gbazin Exp $
- *
- * Authors: Christophe Massiot <massiot@via.ecp.fr>
- * Cyril Deguet <asmax@via.ecp.fr>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <videolan/vlc.h>
-
-#ifdef STRNCASECMP_IN_STRINGS_H
-# include <strings.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#elif defined( _MSC_VER ) && defined( _WIN32 )
-# include <io.h>
-#endif
-
-#include <fcntl.h>
-
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-
-#include "input_ps.h"
-
-#include "debug.h"
-
-/*****************************************************************************
- * fseeko: fseeko replacement for BSDI.
- *****************************************************************************/
-#ifdef __bsdi__
-int __sfseek __P(( FILE *, fpos_t, int ));
-fpos_t __sftell __P(( FILE * ));
-
-static __inline__ off_t fseeko( FILE *p_file, off_t i_offset, int i_pos )
-{
- return __sfseek( p_file, i_offset, i_pos );
-}
-#endif
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int PSProbe ( struct input_thread_s * );
-static int PSRead ( struct input_thread_s *, data_packet_t ** );
-static void PSInit ( struct input_thread_s * );
-static void PSEnd ( struct input_thread_s * );
-static int PSSetProgram ( struct input_thread_s * , pgrm_descriptor_t * );
-static void PSSeek ( struct input_thread_s *, off_t );
-
-/*****************************************************************************
- * Declare a buffer manager
- *****************************************************************************/
-#define FLAGS BUFFERS_NOFLAGS
-#define NB_LIFO 2
-DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_END( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, 300 );
-DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 300 );
-
-
-/*****************************************************************************
- * Functions exported as capabilities. They are declared as static so that
- * we don't pollute the namespace too much.
- *****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list )
-{
-#define input p_function_list->functions.input
- input.pf_probe = PSProbe;
- input.pf_init = PSInit;
- input.pf_open = NULL;
- input.pf_close = NULL;
- input.pf_end = PSEnd;
- input.pf_init_bit_stream = InitBitstream;
- input.pf_set_area = NULL;
- input.pf_set_program = PSSetProgram;
- input.pf_read = PSRead;
- input.pf_demux = input_DemuxPS;
- input.pf_new_packet = input_NewPacket;
- input.pf_new_pes = input_NewPES;
- input.pf_delete_packet = input_DeletePacket;
- input.pf_delete_pes = input_DeletePES;
- input.pf_rewind = NULL;
- input.pf_seek = PSSeek;
-#undef input
-}
-
-/*
- * Data reading functions
- */
-
-/*****************************************************************************
- * PSProbe: verifies that the stream is a PS stream
- *****************************************************************************/
-static int PSProbe( input_thread_t *p_input )
-{
- char * psz_name = p_input->p_source;
-
- if( ( strlen(psz_name) > 5 ) && (!strncasecmp( psz_name, "file:", 5 )
- || !strncasecmp( psz_name, "http:", 5 )) )
- {
- /* If the user specified "file:" or "http:" then it's probably a
- * PS file */
- return 0;
- }
-
- /* Oh, we load it anyway */
- return 0;
-}
-
-/*****************************************************************************
- * PSInit: initializes PS structures
- *****************************************************************************/
-static void PSInit( input_thread_t * p_input )
-{
- if( (p_input->p_method_data = input_BuffersInit()) == NULL )
- {
- p_input->b_error = 1;
- return;
- }
-
- if( p_input->p_stream == NULL )
- {
- /* Re-open the socket as a buffered FILE stream */
- p_input->p_stream = fdopen( p_input->i_handle, "r" );
-
- if( p_input->p_stream == NULL )
- {
- intf_ErrMsg( "Cannot open file (%s)", strerror(errno) );
- input_BuffersEnd( p_input->p_method_data );
- p_input->b_error = 1;
- return;
- }
- }
-
- /* FIXME : detect if InitStream failed */
- input_InitStream( p_input, sizeof( stream_ps_data_t ) );
- input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
-
- p_input->stream.p_selected_program =
- p_input->stream.pp_programs[0] ;
- p_input->stream.p_new_program =
- p_input->stream.pp_programs[0] ;
-
- if( p_input->stream.b_seekable )
- {
- stream_ps_data_t * p_demux_data =
- (stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
-
- rewind( p_input->p_stream );
-
- /* Pre-parse the stream to gather stream_descriptor_t. */
- p_input->stream.pp_programs[0]->b_is_ok = 0;
- p_demux_data->i_PSM_version = EMPTY_PSM_VERSION;
-
- while( !p_input->b_die && !p_input->b_error
- && !p_demux_data->b_has_PSM )
- {
- int i_result;
- data_packet_t * p_data;
- data_packet_t * p_saved_data;
-
- i_result = PSRead( p_input, &p_data );
- p_saved_data = p_data;
-
- while( p_data != NULL )
- {
- input_ParsePS( p_input, p_data );
- p_data = p_data->p_next;
- }
-
- p_input->pf_delete_packet( p_input->p_method_data, p_saved_data );
-
- if( i_result == 0 )
- {
- /* EOF */
- vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.pp_programs[0]->b_is_ok = 1;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- break;
- }
- else if( i_result == -1 )
- {
- p_input->b_error = 1;
- break;
- }
-
- /* File too big. */
- if( p_input->stream.p_selected_area->i_tell >
- INPUT_PREPARSE_LENGTH )
- {
- break;
- }
- }
- rewind( p_input->p_stream );
- vlc_mutex_lock( &p_input->stream.stream_lock );
-
- p_input->stream.p_selected_area->i_tell = 0;
-
- if( p_demux_data->b_has_PSM )
- {
- /* (The PSM decoder will care about spawning the decoders) */
- p_input->stream.pp_programs[0]->b_is_ok = 1;
- }
-#ifdef AUTO_SPAWN
- else
- {
- /* (We have to do it ourselves) */
- int i_es;
-
- /* FIXME: we should do multiple passes in case an audio type
- * is not present */
- for( i_es = 0;
- i_es < p_input->stream.pp_programs[0]->i_es_number;
- i_es++ )
- {
-#define p_es p_input->stream.pp_programs[0]->pp_es[i_es]
- switch( p_es->i_type )
- {
- case MPEG1_VIDEO_ES:
- case MPEG2_VIDEO_ES:
- input_SelectES( p_input, p_es );
- break;
-
- case MPEG1_AUDIO_ES:
- case MPEG2_AUDIO_ES:
- if( config_GetIntVariable( INPUT_CHANNEL_VAR )
- == (p_es->i_id & 0x1F) ||
- ( config_GetIntVariable( INPUT_CHANNEL_VAR ) < 0
- && !(p_es->i_id & 0x1F) ) )
- switch( config_GetIntVariable( INPUT_AUDIO_VAR ) )
- {
- case -1:
- case REQUESTED_MPEG:
- input_SelectES( p_input, p_es );
- }
- break;
-
- case AC3_AUDIO_ES:
- if( config_GetIntVariable( INPUT_CHANNEL_VAR )
- == ((p_es->i_id & 0xF00) >> 8) ||
- ( config_GetIntVariable( INPUT_CHANNEL_VAR ) < 0
- && !((p_es->i_id & 0xF00) >> 8) ) )
- switch( config_GetIntVariable( INPUT_AUDIO_VAR ) )
- {
- case -1:
- case REQUESTED_AC3:
- input_SelectES( p_input, p_es );
- }
- break;
-
- case DVD_SPU_ES:
- if( config_GetIntVariable( INPUT_SUBTITLE_VAR )
- == ((p_es->i_id & 0x1F00) >> 8) )
- {
- input_SelectES( p_input, p_es );
- }
- break;
-
- case LPCM_AUDIO_ES:
- if( config_GetIntVariable( INPUT_CHANNEL_VAR )
- == ((p_es->i_id & 0x1F00) >> 8) ||
- ( config_GetIntVariable( INPUT_CHANNEL_VAR ) < 0
- && !((p_es->i_id & 0x1F00) >> 8) ) )
- switch( config_GetIntVariable( INPUT_AUDIO_VAR ) )
- {
- case -1:
- case REQUESTED_LPCM:
- input_SelectES( p_input, p_es );
- }
- break;
- }
- }
-
- }
-#endif
- if( p_main->b_stats )
- {
- input_DumpStream( p_input );
- }
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- }
- else
- {
- /* The programs will be added when we read them. */
- vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.i_method = INPUT_METHOD_FILE;
- p_input->stream.pp_programs[0]->b_is_ok = 0;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- }
-}
-
-/*****************************************************************************
- * PSEnd: frees unused data
- *****************************************************************************/
-static void PSEnd( input_thread_t * p_input )
-{
- input_BuffersEnd( p_input->p_method_data );
-}
-
-/*****************************************************************************
- * SafeRead: reads a chunk of stream and correctly detects errors
- *****************************************************************************/
-static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
- size_t i_len )
-{
- int i_error;
-
- while( fread( p_buffer, i_len, 1, p_input->p_stream ) != 1 )
- {
- if( feof( p_input->p_stream ) )
- {
- return( 0 );
- }
-
- if( (i_error = ferror( p_input->p_stream )) )
- {
- intf_ErrMsg( "Read failed (%s)", strerror(i_error) );
- return( -1 );
- }
- }
- vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.p_selected_area->i_tell += i_len;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- return( i_len );
-}
-
-/*****************************************************************************
- * PSRead: reads data packets
- *****************************************************************************
- * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
- * packets.
- *****************************************************************************/
-static int PSRead( input_thread_t * p_input,
- data_packet_t ** pp_data )
-{
- byte_t p_header[6];
- data_packet_t * p_data;
- size_t i_packet_size;
- int i_packet, i_error;
-
- *pp_data = NULL;
-
- for( i_packet = 0; i_packet < PS_READ_ONCE; i_packet++ )
- {
- /* Read what we believe to be a packet header. */
- if( (i_error = SafeRead( p_input, p_header, 4 )) <= 0 )
- {
- return( i_error );
- }
-
- if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
- {
- /* This is not the startcode of a packet. Read the stream
- * until we find one. */
- u32 i_startcode = U32_AT(p_header);
- int i_dummy;
-
- if( i_startcode )
- {
- /* It is common for MPEG-1 streams to pad with zeros
- * (although it is forbidden by the recommendation), so
- * don't bother everybody in this case. */
- intf_WarnMsg( 3, "Garbage at input (%.8x)", i_startcode );
- }
-
- while( (i_startcode & 0xFFFFFF00) != 0x100L )
- {
- i_startcode <<= 8;
- if( (i_dummy = getc( p_input->p_stream )) != EOF )
- {
- i_startcode |= i_dummy;
- }
- else
- {
- return( 0 );
- }
- }
- /* Packet found. */
- *(u32 *)p_header = U32_AT(&i_startcode);
- }
-
- /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
- if( U32_AT(p_header) != 0x1B9 )
- {
- /* The packet is at least 6 bytes long. */
- if( (i_error = SafeRead( p_input, p_header + 4, 2 )) <= 0 )
- {
- return( i_error );
- }
-
- if( U32_AT(p_header) != 0x1BA )
- {
- /* That's the case for all packets, except pack header. */
- i_packet_size = U16_AT(&p_header[4]);
- }
- else
- {
- /* Pack header. */
- if( (p_header[4] & 0xC0) == 0x40 )
- {
- /* MPEG-2 */
- i_packet_size = 8;
- }
- else if( (p_header[4] & 0xF0) == 0x20 )
- {
- /* MPEG-1 */
- i_packet_size = 6;
- }
- else
- {
- intf_ErrMsg( "Unable to determine stream type" );
- return( -1 );
- }
- }
- }
- else
- {
- /* System End Code */
- i_packet_size = -2;
- }
-
- /* Fetch a packet of the appropriate size. */
- p_data = p_input->pf_new_packet( p_input->p_method_data,
- i_packet_size + 6 );
- if( p_data == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- return( -1 );
- }
-
- if( U32_AT(p_header) != 0x1B9 )
- {
- /* Copy the header we already read. */
- memcpy( p_data->p_demux_start, p_header, 6 );
-
- /* Read the remaining of the packet. */
- if( i_packet_size && (i_error =
- SafeRead( p_input, p_data->p_demux_start + 6,
- i_packet_size )) <= 0 )
- {
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
- return( i_error );
- }
-
- /* In MPEG-2 pack headers we still have to read stuffing bytes. */
- if( U32_AT(p_header) == 0x1BA )
- {
- if( i_packet_size == 8 && (p_data->p_demux_start[13] & 0x7) != 0 )
- {
- /* MPEG-2 stuffing bytes */
- byte_t p_garbage[8];
- if( (i_error = SafeRead( p_input, p_garbage,
- p_data->p_demux_start[13] & 0x7)) <= 0 )
- {
- p_input->pf_delete_packet( p_input->p_method_data,
- p_data );
- return( i_error );
- }
- }
- }
- }
- else
- {
- /* Copy the small header. */
- memcpy( p_data->p_demux_start, p_header, 4 );
- }
-
- /* Give the packet to the other input stages. */
- *pp_data = p_data;
- pp_data = &p_data->p_next;
- }
-
- return( i_packet + 1 );
-}
-
-/*****************************************************************************
- * PSSetProgram: Does nothing since a PS Stream is mono-program
- *****************************************************************************/
-static int PSSetProgram( input_thread_t * p_input,
- pgrm_descriptor_t * p_program)
-{
- return( 0 );
-}
-/*****************************************************************************
- * PSSeek: changes the stream position indicator
- *****************************************************************************/
-static void PSSeek( input_thread_t * p_input, off_t i_position )
-{
- /* A little bourrin but should work for a while --Meuuh */
-#if defined( WIN32 ) || defined( SYS_GNU0_2 )
- fseek( p_input->p_stream, (long)i_position, SEEK_SET );
-#else
- fseeko( p_input->p_stream, i_position, SEEK_SET );
-#endif
-
- p_input->stream.p_selected_area->i_tell = i_position;
-}
-
+++ /dev/null
-/*****************************************************************************
- * input_ps.h: thread structure of the PS plugin
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ps.h,v 1.2 2001/12/27 03:47:09 massiot Exp $
- *
- * Authors: Christophe Massiot <massiot@via.ecp.fr>
- * Cyril Deguet <asmax@via.ecp.fr>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-#define PS_READ_ONCE 50
+++ /dev/null
-/*****************************************************************************
- * input_ts.c: TS demux and netlist management
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ts.c,v 1.13 2002/02/15 13:32:53 sam Exp $
- *
- * Authors: Henri Fallon <henri@videolan.org>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include <videolan/vlc.h>
-
-#ifdef STRNCASECMP_IN_STRINGS_H
-# include <strings.h>
-#endif
-
-#include <sys/types.h>
-
-#if !defined( _MSC_VER )
-# include <sys/time.h>
-#endif
-
-#ifdef SYS_NTO
-# include <sys/select.h>
-#endif
-
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include <fcntl.h>
-
-#if defined( WIN32 )
-# include <io.h>
-# include <winsock2.h>
-#else
-# include <sys/uio.h> /* struct iovec */
-#endif
-
-#if defined( WIN32 )
-# include "input_iovec.h"
-#endif
-
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-
-#include "input_ts.h"
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int TSProbe ( struct input_thread_s * );
-static void TSInit ( struct input_thread_s * );
-static void TSEnd ( struct input_thread_s * );
-static int TSRead ( struct input_thread_s *, data_packet_t ** );
-
-/*****************************************************************************
- * Declare a buffer manager
- *****************************************************************************/
-#define FLAGS BUFFERS_UNIQUE_SIZE
-#define NB_LIFO 1
-DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_END( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, 1000 );
-DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
-DECLARE_BUFFERS_TOIO( FLAGS, TS_PACKET_SIZE );
-
-/*****************************************************************************
- * Functions exported as capabilities. They are declared as static so that
- * we don't pollute the namespace too much.
- *****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list )
-{
-#define input p_function_list->functions.input
- input.pf_probe = TSProbe;
- input.pf_init = TSInit;
- input.pf_open = NULL;
- input.pf_close = NULL;
- input.pf_end = TSEnd;
- input.pf_init_bit_stream = InitBitstream;
- input.pf_set_area = NULL;
- input.pf_set_program = input_SetProgram;
- input.pf_read = TSRead;
- input.pf_demux = input_DemuxTS;
- input.pf_new_packet = input_NewPacket;
- input.pf_new_pes = input_NewPES;
- input.pf_delete_packet = input_DeletePacket;
- input.pf_delete_pes = input_DeletePES;
- input.pf_rewind = NULL;
- input.pf_seek = NULL;
-#undef input
-}
-
-/*****************************************************************************
- * TSProbe: verifies that the stream is a TS stream
- *****************************************************************************/
-static int TSProbe( input_thread_t * p_input )
-{
- char * psz_name = p_input->p_source;
-
- if( ( strlen(psz_name) >= 10 && !strncasecmp( psz_name, "udpstream:", 10 ) )
- || ( strlen(psz_name) >= 4 && !strncasecmp( psz_name, "udp:", 4 ) ) )
- {
- /* If the user specified "udp:" then it's probably a network stream */
- return 0;
- }
-
- if( ( strlen(psz_name) > 5 ) && !strncasecmp( psz_name, "file:", 5 ) )
- {
- /* If the user specified "file:" then it's probably a file */
- psz_name += 5;
- }
-
- if( ( strlen(psz_name) > 3 ) &&
- !strncasecmp( psz_name+strlen(psz_name)-3, ".ts", 3) )
- {
- /* If it is a ".ts" file it's probably a TS file ... */
- return 0;
- }
-
- return -1;
-}
-
-/*****************************************************************************
- * TSInit: initializes TS structures
- *****************************************************************************/
-static void TSInit( input_thread_t * p_input )
-{
- thread_ts_data_t * p_method;
- es_descriptor_t * p_pat_es;
- es_ts_data_t * p_demux_data;
- stream_ts_data_t * p_stream_data;
-
- /* Initialise structure */
- p_method = malloc( sizeof( thread_ts_data_t ) );
- if( p_method == NULL )
- {
- intf_ErrMsg( "TS input : Out of memory" );
- p_input->b_error = 1;
- return;
- }
-
-#if defined( WIN32 )
- p_method->i_length = 0;
- p_method->i_offset = 0;
-#endif
-
- p_input->p_plugin_data = (void *)p_method;
- p_input->p_method_data = NULL;
-
-
- if( (p_input->p_method_data = input_BuffersInit()) == NULL )
- {
- p_input->b_error = 1;
- return;
- }
-
- /* Initialize the stream */
- input_InitStream( p_input, sizeof( stream_ts_data_t ) );
-
- p_input->stream.p_selected_area->i_tell = 0;
-
- /* Init */
- p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
- p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
-
- /* We'll have to catch the PAT in order to continue
- * Then the input will catch the PMT and then the others ES
- * The PAT es is indepedent of any program. */
- p_pat_es = input_AddES( p_input, NULL,
- 0x00, sizeof( es_ts_data_t ) );
- p_demux_data=(es_ts_data_t *)p_pat_es->p_demux_data;
- p_demux_data->b_psi = 1;
- p_demux_data->i_psi_type = PSI_IS_PAT;
- p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
- p_demux_data->p_psi_section->b_is_complete = 1;
-
-}
-
-/*****************************************************************************
- * TSEnd: frees unused data
- *****************************************************************************/
-static void TSEnd( input_thread_t * p_input )
-{
- es_descriptor_t * p_pat_es;
-
- p_pat_es = input_FindES( p_input, 0x00 );
-
- if( p_pat_es != NULL )
- input_DelES( p_input, p_pat_es );
-
- free(p_input->p_plugin_data);
- input_BuffersEnd( p_input->p_method_data );
-}
-
-/*****************************************************************************
- * TSRead: reads data packets
- *****************************************************************************
- * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
- * packets.
- *****************************************************************************/
-static int TSRead( input_thread_t * p_input,
- data_packet_t ** pp_data )
-{
- thread_ts_data_t * p_method;
- int i_read = 0, i_loop;
- int i_data = 1;
- struct iovec p_iovec[TS_READ_ONCE];
- data_packet_t * p_data;
- struct timeval timeout;
-
- /* Init */
- p_method = ( thread_ts_data_t * )p_input->p_plugin_data;
-
- /* Initialize file descriptor set */
- FD_ZERO( &(p_method->fds) );
- FD_SET( p_input->i_handle, &(p_method->fds) );
-
- /* We'll wait 0.5 second if nothing happens */
- timeout.tv_sec = 0;
- timeout.tv_usec = 500000;
-
- /* Fill if some data is available */
-#if defined( WIN32 )
- if ( ! p_input->stream.b_pace_control )
-#endif
- {
- i_data = select( p_input->i_handle + 1, &p_method->fds,
- NULL, NULL, &timeout );
- }
-
- if( i_data == -1 )
- {
- intf_ErrMsg( "input error: TS select error (%s)", strerror(errno) );
- return( -1 );
- }
-
- if( i_data )
- {
- /* Get iovecs */
- *pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
- TS_READ_ONCE );
-
- if ( p_data == NULL )
- {
- return( -1 );
- }
-
-#if defined( WIN32 )
- if( p_input->stream.b_pace_control )
- {
- i_read = readv( p_input->i_handle, p_iovec, TS_READ_ONCE );
- }
- else
- {
- i_read = readv_network( p_input->i_handle, p_iovec,
- TS_READ_ONCE, p_method );
- }
-#else
- i_read = readv( p_input->i_handle, p_iovec, TS_READ_ONCE );
-
- /* Shouldn't happen, but it does - at least under Linux */
- if( (i_read == -1) && ( (errno == EAGAIN) || (errno = EWOULDBLOCK) ) )
- {
- /* just ignore that error */
- intf_ErrMsg( "input error: 0 bytes read" );
- i_read = 0;
- }
-#endif
- /* Error */
- if( i_read == -1 )
- {
- intf_ErrMsg( "input error: TS readv error" );
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
- return( -1 );
- }
- p_input->stream.p_selected_area->i_tell += i_read;
- i_read /= TS_PACKET_SIZE;
-
- /* Check correct TS header */
- for( i_loop = 0; i_loop < i_read; i_loop++ )
- {
- if( (*pp_data)->p_demux_start[0] != 0x47 )
- {
- intf_ErrMsg( "input error: bad TS packet (starts with "
- "0x%.2x, should be 0x47)",
- p_data->p_demux_start[0] );
- }
- pp_data = &(*pp_data)->p_next;
- }
-
- if( i_read != TS_READ_ONCE )
- {
- /* Delete remaining packets */
- p_input->pf_delete_packet( p_input->p_method_data, *pp_data );
- }
- }
-
- *pp_data = NULL;
-
- return( i_read );
-}
-
+++ /dev/null
-/*****************************************************************************
- * input_ts.h: structures of the input not exported to other modules
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ts.h,v 1.5 2001/12/30 07:09:55 sam Exp $
- *
- * Authors: Henri Fallon <henri@via.ecp.fr>
- * Boris Dorès <babal@via.ecp.fr>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/* UDP packets contain 1500 bytes, that is 7 TS packets */
-#define TS_READ_ONCE 7
-
-#ifdef WIN32
-# define BUFFER_SIZE (7 * TS_PACKET_SIZE)
-#endif
-
-/*****************************************************************************
- * thread_ts_data_t: private input data
- *****************************************************************************/
-typedef struct thread_ts_data_s
-{
- /* The file descriptor we select() on */
- fd_set fds;
-
-#if defined( WIN32 )
- char p_buffer[ BUFFER_SIZE ]; /* temporary buffer for readv_network */
- int i_length; /* length of the UDP packet */
- int i_offset; /* number of bytes already read from the buffer */
-#endif
-
-} thread_ts_data_t;
-
-/*****************************************************************************
- * network readv() replacement for iovec-impaired C libraries
- *****************************************************************************/
-#if defined(WIN32)
-static __inline__ int read_network( int i_fd, char * p_base,
- thread_ts_data_t *p_sys, int i_len )
-{
- int i_bytes;
-
- if( p_sys->i_offset >= p_sys->i_length )
- {
- p_sys->i_length = recv( i_fd, p_sys->p_buffer, BUFFER_SIZE, 0 );
- if ( p_sys->i_length == SOCKET_ERROR )
- {
- return -1;
- }
- p_sys->i_offset = 0;
- }
-
- if( i_len <= p_sys->i_length - p_sys->i_offset )
- {
- i_bytes = i_len;
- }
- else
- {
- i_bytes = p_sys->i_length - p_sys->i_offset;
- }
-
- FAST_MEMCPY( p_base, p_sys->p_buffer + p_sys->i_offset, i_bytes );
- p_sys->i_offset += i_bytes;
-
- return i_bytes;
-}
-
-static __inline__ int readv_network( int i_fd, struct iovec *p_iovec,
- int i_count, thread_ts_data_t *p_sys )
-{
- int i_index, i_len, i_total = 0;
- u8 *p_base;
-
- for( i_index = i_count; i_index; i_index-- )
- {
- register signed int i_bytes;
-
- i_len = p_iovec->iov_len;
- p_base = p_iovec->iov_base;
-
- /* Loop is unrolled one time to spare the (i_bytes <= 0) test */
- if( i_len > 0 )
- {
- i_bytes = read_network( i_fd, p_base, p_sys, i_len );
-
- if( ( i_total == 0 ) && ( i_bytes < 0 ) )
- {
- return -1;
- }
-
- if( i_bytes <= 0 )
- {
- return i_total;
- }
-
- i_len -= i_bytes; i_total += i_bytes; p_base += i_bytes;
-
- while( i_len > 0 )
- {
- i_bytes = read_network( i_fd, p_base, p_sys, i_len );
-
- if( i_bytes <= 0 )
- {
- return i_total;
- }
-
- i_len -= i_bytes; i_total += i_bytes; p_base += i_bytes;
- }
- }
-
- p_iovec++;
- }
-
- return i_total;
-}
-#endif
-
* mpeg_es.c : Elementary Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: mpeg_es.c,v 1.3 2002/02/15 13:32:53 sam Exp $
+ * $Id: mpeg_es.c,v 1.4 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
+#include <errno.h>
#include <videolan/vlc.h>
+#include <sys/types.h>
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+#define ES_PACKET_SIZE 65536
+#define MAX_PACKETS_IN_FIFO 3
+
/*****************************************************************************
- * Capabilities defined in the other files.
+ * Local prototypes
*****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list );
+static void input_getfunctions( function_list_t * p_function_list );
+static int ESDemux ( struct input_thread_s * );
+static int ESInit ( struct input_thread_s * );
+static void ESEnd ( struct input_thread_s * );
/*****************************************************************************
* Build configuration tree.
MODULE_CONFIG_STOP
MODULE_INIT_START
- SET_DESCRIPTION( "ISO 13818-1 MPEG Elementary Stream input" )
- ADD_CAPABILITY( INPUT, 5 )
+ SET_DESCRIPTION( "ISO 13818-2 MPEG Elementary Stream input" )
+ ADD_CAPABILITY( DEMUX, 150 )
ADD_SHORTCUT( "es" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
- _M( input_getfunctions )( &p_module->p_functions->input );
+ input_getfunctions( &p_module->p_functions->demux );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.demux
+ input.pf_init = ESInit;
+ input.pf_end = ESEnd;
+ input.pf_demux = ESDemux;
+ input.pf_rewind = NULL;
+#undef input
+}
+
+/*
+ * Data reading functions
+ */
+
+/*****************************************************************************
+ * ESInit: initializes ES structures
+ *****************************************************************************/
+static int ESInit( input_thread_t * p_input )
+{
+ es_descriptor_t * p_es;
+ byte_t * p_peek;
+
+ /* Initialize access plug-in structures. */
+ if( p_input->i_mtu == 0 )
+ {
+ /* Improve speed. */
+ p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
+ }
+
+ /* Have a peep at the show. */
+ if( input_Peek( p_input, &p_peek, 4 ) < 4 )
+ {
+ /* Stream shorter than 4 bytes... */
+ intf_ErrMsg( "input error: cannot peek() (mpeg_es)" );
+ return( -1 );
+ }
+
+ if( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 )
+ {
+ if( p_input->psz_demux && strncmp( p_input->psz_demux, "es", 3 ) )
+ {
+ /* User forced */
+ intf_ErrMsg( "input error: this doesn't seem like an MPEG stream, continuing" );
+ }
+ else
+ {
+ intf_WarnMsg( 2, "input: ES plug-in discarded (no startcode)" );
+ return( -1 );
+ }
+ }
+ else if( *(p_peek + 3) > 0xb9 )
+ {
+ if( p_input->psz_demux && strncmp( p_input->psz_demux, "es", 3 ) )
+ {
+ /* User forced */
+ intf_ErrMsg( "input error: this seems to be a system stream (PS plug-in ?), but continuing" );
+ }
+ else
+ {
+ intf_WarnMsg( 2, "input: ES plug-in discarded (system startcode)" );
+ return( -1 );
+ }
+ }
+
+ if( input_InitStream( p_input, 0 ) == -1 )
+ {
+ return( -1 );
+ }
+ input_AddProgram( p_input, 0, 0 );
+ p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xE0, 0 );
+ p_es->i_stream_id = 0xE0;
+ p_es->i_type = MPEG1_VIDEO_ES;
+ p_es->i_cat = VIDEO_ES;
+ input_SelectES( p_input, p_es );
+ p_input->stream.p_selected_area->i_tell = 0;
+ p_input->stream.p_selected_program->b_is_ok = 1;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ESEnd: frees unused data
+ *****************************************************************************/
+static void ESEnd( input_thread_t * p_input )
+{
+}
+
+/*****************************************************************************
+ * ESDemux: reads and demuxes data packets
+ *****************************************************************************
+ * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
+ *****************************************************************************/
+static int ESDemux( input_thread_t * p_input )
+{
+ ssize_t i_read;
+ decoder_fifo_t * p_fifo =
+ p_input->stream.p_selected_program->pp_es[0]->p_decoder_fifo;
+ pes_packet_t * p_pes;
+ data_packet_t * p_data;
+
+ i_read = input_SplitBuffer( p_input, &p_data, ES_PACKET_SIZE );
+
+ if ( i_read <= 0 )
+ {
+ return( i_read );
+ }
+
+ p_pes = input_NewPES( p_input->p_method_data );
+
+ if( p_pes == NULL )
+ {
+ intf_ErrMsg("Out of memory");
+ input_DeletePacket( p_input->p_method_data, p_data );
+ return( -1 );
+ }
+
+ p_pes->i_rate = p_input->stream.control.i_rate;
+ p_pes->p_first = p_pes->p_last = p_data;
+ p_pes->i_nb_data = 1;
+
+ vlc_mutex_lock( &p_fifo->data_lock );
+ if( p_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
+ {
+ /* Wait for the decoder. */
+ vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
+ }
+ vlc_mutex_unlock( &p_fifo->data_lock );
+
+ if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
+ | (input_ClockManageControl( p_input,
+ p_input->stream.p_selected_program,
+ (mtime_t)0 ) == PAUSE_S) )
+ {
+ intf_WarnMsg( 2, "synchro reinit" );
+ p_pes->i_pts = mdate() + DEFAULT_PTS_DELAY;
+ p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
+ }
+
+ input_DecodePES( p_fifo, p_pes );
+
+ return( 1 );
+}
+
* mpeg_ps.c : Program Stream input module for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: mpeg_ps.c,v 1.3 2002/02/15 13:32:53 sam Exp $
+ * $Id: mpeg_ps.c,v 1.4 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
+#include <errno.h>
#include <videolan/vlc.h>
+#include <sys/types.h>
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
/*****************************************************************************
- * Capabilities defined in the other files.
+ * Constants
*****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list );
+#define PS_READ_ONCE 50
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list );
+static int PSDemux ( struct input_thread_s * );
+static int PSInit ( struct input_thread_s * );
+static void PSEnd ( struct input_thread_s * );
/*****************************************************************************
* Build configuration tree.
MODULE_INIT_START
SET_DESCRIPTION( "ISO 13818-1 MPEG Program Stream input" )
- ADD_CAPABILITY( INPUT, 10 )
+ ADD_CAPABILITY( DEMUX, 100 )
ADD_SHORTCUT( "ps" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
- _M( input_getfunctions )( &p_module->p_functions->input );
+ input_getfunctions( &p_module->p_functions->demux );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.demux
+ input.pf_init = PSInit;
+ input.pf_end = PSEnd;
+ input.pf_demux = PSDemux;
+ input.pf_rewind = NULL;
+#undef input
+}
+
+/*
+ * Data reading functions
+ */
+
+/*****************************************************************************
+ * PSRead: reads one PS packet
+ *****************************************************************************/
+#define PEEK( SIZE ) \
+ i_error = input_Peek( p_input, &p_peek, SIZE ); \
+ if( i_error == -1 ) \
+ { \
+ return( -1 ); \
+ } \
+ else if( i_error < SIZE ) \
+ { \
+ /* EOF */ \
+ return( 0 ); \
+ }
+
+static __inline__ ssize_t PSRead( input_thread_t * p_input,
+ data_packet_t ** pp_data )
+{
+ byte_t * p_peek;
+ size_t i_packet_size;
+ ssize_t i_error, i_read;
+
+ /* Read what we believe to be a packet header. */
+ PEEK( 4 );
+
+ if( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 )
+ {
+ if( *p_peek || *(p_peek + 1) || *(p_peek + 2) )
+ {
+ /* It is common for MPEG-1 streams to pad with zeros
+ * (although it is forbidden by the recommendation), so
+ * don't bother everybody in this case. */
+ intf_WarnMsg( 3, "input warning: garbage at input (0x%x%x%x%x)",
+ *p_peek, *(p_peek + 1), *(p_peek + 2), *(p_peek + 3) );
+ }
+
+ /* This is not the startcode of a packet. Read the stream
+ * until we find one. */
+ while( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 )
+ {
+ p_input->p_current_data++;
+ PEEK( 4 );
+ }
+ /* Packet found. */
+ }
+
+ /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
+ if( p_peek[3] != 0xB9 )
+ {
+ /* The packet is at least 6 bytes long. */
+ PEEK( 6 );
+
+ if( p_peek[3] != 0xBA )
+ {
+ /* That's the case for all packets, except pack header. */
+ i_packet_size = (p_peek[4] << 8) | p_peek[5];
+ }
+ else
+ {
+ /* Pack header. */
+ if( (p_peek[4] & 0xC0) == 0x40 )
+ {
+ /* MPEG-2 */
+ i_packet_size = 8;
+ }
+ else if( (p_peek[4] & 0xF0) == 0x20 )
+ {
+ /* MPEG-1 */
+ i_packet_size = 6;
+ }
+ else
+ {
+ intf_ErrMsg( "Unable to determine stream type" );
+ return( -1 );
+ }
+ }
+ }
+ else
+ {
+ /* System End Code */
+ i_packet_size = -2;
+ }
+
+ /* Fetch a packet of the appropriate size. */
+ i_read = input_SplitBuffer( p_input, pp_data, i_packet_size + 6 );
+ if( i_read <= 0 )
+ {
+ return( i_read );
+ }
+
+ /* In MPEG-2 pack headers we still have to read stuffing bytes. */
+ if( ((*pp_data)->p_demux_start[3] == 0xBA) && (i_packet_size == 8) )
+ {
+ size_t i_stuffing = ((*pp_data)->p_demux_start[13] & 0x7);
+ /* Force refill of the input buffer - though we don't care
+ * about p_peek. Please note that this is unoptimized. */
+ PEEK( i_stuffing );
+ p_input->p_current_data += i_stuffing;
+ }
+
+ return( 1 );
+}
+
+/*****************************************************************************
+ * PSInit: initializes PS structures
+ *****************************************************************************/
+static int PSInit( input_thread_t * p_input )
+{
+ byte_t * p_peek;
+
+ /* Initialize access plug-in structures. */
+ if( p_input->i_mtu == 0 )
+ {
+ /* Improve speed. */
+ p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
+ }
+
+ /* Have a peep at the show. */
+ if( input_Peek( p_input, &p_peek, 4 ) < 4 )
+ {
+ /* Stream shorter than 4 bytes... */
+ intf_ErrMsg( "input error: cannot peek() (mpeg_ps)" );
+ return( -1 );
+ }
+
+ if( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 )
+ {
+ if( p_input->psz_demux && strncmp( p_input->psz_demux, "ps", 3 ) )
+ {
+ /* User forced */
+ intf_ErrMsg( "input error: this doesn't seem like an MPEG stream, continuing" );
+ }
+ else
+ {
+ intf_WarnMsg( 2, "input: PS plug-in discarded (no startcode)" );
+ return( -1 );
+ }
+ }
+ else if( *(p_peek + 3) <= 0xb9 )
+ {
+ if( p_input->psz_demux && strncmp( p_input->psz_demux, "ps", 3 ) )
+ {
+ /* User forced */
+ intf_ErrMsg( "input error: this seems to be an elementary stream (ES plug-in ?),");
+ intf_ErrMsg( "but continuing" );
+ }
+ else
+ {
+ intf_WarnMsg( 2, "input: PS plug-in discarded (ES startcode)" );
+ return( -1 );
+ }
+ }
+
+ if( input_InitStream( p_input, sizeof( stream_ps_data_t ) ) == -1 )
+ {
+ return( -1 );
+ }
+ input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
+
+ p_input->stream.p_selected_program =
+ p_input->stream.pp_programs[0] ;
+ p_input->stream.p_new_program =
+ p_input->stream.pp_programs[0] ;
+
+ if( p_input->stream.b_seekable )
+ {
+ stream_ps_data_t * p_demux_data =
+ (stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
+
+ /* Pre-parse the stream to gather stream_descriptor_t. */
+ p_input->stream.pp_programs[0]->b_is_ok = 0;
+ p_demux_data->i_PSM_version = EMPTY_PSM_VERSION;
+
+ while( !p_input->b_die && !p_input->b_error
+ && !p_demux_data->b_has_PSM )
+ {
+ ssize_t i_result;
+ data_packet_t * p_data;
+
+ i_result = PSRead( p_input, &p_data );
+
+ if( i_result == 0 )
+ {
+ /* EOF */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.pp_programs[0]->b_is_ok = 1;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ break;
+ }
+ else if( i_result == -1 )
+ {
+ p_input->b_error = 1;
+ break;
+ }
+
+ input_ParsePS( p_input, p_data );
+ input_DeletePacket( p_input->p_method_data, p_data );
+
+ /* File too big. */
+ if( p_input->stream.p_selected_area->i_tell >
+ INPUT_PREPARSE_LENGTH )
+ {
+ break;
+ }
+ }
+ p_input->pf_seek( p_input, (off_t)0 );
+ input_AccessReinit( p_input );
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+
+ if( p_demux_data->b_has_PSM )
+ {
+ /* (The PSM decoder will care about spawning the decoders) */
+ p_input->stream.pp_programs[0]->b_is_ok = 1;
+ }
+#ifdef AUTO_SPAWN
+ else
+ {
+ /* (We have to do it ourselves) */
+ int i_es;
+
+ /* FIXME: we should do multiple passes in case an audio type
+ * is not present */
+ for( i_es = 0;
+ i_es < p_input->stream.pp_programs[0]->i_es_number;
+ i_es++ )
+ {
+#define p_es p_input->stream.pp_programs[0]->pp_es[i_es]
+ switch( p_es->i_type )
+ {
+ case MPEG1_VIDEO_ES:
+ case MPEG2_VIDEO_ES:
+ input_SelectES( p_input, p_es );
+ break;
+
+ case MPEG1_AUDIO_ES:
+ case MPEG2_AUDIO_ES:
+ if( config_GetIntVariable( INPUT_CHANNEL_VAR )
+ == (p_es->i_id & 0x1F) ||
+ ( config_GetIntVariable( INPUT_CHANNEL_VAR ) < 0
+ && !(p_es->i_id & 0x1F) ) )
+ switch( config_GetIntVariable( INPUT_AUDIO_VAR ) )
+ {
+ case -1:
+ case REQUESTED_MPEG:
+ input_SelectES( p_input, p_es );
+ }
+ break;
+
+ case AC3_AUDIO_ES:
+ if( config_GetIntVariable( INPUT_CHANNEL_VAR )
+ == ((p_es->i_id & 0xF00) >> 8) ||
+ ( config_GetIntVariable( INPUT_CHANNEL_VAR ) < 0
+ && !((p_es->i_id & 0xF00) >> 8) ) )
+ switch( config_GetIntVariable( INPUT_AUDIO_VAR ) )
+ {
+ case -1:
+ case REQUESTED_AC3:
+ input_SelectES( p_input, p_es );
+ }
+ break;
+
+ case DVD_SPU_ES:
+ if( config_GetIntVariable( INPUT_SUBTITLE_VAR )
+ == ((p_es->i_id & 0x1F00) >> 8) )
+ {
+ input_SelectES( p_input, p_es );
+ }
+ break;
+
+ case LPCM_AUDIO_ES:
+ if( config_GetIntVariable( INPUT_CHANNEL_VAR )
+ == ((p_es->i_id & 0x1F00) >> 8) ||
+ ( config_GetIntVariable( INPUT_CHANNEL_VAR ) < 0
+ && !((p_es->i_id & 0x1F00) >> 8) ) )
+ switch( config_GetIntVariable( INPUT_AUDIO_VAR ) )
+ {
+ case -1:
+ case REQUESTED_LPCM:
+ input_SelectES( p_input, p_es );
+ }
+ break;
+ }
+ }
+
+ }
+#endif
+ if( p_main->b_stats )
+ {
+ input_DumpStream( p_input );
+ }
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+ else
+ {
+ /* The programs will be added when we read them. */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.i_method = INPUT_METHOD_FILE;
+ p_input->stream.pp_programs[0]->b_is_ok = 0;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * PSEnd: frees unused data
+ *****************************************************************************/
+static void PSEnd( input_thread_t * p_input )
+{
+}
+
+/*****************************************************************************
+ * PSDemux: reads and demuxes data packets
+ *****************************************************************************
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
+ *****************************************************************************/
+static int PSDemux( input_thread_t * p_input )
+{
+ int i;
+
+ for( i = 0; i < PS_READ_ONCE; i++ )
+ {
+ data_packet_t * p_data;
+ ssize_t i_result;
+
+ i_result = PSRead( p_input, &p_data );
+
+ if( i_result <= 0 )
+ {
+ return( i_result );
+ }
+
+ input_DemuxPS( p_input, p_data );
+ }
+
+ return( i );
+}
+
* mpeg_ts.c : Transport Stream input module for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: mpeg_ts.c,v 1.3 2001/12/31 04:53:33 sam Exp $
+ * $Id: mpeg_ts.c,v 1.4 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Henri Fallon <henri@via.ecp.fr>
*
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <stdlib.h> /* malloc(), free() */
-#include <string.h> /* strdup() */
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
#include <videolan/vlc.h>
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
/*****************************************************************************
- * Capabilities defined in the other files.
+ * Constants
*****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list );
+#define TS_READ_ONCE 200
+#define TS_PACKET_SIZE 188
+#define TS_SYNC_CODE 0x47
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list );
+static int TSInit ( struct input_thread_s * );
+static void TSEnd ( struct input_thread_s * );
+static int TSDemux ( struct input_thread_s * );
/*****************************************************************************
* Build configuration tree.
MODULE_INIT_START
SET_DESCRIPTION( "ISO 13818-1 MPEG Transport Stream input" )
- ADD_CAPABILITY( INPUT, 150 )
+ ADD_CAPABILITY( DEMUX, 160 )
ADD_SHORTCUT( "ts" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
- _M( input_getfunctions )( &p_module->p_functions->input );
+ input_getfunctions( &p_module->p_functions->demux );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.demux
+ input.pf_init = TSInit;
+ input.pf_end = TSEnd;
+ input.pf_demux = TSDemux;
+ input.pf_rewind = NULL;
+#undef input
+}
+
+/*****************************************************************************
+ * TSInit: initializes TS structures
+ *****************************************************************************/
+static int TSInit( input_thread_t * p_input )
+{
+ es_descriptor_t * p_pat_es;
+ es_ts_data_t * p_demux_data;
+ stream_ts_data_t * p_stream_data;
+ byte_t * p_peek;
+
+ /* Initialize access plug-in structures. */
+ if( p_input->i_mtu == 0 )
+ {
+ /* Improve speed. */
+ p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
+ }
+
+ /* Have a peep at the show. */
+ if( input_Peek( p_input, &p_peek, 1 ) < 1 )
+ {
+ intf_ErrMsg( "input error: cannot peek() (mpeg_ts)" );
+ return( -1 );
+ }
+
+ if( *p_peek != TS_SYNC_CODE )
+ {
+ if( p_input->psz_demux && strncmp( p_input->psz_demux, "ts", 3 ) )
+ {
+ /* User forced */
+ intf_ErrMsg( "input error: this doesn't seem like a TS stream, continuing" );
+ }
+ else
+ {
+ intf_WarnMsg( 2, "input: TS plug-in discarded (no sync)" );
+ return( -1 );
+ }
+ }
+
+ /* Adapt the bufsize for our only use. */
+ if( p_input->i_mtu != 0 )
+ {
+ /* Have minimum granularity to avoid bottlenecks at the input level. */
+ p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
+ }
+
+ if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
+ {
+ return( -1 );
+ }
+
+ p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
+ p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
+
+ /* We'll have to catch the PAT in order to continue
+ * Then the input will catch the PMT and then the others ES
+ * The PAT es is indepedent of any program. */
+ p_pat_es = input_AddES( p_input, NULL,
+ 0x00, sizeof( es_ts_data_t ) );
+ p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
+ p_demux_data->b_psi = 1;
+ p_demux_data->i_psi_type = PSI_IS_PAT;
+ p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
+ p_demux_data->p_psi_section->b_is_complete = 1;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * TSEnd: frees unused data
+ *****************************************************************************/
+static void TSEnd( input_thread_t * p_input )
+{
+}
+
+/*****************************************************************************
+ * TSDemux: reads and demuxes data packets
+ *****************************************************************************
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
+ *****************************************************************************/
+#define PEEK( SIZE ) \
+ i_error = input_Peek( p_input, &p_peek, SIZE ); \
+ if( i_error == -1 ) \
+ { \
+ return( -1 ); \
+ } \
+ else if( i_error < SIZE ) \
+ { \
+ /* EOF */ \
+ return( 0 ); \
+ }
+
+static int TSDemux( input_thread_t * p_input )
+{
+ int i_read_once = (p_input->i_mtu ?
+ p_input->i_bufsize / TS_PACKET_SIZE :
+ TS_READ_ONCE);
+ int i;
+
+ for( i = 0; i < i_read_once; i++ )
+ {
+ data_packet_t * p_data;
+ ssize_t i_read, i_error;
+ byte_t * p_peek;
+
+ PEEK( 1 );
+
+ if( *p_peek != TS_SYNC_CODE )
+ {
+ intf_WarnMsg( 3, "input warning: garbage at input (%x)", *p_peek );
+
+ if( p_input->i_mtu )
+ {
+ /* Try to resync on next packet. */
+ PEEK( TS_PACKET_SIZE );
+ p_input->p_current_data += TS_PACKET_SIZE;
+ }
+ else
+ {
+ /* Move forward until we find 0x47 (and hope it's the good
+ * one... FIXME) */
+ while( *p_peek != TS_SYNC_CODE )
+ {
+ p_input->p_current_data++;
+ PEEK( 1 );
+ }
+ }
+ }
+
+ i_read = input_SplitBuffer( p_input, &p_data, TS_PACKET_SIZE );
+
+ if( i_read <= 0 )
+ {
+ return( i_read );
+ }
+
+ input_DemuxTS( p_input, p_data );
+ }
+
+ return( i_read_once );
+}
+
--- /dev/null
+.dep
+*.lo
+*.o.*
+*.lo.*
--- /dev/null
+ipv4_SOURCES = ipv4.c
--- /dev/null
+/*****************************************************************************
+ * ipv4.c: IPv4 network abstraction layer
+ *****************************************************************************
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: ipv4.c,v 1.1 2002/03/01 00:33:18 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <videolan/vlc.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#elif defined( _MSC_VER ) && defined( _WIN32 )
+# include <io.h>
+#endif
+
+#ifdef WIN32
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#elif !defined( SYS_BEOS ) && !defined( SYS_NTO )
+# include <netdb.h> /* hostent ... */
+# include <sys/socket.h>
+# include <netinet/in.h>
+# ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h> /* inet_ntoa(), inet_aton() */
+# endif
+#endif
+
+#include "network.h"
+
+/* Default MTU used for UDP socket. FIXME: we should issue some ioctl()
+ * call to get that value from the interface driver. */
+#define DEFAULT_MTU 1500
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void getfunctions( function_list_t * );
+static int NetworkOpen( struct network_socket_s * );
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+MODULE_CONFIG_STOP
+
+MODULE_INIT_START
+ SET_DESCRIPTION( "IPv4 network abstraction layer" )
+ ADD_CAPABILITY( NETWORK, 50 )
+ ADD_SHORTCUT( "ipv4" )
+MODULE_INIT_STOP
+
+MODULE_ACTIVATE_START
+ getfunctions( &p_module->p_functions->network );
+MODULE_ACTIVATE_STOP
+
+MODULE_DEACTIVATE_START
+MODULE_DEACTIVATE_STOP
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void getfunctions( function_list_t * p_function_list )
+{
+#define f p_function_list->functions.network
+ f.pf_open = NetworkOpen;
+#undef f
+}
+
+/*****************************************************************************
+ * BuildAddr: utility function to build a struct sockaddr_in
+ *****************************************************************************/
+static int BuildAddr( struct sockaddr_in * p_socket,
+ const char * psz_address, int i_port )
+{
+ /* Reset struct */
+ memset( p_socket, 0, sizeof( struct sockaddr_in ) );
+ p_socket->sin_family = AF_INET; /* family */
+ p_socket->sin_port = htons( i_port );
+ if( psz_address == NULL )
+ {
+ p_socket->sin_addr.s_addr = INADDR_ANY;
+ }
+ else
+ {
+ struct hostent * p_hostent;
+
+ /* Try to convert address directly from in_addr - this will work if
+ * psz_address is dotted decimal. */
+#ifdef HAVE_ARPA_INET_H
+ if( !inet_aton( psz_address, &p_socket->sin_addr ) )
+#else
+ if( (p_socket->sin_addr.s_addr = inet_addr( psz_address )) == -1 )
+#endif
+ {
+ /* We have a fqdn, try to find its address */
+ if ( (p_hostent = gethostbyname( psz_address )) == NULL )
+ {
+ intf_ErrMsg( "BuildLocalAddr: unknown host %s", psz_address );
+ return( -1 );
+ }
+
+ /* Copy the first address of the host in the socket address */
+ memcpy( &p_socket->sin_addr, p_hostent->h_addr_list[0],
+ p_hostent->h_length );
+ }
+ }
+ return( 0 );
+}
+
+/*****************************************************************************
+ * OpenUDP: open a UDP socket
+ *****************************************************************************
+ * psz_bind_addr, i_bind_port : address and port used for the bind()
+ * system call. If psz_bind_addr == NULL, the socket is bound to
+ * INADDR_ANY and broadcast reception is enabled. If i_bind_port == 0,
+ * 1234 is used. If psz_bind_addr is a multicast (class D) address,
+ * join the multicast group.
+ * psz_server_addr, i_server_port : address and port used for the connect()
+ * system call. It can avoid receiving packets from unauthorized IPs.
+ * Its use leads to great confusion and is currently discouraged.
+ * This function returns -1 in case of error.
+ *****************************************************************************/
+static int OpenUDP( network_socket_t * p_socket )
+{
+ char * psz_bind_addr = p_socket->psz_bind_addr;
+ int i_bind_port = p_socket->i_bind_port;
+ char * psz_server_addr = p_socket->psz_server_addr;
+ int i_server_port = p_socket->i_server_port;
+
+ int i_handle, i_opt, i_opt_size;
+ struct sockaddr_in sock;
+
+ if( i_bind_port == 0 )
+ {
+ i_bind_port = config_GetIntVariable( INPUT_PORT_VAR );
+ }
+
+ /* Open a SOCK_DGRAM (UDP) socket, in the AF_INET domain, automatic (0)
+ * protocol */
+ if( (i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 )
+ {
+ intf_ErrMsg( "ipv4 error: cannot create socket (%s)", strerror(errno) );
+ return( -1 );
+ }
+
+ /* We may want to reuse an already used socket */
+ i_opt = 1;
+ if( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR,
+ (void *) &i_opt, sizeof( i_opt ) ) == -1 )
+ {
+ intf_ErrMsg( "ipv4 error: cannot configure socket (SO_REUSEADDR: %s)",
+ strerror(errno));
+ close( i_handle );
+ return( -1 );
+ }
+
+ /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) to avoid
+ * packet loss caused by scheduling problems */
+ i_opt = 0x80000;
+ if( setsockopt( i_handle, SOL_SOCKET, SO_RCVBUF,
+ (void *) &i_opt, sizeof( i_opt ) ) == -1 )
+ {
+ intf_WarnMsg( 1,
+ "ipv4 warning: cannot configure socket (SO_RCVBUF: %s)",
+ strerror(errno));
+ }
+
+ /* Check if we really got what we have asked for, because Linux, etc.
+ * will silently limit the max buffer size to net.core.rmem_max which
+ * is typically only 65535 bytes */
+ i_opt = 0;
+ i_opt_size = sizeof( i_opt );
+ if( getsockopt( i_handle, SOL_SOCKET, SO_RCVBUF,
+ (void*) &i_opt, &i_opt_size ) == -1 )
+ {
+ intf_WarnMsg( 1, "ipv4 warning: cannot query socket (SO_RCVBUF: %s)",
+ strerror(errno));
+ }
+ else if( i_opt < 0x80000 )
+ {
+ intf_WarnMsg( 1, "ipv4 warning: socket buffer size is 0x%x"
+ " instead of 0x%x", i_opt, 0x80000 );
+ }
+
+ /* Build the local socket */
+ if ( BuildAddr( &sock, psz_bind_addr, i_bind_port ) == -1 )
+ {
+ close( i_handle );
+ return( -1 );
+ }
+
+ /* Bind it */
+ if( bind( i_handle, (struct sockaddr *)&sock, sizeof( sock ) ) < 0 )
+ {
+ intf_ErrMsg( "ipv4 error: cannot bind socket (%s)", strerror(errno) );
+ close( i_handle );
+ return( -1 );
+ }
+
+ /* Allow broadcast reception if we bound on INADDR_ANY */
+ if( psz_bind_addr == NULL )
+ {
+ i_opt = 1;
+ if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST,
+ (void*) &i_opt, sizeof( i_opt ) ) == -1 )
+ {
+ intf_WarnMsg( 1,
+ "ipv4 warning: cannot configure socket (SO_BROADCAST: %s)",
+ strerror(errno));
+ }
+ }
+
+ /* Join the multicast group if the socket is a multicast address */
+#ifndef IN_MULTICAST
+# define IN_MULTICAST(a) IN_CLASSD(a)
+#endif
+ if( IN_MULTICAST( ntohl(sock.sin_addr.s_addr) ) )
+ {
+ struct ip_mreq imr;
+
+ imr.imr_interface.s_addr = INADDR_ANY;
+ imr.imr_multiaddr.s_addr = sock.sin_addr.s_addr;
+ if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char*)&imr, sizeof(struct ip_mreq) ) == -1 )
+ {
+ intf_ErrMsg( "ipv4 error: failed to join IP multicast group (%s)",
+ strerror(errno) );
+ close( i_handle );
+ return( -1 );
+ }
+ }
+
+ if( psz_server_addr != NULL )
+ {
+ /* Build socket for remote connection */
+ if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
+ {
+ intf_ErrMsg( "ipv4 error: cannot build remote address" );
+ close( i_handle );
+ return( -1 );
+ }
+
+ /* Connect the socket */
+ if( connect( i_handle, (struct sockaddr *) &sock,
+ sizeof( sock ) ) == (-1) )
+ {
+ intf_ErrMsg( "ipv4 error: cannot connect socket (%s)",
+ strerror(errno) );
+ close( i_handle );
+ return( -1 );
+ }
+ }
+
+ p_socket->i_handle = i_handle;
+ p_socket->i_mtu = DEFAULT_MTU;
+ return( 0 );
+}
+
+/*****************************************************************************
+ * OpenTCP: open a TCP socket
+ *****************************************************************************
+ * psz_server_addr, i_server_port : address and port used for the connect()
+ * system call. If i_server_port == 0, 80 is used.
+ * Other parameters are ignored.
+ * This function returns -1 in case of error.
+ *****************************************************************************/
+static int OpenTCP( network_socket_t * p_socket )
+{
+ char * psz_server_addr = p_socket->psz_server_addr;
+ int i_server_port = p_socket->i_server_port;
+
+ int i_handle;
+ struct sockaddr_in sock;
+
+ if( i_server_port == 0 )
+ {
+ i_server_port = 80;
+ }
+
+ /* Open a SOCK_STREAM (TCP) socket, in the AF_INET domain, automatic (0)
+ * protocol */
+ if( (i_handle = socket( AF_INET, SOCK_STREAM, 0 )) == -1 )
+ {
+ intf_ErrMsg( "ipv4 error: cannot create socket (%s)", strerror(errno) );
+ return( -1 );
+ }
+
+ /* Build remote address */
+ if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
+ {
+ close( i_handle );
+ return( -1 );
+ }
+
+ /* Connect the socket */
+ if( connect( i_handle, (struct sockaddr *) &sock,
+ sizeof( sock ) ) == (-1) )
+ {
+ intf_ErrMsg( "ipv4 error: cannot connect socket (%s)",
+ strerror(errno) );
+ close( i_handle );
+ return( -1 );
+ }
+
+ p_socket->i_handle = i_handle;
+ p_socket->i_mtu = 0; /* There is no MTU notion in TCP */
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * NetworkOpen: wrapper around OpenUDP and OpenTCP
+ *****************************************************************************/
+static int NetworkOpen( network_socket_t * p_socket )
+{
+ if( p_socket->i_type == NETWORK_UDP )
+ {
+ return OpenUDP( p_socket );
+ }
+ else
+ {
+ return OpenTCP( p_socket );
+ }
+}
* decoders.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input.c,v 1.179 2002/02/27 04:49:55 sam Exp $
+ * $Id: input.c,v 1.180 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
+ * Alexis Guillard <alexis.guillard@bt.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <videolan/vlc.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#elif defined( _MSC_VER ) && defined( _WIN32 )
-# include <io.h>
-#endif
-
#include <string.h>
#include <errno.h>
-#ifdef STRNCASECMP_IN_STRINGS_H
-# include <strings.h>
-#endif
-
-#ifdef WIN32
-# include <winsock2.h>
-# include <ws2tcpip.h>
-#elif defined( SYS_NTO )
- /* unsupported */
-#else
-# include <netdb.h> /* hostent ... */
-# include <sys/socket.h>
-# include <netinet/in.h>
-# ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h> /* inet_ntoa(), inet_aton() */
-# endif
-#endif
-
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
static void DestroyThread ( input_thread_t *p_input );
static void EndThread ( input_thread_t *p_input );
-static void FileOpen ( input_thread_t *p_input );
-static void StdOpen ( input_thread_t *p_input );
-static void FileClose ( input_thread_t *p_input );
-#if !defined( SYS_NTO )
-static void NetworkOpen ( input_thread_t *p_input );
-static void HTTPOpen ( input_thread_t *p_input );
-static void NetworkClose ( input_thread_t *p_input );
-#endif
-
/*****************************************************************************
* input_InitBank: initialize the input bank.
*****************************************************************************/
p_input->b_eof = 0;
/* Set target */
- p_input->p_source = p_item->psz_name;
+ p_input->psz_source = strdup( p_item->psz_name );
/* Set status */
p_input->i_status = THREAD_CREATE;
p_input->c_loops = 0;
p_input->stream.c_packets_read = 0;
p_input->stream.c_packets_trashed = 0;
- p_input->p_stream = NULL;
/* Set locks. */
vlc_mutex_init( &p_input->stream.stream_lock );
VOUT_GRAYSCALE_VAR );
p_input->stream.control.i_smp = config_GetIntVariable( VDEC_SMP_VAR );
- intf_WarnMsg( 1, "input: playlist item `%s'", p_input->p_source );
+ intf_WarnMsg( 1, "input: playlist item `%s'", p_input->psz_source );
/* Create thread. */
if( vlc_thread_create( &p_input->thread_id, "input",
while( !p_input->b_die && !p_input->b_error && !p_input->b_eof )
{
- data_packet_t * p_data;
- int i_count, i;
+ int i, i_count;
p_input->c_loops++;
{
if( p_input->stream.b_seekable && p_input->pf_seek != NULL )
{
- p_input->pf_seek( p_input,
- p_input->stream.p_selected_area->i_seek );
+ off_t i_new_pos = p_input->stream.p_selected_area->i_seek;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ p_input->pf_seek( p_input, i_new_pos );
+ vlc_mutex_lock( &p_input->stream.stream_lock );
for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
{
/* Reinitialize synchro. */
p_pgrm->i_synchro_state = SYNCHRO_REINIT;
}
+
+ /* Reinitialize buffer manager. */
+ input_AccessReinit( p_input );
}
p_input->stream.p_selected_area->i_seek = NO_SEEK;
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
- i_count = p_input->pf_read( p_input, &p_data );
-
- /* Demultiplex read packets. */
- while( p_data != NULL )
- {
- data_packet_t * p_next = p_data->p_next;
- p_data->p_next = NULL;
-
- p_input->stream.c_packets_read++;
- p_input->pf_demux( p_input, p_data );
-
- p_data = p_next;
- }
+ /* Read and demultiplex some data. */
+ i_count = p_input->pf_demux( p_input );
if( i_count == 0 && p_input->stream.b_seekable )
{
*****************************************************************************/
static int InitThread( input_thread_t * p_input )
{
- char *psz_name;
+ /* Parse source string. Syntax : [[<access>][/<demux>]:][<source>] */
+ char * psz_parser = p_input->psz_source;
- /* Find appropriate module. */
- psz_name = config_GetPszVariable( INPUT_METHOD_VAR );
- p_input->p_input_module = module_Need( MODULE_CAPABILITY_INPUT, psz_name,
- (void *)p_input );
+ /* Skip the plug-in names */
+ while( *psz_parser && *psz_parser != ':' )
+ {
+ psz_parser++;
+ }
- if( psz_name ) free( psz_name );
- if( p_input->p_input_module == NULL )
+ if( !*psz_parser )
{
- intf_ErrMsg( "input error: no suitable input module for `%s'",
- p_input->p_source );
- return( -1 );
+ p_input->psz_access = p_input->psz_demux = NULL;
+ p_input->psz_name = p_input->psz_source;
}
+ else
+ {
+ *psz_parser++ = '\0';
-#define f p_input->p_input_module->p_functions->input.functions.input
- p_input->pf_probe = f.pf_probe;
- p_input->pf_init = f.pf_init;
- p_input->pf_end = f.pf_end;
- p_input->pf_read = f.pf_read;
- p_input->pf_set_area = f.pf_set_area;
- p_input->pf_set_program = f.pf_set_program;
- p_input->pf_demux = f.pf_demux;
- p_input->pf_new_packet = f.pf_new_packet;
- p_input->pf_new_pes = f.pf_new_pes;
- p_input->pf_delete_packet = f.pf_delete_packet;
- p_input->pf_delete_pes = f.pf_delete_pes;
- p_input->pf_rewind = f.pf_rewind;
- p_input->pf_seek = f.pf_seek;
+ p_input->psz_name = psz_parser;
- if( f.pf_open != NULL )
- {
- f.pf_open( p_input );
+ /* Come back to parse the access and demux plug-ins */
+ psz_parser = p_input->psz_source;
+ if( !*psz_parser )
+ {
+ /* No access */
+ p_input->psz_access = NULL;
+ }
+ else if( *psz_parser == '/' )
+ {
+ /* No access */
+ p_input->psz_access = NULL;
+ psz_parser++;
+ }
+ else
+ {
+ p_input->psz_access = psz_parser;
+
+ while( *psz_parser && *psz_parser != '/' )
+ {
+ psz_parser++;
+ }
+
+ if( *psz_parser == '/' )
+ {
+ *psz_parser++ = '\0';
+ }
+ }
+
+ if( !*psz_parser )
+ {
+ /* No demux */
+ p_input->psz_demux = NULL;
+ }
+ else
+ {
+ p_input->psz_demux = psz_parser;
+ }
}
-#if !defined( SYS_NTO )
- /* FIXME : this is waaaay too kludgy */
- else if( ( strlen( p_input->p_source ) >= 10
- && !strncasecmp( p_input->p_source, "udpstream:", 10 ) )
- || ( strlen( p_input->p_source ) >= 4
- && !strncasecmp( p_input->p_source, "udp:", 4 ) ) )
+
+ intf_WarnMsg( 2, "input: access=%s demux=%s name=%s",
+ p_input->psz_access, p_input->psz_demux,
+ p_input->psz_name );
+
+ if( input_AccessInit( p_input ) == -1 )
{
- /* Network stream */
- NetworkOpen( p_input );
- p_input->stream.i_method = INPUT_METHOD_NETWORK;
+ return( -1 );
}
- else if( ( strlen( p_input->p_source ) > 5 )
- && !strncasecmp( p_input->p_source, "http:", 5 ) )
+
+ /* Find and open appropriate access plug-in. */
+ p_input->p_access_module = module_Need( MODULE_CAPABILITY_ACCESS,
+ p_input->psz_access,
+ (void *)p_input );
+
+ if( p_input->p_access_module == NULL )
{
- /* HTTP stream */
- HTTPOpen( p_input );
- p_input->stream.i_method = INPUT_METHOD_NETWORK;
+ intf_ErrMsg( "input error: no suitable access plug-in for `%s/%s:%s'",
+ p_input->psz_access, p_input->psz_demux,
+ p_input->psz_name );
+ return( -1 );
}
-#endif
- else if( ( strlen( p_input->p_source ) == 1 )
- && *p_input->p_source == '-' )
+
+#define f p_input->p_access_module->p_functions->access.functions.access
+ p_input->pf_open = f.pf_open;
+ p_input->pf_close = f.pf_close;
+ p_input->pf_read = f.pf_read;
+ p_input->pf_set_area = f.pf_set_area;
+ p_input->pf_set_program = f.pf_set_program;
+ p_input->pf_seek = f.pf_seek;
+#undef f
+
+ /* Waiting for stream. */
+ if( p_input->i_mtu )
{
- /* Stdin */
- StdOpen( p_input );
+ p_input->i_bufsize = p_input->i_mtu;
}
else
{
- /* File input */
- FileOpen( p_input );
- p_input->stream.i_method = INPUT_METHOD_FILE;
+ p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
}
-#undef f
- if( p_input->b_error )
+ if( p_input->p_current_data == NULL )
{
- /* We barfed -- exit nicely */
- module_Unneed( p_input->p_input_module );
- return( -1 );
+ while( !input_FillBuffer( p_input ) )
+ {
+ if( p_input->b_die || p_input->b_error )
+ {
+ module_Unneed( p_input->p_access_module );
+ return( -1 );
+ }
+ }
}
- p_input->pf_init( p_input );
+ /* Find and open appropriate demux plug-in. */
+ p_input->p_demux_module = module_Need( MODULE_CAPABILITY_DEMUX,
+ p_input->psz_demux,
+ (void *)p_input );
- if( p_input->b_error )
+ if( p_input->p_demux_module == NULL )
{
- /* We barfed -- exit nicely */
- CloseThread( p_input );
- module_Unneed( p_input->p_input_module );
+ intf_ErrMsg( "input error: no suitable demux plug-in for `%s/%s:%s'",
+ p_input->psz_access, p_input->psz_demux,
+ p_input->psz_name );
+ module_Unneed( p_input->p_access_module );
return( -1 );
}
+#define f p_input->p_demux_module->p_functions->demux.functions.demux
+ p_input->pf_init = f.pf_init;
+ p_input->pf_end = f.pf_end;
+ p_input->pf_demux = f.pf_demux;
+ p_input->pf_rewind = f.pf_rewind;
+#undef f
+
return( 0 );
}
/* Free demultiplexer's data */
p_input->pf_end( p_input );
+ module_Unneed( p_input->p_demux_module );
- /* Close the input method */
+ /* Close the access plug-in */
CloseThread( p_input );
-
- /* Release modules */
- module_Unneed( p_input->p_input_module );
}
/*****************************************************************************
*****************************************************************************/
static void CloseThread( input_thread_t * p_input )
{
-#define f p_input->p_input_module->p_functions->input.functions.input
+ p_input->pf_close( p_input );
+ module_Unneed( p_input->p_access_module );
- if( f.pf_close != NULL )
- {
- f.pf_close( p_input );
- }
-#if !defined( SYS_NTO )
- /* Close stream */
- else if( ( strlen( p_input->p_source ) > 10
- && !strncasecmp( p_input->p_source, "udpstream:", 10 ) )
- || ( strlen( p_input->p_source ) > 4
- && !strncasecmp( p_input->p_source, "udp:", 4 ) ) )
- {
- NetworkClose( p_input );
- }
- else if( ( strlen( p_input->p_source ) > 5 )
- && !strncasecmp( p_input->p_source, "http:", 5 ) )
- {
- NetworkClose( p_input );
- }
-#endif
- else
- {
- FileClose( p_input );
- }
-#undef f
+ input_AccessEnd( p_input );
+
+ free( p_input->psz_source );
}
/*****************************************************************************
p_input->i_status = THREAD_OVER;
}
-/*****************************************************************************
- * StdOpen : open standard input
- *****************************************************************************/
-static void StdOpen( input_thread_t * p_input )
-{
- vlc_mutex_lock( &p_input->stream.stream_lock );
-
- /* Suppose we can control the pace - this won't work in some cases ! */
- p_input->stream.b_pace_control = 1;
-
- p_input->stream.b_seekable = 0;
- p_input->stream.p_selected_area->i_size = 0;
- p_input->stream.p_selected_area->i_tell = 0;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
- intf_WarnMsg( 2, "input: opening stdin" );
- p_input->i_handle = 0;
-}
-
-/*****************************************************************************
- * FileOpen : open a file descriptor
- *****************************************************************************/
-static void FileOpen( input_thread_t * p_input )
-{
- struct stat stat_info;
- int i_stat;
-
- char *psz_name = p_input->p_source;
-
- if( ( i_stat = stat( psz_name, &stat_info ) ) == (-1) )
- {
- int i_size = strlen( psz_name );
-
- if( ( i_size > 8 )
- && !strncasecmp( psz_name, "dvdread:", 8 ) )
- {
- /* get rid of the 'dvdread:' stuff and try again */
- psz_name += 8;
- i_stat = stat( psz_name, &stat_info );
- }
- else if( ( i_size > 4 )
- && !strncasecmp( psz_name, "dvd:", 4 ) )
- {
- /* get rid of the 'dvd:' stuff and try again */
- psz_name += 4;
- i_stat = stat( psz_name, &stat_info );
- }
- else if( ( i_size > 4 )
- && !strncasecmp( psz_name, "vcd:", 4 ) )
- {
- /* get rid of the 'vcd:' stuff and try again */
- psz_name += 4;
- i_stat = stat( psz_name, &stat_info );
- }
- else if( ( i_size > 5 )
- && !strncasecmp( psz_name, "file:", 5 ) )
- {
- /* get rid of the 'file:' stuff and try again */
- psz_name += 5;
- i_stat = stat( psz_name, &stat_info );
- }
-
- if( i_stat == (-1) )
- {
- intf_ErrMsg( "input error: cannot stat() file `%s' (%s)",
- psz_name, strerror(errno));
- p_input->b_error = 1;
- return;
- }
- }
-
- vlc_mutex_lock( &p_input->stream.stream_lock );
-
- /* If we are here we can control the pace... */
- p_input->stream.b_pace_control = 1;
-
- if( S_ISREG(stat_info.st_mode) || S_ISCHR(stat_info.st_mode)
- || S_ISBLK(stat_info.st_mode) )
- {
- p_input->stream.b_seekable = 1;
- p_input->stream.p_selected_area->i_size = stat_info.st_size;
- }
- else if( S_ISFIFO(stat_info.st_mode)
-#if !defined( SYS_BEOS ) && !defined( WIN32 )
- || S_ISSOCK(stat_info.st_mode)
-#endif
- )
- {
- p_input->stream.b_seekable = 0;
- p_input->stream.p_selected_area->i_size = 0;
- }
- else
- {
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- intf_ErrMsg( "input error: unknown file type for `%s'",
- psz_name );
- p_input->b_error = 1;
- return;
- }
-
- p_input->stream.p_selected_area->i_tell = 0;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
- intf_WarnMsg( 2, "input: opening file `%s'", p_input->p_source );
- if( (p_input->i_handle = open( psz_name,
- /*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
- {
- intf_ErrMsg( "input error: cannot open file (%s)", strerror(errno) );
- p_input->b_error = 1;
- return;
- }
-
-}
-
-/*****************************************************************************
- * FileClose : close a file descriptor
- *****************************************************************************/
-static void FileClose( input_thread_t * p_input )
-{
- intf_WarnMsg( 2, "input: closing file `%s'", p_input->p_source );
-
- close( p_input->i_handle );
-
- return;
-}
-
-#if !defined( SYS_NTO )
-/*****************************************************************************
- * NetworkOpen : open a network socket
- *****************************************************************************/
-static void NetworkOpen( input_thread_t * p_input )
-{
- char *psz_server = NULL;
- char *psz_bind = NULL;
- int i_server_port = 0;
- int i_bind_port = 0;
- int i_opt;
- int i_opt_size;
- struct sockaddr_in sock;
-
- /* Get the remote server. Syntax is :
- * udp[stream]:[/][/][serveraddr[:serverport]][@[bindaddr]:[bindport]] */
- if( p_input->p_source != NULL )
- {
- char * psz_parser = p_input->p_source;
- char * psz_server_port = NULL;
- char * psz_bind_port = NULL;
-
- /* Skip the protocol name */
- while( *psz_parser && *psz_parser != ':' )
- {
- psz_parser++;
- }
-
- /* Skip the "://" part */
- while( *psz_parser && (*psz_parser == ':' || *psz_parser == '/') )
- {
- psz_parser++;
- }
-
- if( *psz_parser && *psz_parser != '@' )
- {
- /* Found server */
- psz_server = psz_parser;
-
- while( *psz_parser && *psz_parser != ':' && *psz_parser != '@' )
- {
- psz_parser++;
- }
-
- if( *psz_parser == ':' )
- {
- /* Found server port */
- *psz_parser = '\0'; /* Terminate server name */
- psz_parser++;
- psz_server_port = psz_parser;
-
- while( *psz_parser && *psz_parser != '@' )
- {
- psz_parser++;
- }
- }
- }
-
- if( *psz_parser == '@' )
- {
- /* Found bind address or bind port */
- *psz_parser = '\0'; /* Terminate server port or name if necessary */
- psz_parser++;
-
- if( *psz_parser && *psz_parser != ':' )
- {
- /* Found bind address */
- psz_bind = psz_parser;
-
- while( *psz_parser && *psz_parser != ':' )
- {
- psz_parser++;
- }
- }
-
- if( *psz_parser == ':' )
- {
- /* Found bind port */
- *psz_parser = '\0'; /* Terminate bind address if necessary */
- psz_parser++;
-
- psz_bind_port = psz_parser;
- }
- }
-
- /* Convert ports format */
- if( psz_server_port != NULL )
- {
- i_server_port = strtol( psz_server_port, &psz_parser, 10 );
- if( *psz_parser )
- {
- intf_ErrMsg( "input error: cannot parse server port near %s",
- psz_parser );
- p_input->b_error = 1;
- return;
- }
- }
-
- if( psz_bind_port != NULL )
- {
- i_bind_port = strtol( psz_bind_port, &psz_parser, 10 );
- if( *psz_parser )
- {
- intf_ErrMsg( "input error: cannot parse bind port near %s",
- psz_parser );
- p_input->b_error = 1;
- return;
- }
- }
- }
- else
- {
- /* This is required or NetworkClose will never be called */
- p_input->p_source = "ts: network input";
- }
-
- /* Check that we got a valid port */
- if( i_bind_port == 0 )
- {
- i_bind_port = config_GetIntVariable( INPUT_PORT_VAR );
- }
-
- intf_WarnMsg( 2, "input: server=%s:%d local=%s:%d",
- psz_server, i_server_port, psz_bind, i_bind_port );
-
- /* Open a SOCK_DGRAM (UDP) socket, in the AF_INET domain, automatic (0)
- * protocol */
- p_input->i_handle = socket( AF_INET, SOCK_DGRAM, 0 );
- if( p_input->i_handle == -1 )
- {
- intf_ErrMsg( "input error: can't create socket (%s)", strerror(errno) );
- p_input->b_error = 1;
- return;
- }
-
- /* We may want to reuse an already used socket */
- i_opt = 1;
- if( setsockopt( p_input->i_handle, SOL_SOCKET, SO_REUSEADDR,
- (void *) &i_opt, sizeof( i_opt ) ) == -1 )
- {
- intf_ErrMsg( "input error: can't configure socket (SO_REUSEADDR: %s)",
- strerror(errno));
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) to avoid
- * packet loss caused by scheduling problems */
- i_opt = 0x80000;
- if( setsockopt( p_input->i_handle, SOL_SOCKET, SO_RCVBUF,
- (void *) &i_opt, sizeof( i_opt ) ) == -1 )
- {
- intf_WarnMsg( 1, "input warning: can't configure socket (SO_RCVBUF: %s)",
- strerror(errno));
- }
-
- /* Check if we really got what we have asked for, because Linux, etc.
- * will silently limit the max buffer size to net.core.rmem_max which
- * is typically only 65535 bytes */
- i_opt = 0;
- i_opt_size = sizeof( i_opt );
- if( getsockopt( p_input->i_handle, SOL_SOCKET, SO_RCVBUF,
- (void*) &i_opt, &i_opt_size ) == -1 )
- {
- intf_WarnMsg( 1, "input warning: can't query socket (SO_RCVBUF: %s)",
- strerror(errno));
- }
- else if( i_opt < 0x80000 )
- {
- intf_WarnMsg( 1, "input warning: socket buffer size is 0x%x"
- " instead of 0x%x", i_opt, 0x80000 );
- }
-
- /* Build the local socket */
-
-/* As we have a problem with multicast under win32, let's bind on INADDR_ANY */
-
-#ifdef WIN32
- if ( network_BuildAddr( &sock, NULL, i_bind_port ) == -1 )
-#else
- if ( network_BuildAddr( &sock, psz_bind, i_bind_port ) == -1 )
-#endif
- {
- intf_ErrMsg( "input error: can't build local address" );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Bind it */
- if( bind( p_input->i_handle, (struct sockaddr *)&sock,
- sizeof( sock ) ) < 0 )
- {
- intf_ErrMsg( "input error: can't bind socket (%s)", strerror(errno) );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Allow broadcast reception if we bound on INADDR_ANY */
- if( psz_bind == NULL )
- {
- i_opt = 1;
- if( setsockopt( p_input->i_handle, SOL_SOCKET, SO_BROADCAST,
- (void*) &i_opt, sizeof( i_opt ) ) == -1 )
- {
- intf_WarnMsg( 1, "input warning: can't configure socket (SO_BROADCAST: %s)",
- strerror(errno));
- }
- }
-
- /* Join the multicast group if the socket is a multicast address */
-#ifndef IN_MULTICAST
-# define IN_MULTICAST(a) IN_CLASSD(a)
-#endif
-
-#ifdef WIN32
- if( IN_MULTICAST( ntohl( inet_addr (psz_bind) ) ) )
- {
- struct ip_mreq imr;
- imr.imr_interface.s_addr = INADDR_ANY;
- imr.imr_multiaddr.s_addr = inet_addr (psz_bind) ;
-#else
- if( IN_MULTICAST( ntohl(sock.sin_addr.s_addr) ) )
- {
- struct ip_mreq imr;
-
- imr.imr_interface.s_addr = INADDR_ANY;
- imr.imr_multiaddr.s_addr = sock.sin_addr.s_addr;
-#endif
- if( setsockopt( p_input->i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (char*)&imr, sizeof(struct ip_mreq) ) == -1 )
- {
- intf_ErrMsg( "input error: failed to join IP multicast group (%s)",
- strerror(errno) );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
- }
-
- if( psz_server != NULL )
- {
- /* Build socket for remote connection */
- if ( network_BuildAddr( &sock, psz_server, i_server_port ) == -1 )
- {
- intf_ErrMsg( "input error: can't build remote address" );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Connect the socket */
- if( connect( p_input->i_handle, (struct sockaddr *) &sock,
- sizeof( sock ) ) == (-1) )
- {
- intf_ErrMsg( "input error: can't connect socket (%s)",
- strerror(errno) );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
- }
-
- p_input->stream.b_pace_control = 0;
- p_input->stream.b_seekable = 0;
-
- intf_WarnMsg( 3, "input: successfully opened network mode" );
-
- return;
-}
-
-/*****************************************************************************
- * NetworkClose : close a network socket
- *****************************************************************************/
-static void NetworkClose( input_thread_t * p_input )
-{
- intf_WarnMsg( 2, "input: closing network target `%s'", p_input->p_source );
-
- close( p_input->i_handle );
-}
-
-/*****************************************************************************
- * HTTPOpen : make an HTTP request
- *****************************************************************************/
-static void HTTPOpen( input_thread_t * p_input )
-{
- char *psz_server = NULL;
- char *psz_path = NULL;
- char *psz_proxy;
- int i_port = 0;
- int i_opt;
- struct sockaddr_in sock;
- char psz_buffer[256];
-
- /* Get the remote server */
- if( p_input->p_source != NULL )
- {
- psz_server = p_input->p_source;
-
- /* Skip the protocol name */
- while( *psz_server && *psz_server != ':' )
- {
- psz_server++;
- }
-
- /* Skip the "://" part */
- while( *psz_server && (*psz_server == ':' || *psz_server == '/') )
- {
- psz_server++;
- }
-
- /* Found a server name */
- if( *psz_server )
- {
- char *psz_port = psz_server;
-
- /* Skip the hostname part */
- while( *psz_port && *psz_port != ':' && *psz_port != '/' )
- {
- psz_port++;
- }
-
- /* Found a port name */
- if( *psz_port )
- {
- if( *psz_port == ':' )
- {
- /* Replace ':' with '\0' */
- *psz_port = '\0';
- psz_port++;
- }
-
- psz_path = psz_port;
- while( *psz_path && *psz_path != '/' )
- {
- psz_path++;
- }
-
- if( *psz_path )
- {
- *psz_path = '\0';
- psz_path++;
- }
- else
- {
- psz_path = NULL;
- }
-
- if( *psz_port != '\0' )
- {
- i_port = atoi( psz_port );
- }
- }
- }
- else
- {
- psz_server = NULL;
- }
- }
-
- /* Check that we got a valid server */
- if( psz_server == NULL )
- {
- intf_ErrMsg( "input error: No server given" );
- p_input->b_error = 1;
- return;
- }
-
- /* Check that we got a valid port */
- if( i_port == 0 )
- {
- i_port = 80; /* FIXME */
- }
-
- intf_WarnMsg( 2, "input: server=%s port=%d path=%s", psz_server,
- i_port, psz_path );
-
- /* Open a SOCK_STREAM (TCP) socket, in the AF_INET domain, automatic (0)
- * * protocol */
- p_input->i_handle = socket( AF_INET, SOCK_STREAM, 0 );
- if( p_input->i_handle == -1 )
- {
- intf_ErrMsg( "input error: can't create socket (%s)", strerror(errno) ); p_input->b_error = 1;
- return;
- }
-
- /* We may want to reuse an already used socket */
- i_opt = 1;
- if( setsockopt( p_input->i_handle, SOL_SOCKET, SO_REUSEADDR,
- (void *) &i_opt, sizeof( i_opt ) ) == -1 )
- {
- intf_ErrMsg( "input error: can't configure socket (SO_REUSEADDR: %s)",
- strerror(errno));
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Check proxy */
- if( (psz_proxy = getenv( "http_proxy" )) != NULL )
- {
- /* http://myproxy.mydomain:myport/ */
- int i_proxy_port = 0;
-
- /* Skip the protocol name */
- while( *psz_proxy && *psz_proxy != ':' )
- {
- psz_proxy++;
- }
-
- /* Skip the "://" part */
- while( *psz_proxy && (*psz_proxy == ':' || *psz_proxy == '/') )
- {
- psz_proxy++;
- }
-
- /* Found a proxy name */
- if( *psz_proxy )
- {
- char *psz_port = psz_proxy;
-
- /* Skip the hostname part */
- while( *psz_port && *psz_port != ':' && *psz_port != '/' )
- {
- psz_port++;
- }
-
- /* Found a port name */
- if( *psz_port )
- {
- char * psz_junk;
-
- /* Replace ':' with '\0' */
- *psz_port = '\0';
- psz_port++;
-
- psz_junk = psz_port;
- while( *psz_junk && *psz_junk != '/' )
- {
- psz_junk++;
- }
-
- if( *psz_junk )
- {
- *psz_junk = '\0';
- }
-
- if( *psz_port != '\0' )
- {
- i_proxy_port = atoi( psz_port );
- }
- }
- }
- else
- {
- intf_ErrMsg( "input error: http_proxy environment variable is invalid !" );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Build socket for proxy connection */
- if ( network_BuildAddr( &sock, psz_proxy, i_proxy_port ) == -1 )
- {
- intf_ErrMsg( "input error: can't build remote address" );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
- }
- else
- {
- /* No proxy, direct connection */
- if ( network_BuildAddr( &sock, psz_server, i_port ) == -1 )
- {
- intf_ErrMsg( "input error: can't build remote address" );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
- }
-
- /* Connect the socket */
- if( connect( p_input->i_handle, (struct sockaddr *) &sock,
- sizeof( sock ) ) == (-1) )
- {
- intf_ErrMsg( "input error: can't connect socket (%s)",
- strerror(errno) );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- p_input->stream.b_seekable = 0;
- p_input->stream.b_pace_control = 1; /* TCP/IP... */
-
-# define HTTP_USERAGENT "User-Agent: " COPYRIGHT_MESSAGE "\r\n"
-# define HTTP_END "\r\n"
-
- /* Prepare GET ... */
- if( psz_proxy != NULL )
- {
- snprintf( psz_buffer, sizeof(psz_buffer),
- "GET http://%s:%d/%s HTTP/1.0\r\n"
- HTTP_USERAGENT HTTP_END,
- psz_server, i_port, psz_path );
- }
- else
- {
- snprintf( psz_buffer, sizeof(psz_buffer),
- "GET /%s HTTP/1.0\r\nHost: %s\r\n"
- HTTP_USERAGENT HTTP_END,
- psz_path, psz_server );
- }
- psz_buffer[sizeof(psz_buffer) - 1] = '\0';
-
- /* Send GET ... */
- if( write( p_input->i_handle, psz_buffer, strlen( psz_buffer ) ) == (-1) )
- {
- intf_ErrMsg( "input error: can't send request (%s)", strerror(errno) );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- /* Read HTTP header - this is gonna be fun with plug-ins which do not
- * use p_input->p_stream :-( */
- if( (p_input->p_stream = fdopen( p_input->i_handle, "r+" )) == NULL )
- {
- intf_ErrMsg( "input error: can't reopen socket (%s)", strerror(errno) );
- close( p_input->i_handle );
- p_input->b_error = 1;
- return;
- }
-
- while( !feof( p_input->p_stream ) && !ferror( p_input->p_stream ) )
- {
- if( fgets( psz_buffer, sizeof(psz_buffer), p_input->p_stream ) == NULL
- || *psz_buffer == '\r' || *psz_buffer == '\0' )
- {
- break;
- }
- /* FIXME : check Content-Type one day */
- }
-
- intf_WarnMsg( 3, "input: successfully opened HTTP mode" );
-}
-
-#endif /* !defined( SYS_NTO ) */
-
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.28 2002/02/24 20:51:10 gbazin Exp $
+ * $Id: input_dec.c,v 1.29 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
p_config->p_decoder_fifo->i_depth = 0;
p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0;
p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data;
- p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes;
return p_config;
}
p_config->i_id, p_config->i_type,
p_config->p_decoder_fifo->i_depth );
/* Free all packets still in the decoder fifo. */
- p_config->p_decoder_fifo->pf_delete_pes(
- p_config->p_decoder_fifo->p_packets_mgt,
- p_config->p_decoder_fifo->p_first );
+ input_DeletePES( p_config->p_decoder_fifo->p_packets_mgt,
+ p_config->p_decoder_fifo->p_first );
/* Destroy the lock and cond */
vlc_cond_destroy( &p_config->p_decoder_fifo->data_wait );
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ext-dec.c,v 1.29 2002/01/21 23:57:46 massiot Exp $
+ * $Id: input_ext-dec.c,v 1.30 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
while (!p_fifo->b_die)
{
/* Trash all received PES packets */
- p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
+ input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
p_fifo->p_first = NULL;
p_fifo->pp_last = &p_fifo->p_first;
/* Free the previous PES packet. */
p_next = p_fifo->p_first->p_next;
p_fifo->p_first->p_next = NULL;
- p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
- p_fifo->p_first );
+ input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
p_fifo->p_first = p_next;
p_fifo->i_depth--;
--- /dev/null
+/*****************************************************************************
+ * input_ext-plugins.c: useful functions for access and demux plug-ins
+ *****************************************************************************
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: input_ext-plugins.c,v 1.1 2002/03/01 00:33:18 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <videolan/vlc.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#elif defined( _MSC_VER ) && defined( _WIN32 )
+# include <io.h>
+#endif
+
+#ifdef WIN32
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#elif !defined( SYS_BEOS ) && !defined( SYS_NTO )
+# include <netdb.h> /* hostent ... */
+# include <sys/socket.h>
+# include <netinet/in.h>
+# ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h> /* inet_ntoa(), inet_aton() */
+# endif
+#endif
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+#include "input_ext-plugins.h"
+
+
+/*
+ * Buffers management : internal functions
+ *
+ * All functions are static, but exported versions with mutex protection
+ * start with input_*. Not all of these exported functions are actually used,
+ * but they are included here for completeness.
+ */
+
+#define BUFFERS_CACHE_SIZE 500
+#define DATA_CACHE_SIZE 1000
+#define PES_CACHE_SIZE 1000
+
+/*****************************************************************************
+ * data_buffer_t: shared data type
+ *****************************************************************************/
+typedef struct data_buffer_s
+{
+ struct data_buffer_s * p_next;
+
+ /* number of data packets this buffer is referenced from - when it falls
+ * down to 0, the buffer is freed */
+ int i_refcount;
+
+ /* size of the current buffer (starting right after this byte) */
+ size_t i_size;
+} data_buffer_t;
+
+/*****************************************************************************
+ * input_buffers_t: defines a LIFO per data type to keep
+ *****************************************************************************/
+#define PACKETS_LIFO( TYPE, NAME ) \
+struct \
+{ \
+ TYPE * p_stack; \
+ unsigned int i_depth; \
+} NAME;
+
+typedef struct input_buffers_s
+{
+ vlc_mutex_t lock;
+ PACKETS_LIFO( pes_packet_t, pes )
+ PACKETS_LIFO( data_packet_t, data )
+ PACKETS_LIFO( data_buffer_t, buffers )
+ size_t i_allocated;
+} input_buffers_t;
+
+
+/*****************************************************************************
+ * input_BuffersInit: initialize the cache structures, return a pointer to it
+ *****************************************************************************/
+void * input_BuffersInit( void )
+{
+ input_buffers_t * p_buffers = malloc( sizeof( input_buffers_t ) );
+
+ if( p_buffers == NULL )
+ {
+ return( NULL );
+ }
+
+ memset( p_buffers, 0, sizeof( input_buffers_t ) );
+ vlc_mutex_init( &p_buffers->lock );
+
+ return( p_buffers );
+}
+
+/*****************************************************************************
+ * input_BuffersEnd: free all cached structures
+ *****************************************************************************/
+#define BUFFERS_END_PACKETS_LOOP \
+ while( p_packet != NULL ) \
+ { \
+ p_next = p_packet->p_next; \
+ free( p_packet ); \
+ p_packet = p_next; \
+ }
+
+void input_BuffersEnd( input_buffers_t * p_buffers )
+{
+ if( p_buffers != NULL )
+ {
+ if( p_main->b_stats )
+ {
+ intf_StatMsg( "input buffers stats: pes: %d packets",
+ p_buffers->pes.i_depth );
+ intf_StatMsg( "input buffers stats: data: %d packets",
+ p_buffers->data.i_depth );
+ intf_StatMsg( "input buffers stats: buffers: %d packets",
+ p_buffers->buffers.i_depth );
+ }
+
+ {
+ /* Free PES */
+ pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack;
+ BUFFERS_END_PACKETS_LOOP;
+ }
+
+ {
+ /* Free data packets */
+ data_packet_t * p_next, * p_packet = p_buffers->data.p_stack;
+ BUFFERS_END_PACKETS_LOOP;
+ }
+
+ {
+ /* Free buffers */
+ data_buffer_t * p_next, * p_buf = p_buffers->buffers.p_stack;
+ while( p_buf != NULL )
+ {
+ p_next = p_buf->p_next;
+ p_buffers->i_allocated -= p_buf->i_size;
+ free( p_buf );
+ p_buf = p_next;
+ }
+ }
+
+ if( p_buffers->i_allocated )
+ {
+ intf_ErrMsg( "input buffers error: %d bytes have not been"
+ " freed, expect memory leak",
+ p_buffers->i_allocated );
+ }
+
+ vlc_mutex_destroy( &p_buffers->lock );
+ free( p_buffers );
+ }
+}
+
+/*****************************************************************************
+ * input_NewBuffer: return a pointer to a data buffer of the appropriate size
+ *****************************************************************************/
+static __inline__ data_buffer_t * NewBuffer( input_buffers_t * p_buffers,
+ size_t i_size )
+{
+ data_buffer_t * p_buf;
+
+ /* Safety check */
+ if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION )
+ {
+ intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)",
+ p_buffers->i_allocated );
+ return NULL;
+ }
+
+ if( p_buffers->buffers.p_stack != NULL )
+ {
+ /* Take the buffer from the cache */
+ p_buf = p_buffers->buffers.p_stack;
+ p_buffers->buffers.p_stack = p_buf->p_next;
+ p_buffers->buffers.i_depth--;
+
+ /* Reallocate the packet if it is too small or too large */
+ if( p_buf->i_size < i_size || p_buf->i_size > 3 * i_size )
+ {
+ p_buffers->i_allocated -= p_buf->i_size;
+ free( p_buf );
+ p_buf = malloc( sizeof(input_buffers_t) + i_size );
+ if( p_buf == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ return NULL;
+ }
+ p_buf->i_size = i_size;
+ p_buffers->i_allocated += i_size;
+ }
+ }
+ else
+ {
+ /* Allocate a new buffer */
+ p_buf = malloc( sizeof(input_buffers_t) + i_size );
+ if( p_buf == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ return NULL;
+ }
+ p_buf->i_size = i_size;
+ p_buffers->i_allocated += i_size;
+ }
+
+ /* Initialize data */
+ p_buf->p_next = NULL;
+ p_buf->i_refcount = 0;
+
+ return( p_buf );
+}
+
+data_buffer_t * input_NewBuffer( input_buffers_t * p_buffers, size_t i_size )
+{
+ data_buffer_t * p_buf;
+
+ vlc_mutex_lock( &p_buffers->lock );
+ p_buf = NewBuffer( p_buffers, i_size );
+ vlc_mutex_unlock( &p_buffers->lock );
+
+ return( p_buf );
+}
+
+/*****************************************************************************
+ * input_ReleaseBuffer: put a buffer back into the cache
+ *****************************************************************************/
+static __inline__ void ReleaseBuffer( input_buffers_t * p_buffers,
+ data_buffer_t * p_buf )
+{
+ /* Decrement refcount */
+ if( --p_buf->i_refcount > 0 )
+ {
+ return;
+ }
+
+ if( p_buffers->buffers.i_depth < BUFFERS_CACHE_SIZE )
+ {
+ /* Cache not full : store the buffer in it */
+ p_buf->p_next = p_buffers->buffers.p_stack;
+ p_buffers->buffers.p_stack = p_buf;
+ p_buffers->buffers.i_depth++;
+ }
+ else
+ {
+ p_buffers->i_allocated -= p_buf->i_size;
+ free( p_buf );
+ }
+}
+
+void input_ReleaseBuffer( input_buffers_t * p_buffers, data_buffer_t * p_buf )
+{
+ vlc_mutex_lock( &p_buffers->lock );
+ ReleaseBuffer( p_buffers, p_buf );
+ vlc_mutex_unlock( &p_buffers->lock );
+}
+
+/*****************************************************************************
+ * input_ShareBuffer: allocate a data_packet_t pointing to a given buffer
+ *****************************************************************************/
+static __inline__ data_packet_t * ShareBuffer( input_buffers_t * p_buffers,
+ data_buffer_t * p_buf )
+{
+ data_packet_t * p_data;
+
+ if( p_buffers->data.p_stack != NULL )
+ {
+ /* Take the packet from the cache */
+ p_data = p_buffers->data.p_stack;
+ p_buffers->data.p_stack = p_data->p_next;
+ p_buffers->data.i_depth--;
+ }
+ else
+ {
+ /* Allocate a new packet */
+ p_data = malloc( sizeof(data_packet_t) );
+ if( p_data == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ return NULL;
+ }
+ }
+
+ p_data->p_buffer = p_buf;
+ p_data->p_next = NULL;
+ p_data->b_discard_payload = 0;
+ p_data->p_payload_start = p_data->p_demux_start
+ = (byte_t *)p_buf + sizeof(input_buffers_t);
+ p_data->p_payload_end = p_data->p_demux_start + p_buf->i_size;
+ p_buf->i_refcount++;
+
+ return( p_data );
+}
+
+data_packet_t * input_ShareBuffer( input_buffers_t * p_buffers,
+ data_buffer_t * p_buf )
+{
+ data_packet_t * p_data;
+
+ vlc_mutex_lock( &p_buffers->lock );
+ p_data = ShareBuffer( p_buffers, p_buf );
+ vlc_mutex_unlock( &p_buffers->lock );
+
+ return( p_data );
+}
+
+/*****************************************************************************
+ * input_NewPacket: allocate a packet along with a buffer
+ *****************************************************************************/
+static __inline__ data_packet_t * NewPacket( input_buffers_t * p_buffers,
+ size_t i_size )
+{
+ data_buffer_t * p_buf = NewBuffer( p_buffers, i_size );
+ data_packet_t * p_data;
+
+ if( p_buf == NULL )
+ {
+ return( NULL );
+ }
+
+ p_data = ShareBuffer( p_buffers, p_buf );
+ if( p_data == NULL )
+ {
+ ReleaseBuffer( p_buffers, p_buf );
+ }
+ return( p_data );
+}
+
+data_packet_t * input_NewPacket( input_buffers_t * p_buffers, size_t i_size )
+{
+ data_packet_t * p_data;
+
+ vlc_mutex_lock( &p_buffers->lock );
+ p_data = NewPacket( p_buffers, i_size );
+ vlc_mutex_unlock( &p_buffers->lock );
+
+ return( p_data );
+}
+
+/*****************************************************************************
+ * input_DeletePacket: deallocate a packet and its buffers
+ *****************************************************************************/
+static __inline__ void DeletePacket( input_buffers_t * p_buffers,
+ data_packet_t * p_data )
+{
+ while( p_data != NULL )
+ {
+ data_packet_t * p_next = p_data->p_next;
+
+ ReleaseBuffer( p_buffers, p_data->p_buffer );
+
+ if( p_buffers->data.i_depth < DATA_CACHE_SIZE )
+ {
+ /* Cache not full : store the packet in it */
+ p_data->p_next = p_buffers->data.p_stack;
+ p_buffers->data.p_stack = p_data;
+ p_buffers->data.i_depth++;
+ }
+ else
+ {
+ free( p_data );
+ }
+
+ p_data = p_next;
+ }
+}
+
+void input_DeletePacket( input_buffers_t * p_buffers, data_packet_t * p_data )
+{
+ vlc_mutex_lock( &p_buffers->lock );
+ DeletePacket( p_buffers, p_data );
+ vlc_mutex_unlock( &p_buffers->lock );
+}
+
+/*****************************************************************************
+ * input_NewPES: return a pointer to a new PES packet
+ *****************************************************************************/
+static __inline__ pes_packet_t * NewPES( input_buffers_t * p_buffers )
+{
+ pes_packet_t * p_pes;
+
+ if( p_buffers->pes.p_stack != NULL )
+ {
+ /* Take the packet from the cache */
+ p_pes = p_buffers->pes.p_stack;
+ p_buffers->pes.p_stack = p_pes->p_next;
+ p_buffers->pes.i_depth--;
+ }
+ else
+ {
+ /* Allocate a new packet */
+ p_pes = malloc( sizeof(pes_packet_t) );
+ if( p_pes == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ return NULL;
+ }
+ }
+
+ p_pes->p_next = NULL;
+ p_pes->b_data_alignment = p_pes->b_discontinuity =
+ p_pes->i_pts = p_pes->i_dts = 0;
+ p_pes->p_first = p_pes->p_last = NULL;
+ p_pes->i_pes_size = 0;
+ p_pes->i_nb_data = 0;
+
+ return( p_pes );
+}
+
+pes_packet_t * input_NewPES( input_buffers_t * p_buffers )
+{
+ pes_packet_t * p_pes;
+
+ vlc_mutex_lock( &p_buffers->lock );
+ p_pes = NewPES( p_buffers );
+ vlc_mutex_unlock( &p_buffers->lock );
+
+ return( p_pes );
+}
+
+/*****************************************************************************
+ * input_DeletePES: put a pes and all data packets and all buffers back into
+ * the cache
+ *****************************************************************************/
+static __inline__ void DeletePES( input_buffers_t * p_buffers,
+ pes_packet_t * p_pes )
+{
+ while( p_pes != NULL )
+ {
+ pes_packet_t * p_next = p_pes->p_next;
+
+ /* Delete all data packets */
+ if( p_pes->p_first != NULL )
+ {
+ DeletePacket( p_buffers, p_pes->p_first );
+ }
+
+ if( p_buffers->pes.i_depth < PES_CACHE_SIZE )
+ {
+ /* Cache not full : store the packet in it */
+ p_pes->p_next = p_buffers->pes.p_stack;
+ p_buffers->pes.p_stack = p_pes;
+ p_buffers->pes.i_depth++;
+ }
+ else
+ {
+ free( p_pes );
+ }
+
+ p_pes = p_next;
+ }
+}
+
+void input_DeletePES( input_buffers_t * p_buffers, pes_packet_t * p_pes )
+{
+ vlc_mutex_lock( &p_buffers->lock );
+ DeletePES( p_buffers, p_pes );
+ vlc_mutex_unlock( &p_buffers->lock );
+}
+
+
+/*
+ * Buffers management : external functions
+ *
+ * These functions make the glu between the access plug-in (pf_read) and
+ * the demux plug-in (pf_demux). We fill in a large buffer (approx. 10s kB)
+ * with a call to pf_read, then allow the demux plug-in to have a peep at
+ * it (input_Peek), and to split it in data_packet_t (input_SplitBuffer).
+ */
+/*****************************************************************************
+ * input_FillBuffer: fill in p_data_buffer with data from pf_read
+ *****************************************************************************/
+ssize_t input_FillBuffer( input_thread_t * p_input )
+{
+ ptrdiff_t i_remains = p_input->p_last_data - p_input->p_current_data;
+ data_buffer_t * p_buf;
+ ssize_t i_ret;
+
+ vlc_mutex_lock( &p_input->p_method_data->lock );
+
+ p_buf = NewBuffer( p_input->p_method_data,
+ i_remains + p_input->i_bufsize );
+ if( p_buf == NULL )
+ {
+ return( -1 );
+ }
+ p_buf->i_refcount = 1;
+
+ if( p_input->p_data_buffer != NULL )
+ {
+ FAST_MEMCPY( (byte_t *)p_buf + sizeof(data_buffer_t),
+ p_input->p_current_data, (size_t)i_remains );
+ ReleaseBuffer( p_input->p_method_data, p_input->p_data_buffer );
+ }
+
+ /* Do not hold the lock during pf_read (blocking call). */
+ vlc_mutex_unlock( &p_input->p_method_data->lock );
+
+ i_ret = p_input->pf_read( p_input,
+ (byte_t *)p_buf + sizeof(data_buffer_t)
+ + i_remains,
+ p_input->i_bufsize );
+
+ if( i_ret < 0 ) i_ret = 0;
+ p_input->p_data_buffer = p_buf;
+ p_input->p_current_data = (byte_t *)p_buf + sizeof(data_buffer_t);
+ p_input->p_last_data = p_input->p_current_data + i_remains + i_ret;
+
+ return( (ssize_t)i_remains + i_ret );
+}
+
+/*****************************************************************************
+ * input_Peek: give a pointer to the next available bytes in the buffer
+ * (min. i_size bytes)
+ * Returns the number of bytes read, or -1 in case of error
+ *****************************************************************************/
+ssize_t input_Peek( input_thread_t * p_input, byte_t ** pp_byte, size_t i_size )
+{
+ if( p_input->p_last_data - p_input->p_current_data < i_size )
+ {
+ /* Go to the next buffer */
+ ssize_t i_ret = input_FillBuffer( p_input );
+
+ if( i_size == -1 )
+ {
+ return( -1 );
+ }
+ else if( i_ret < i_size )
+ {
+ i_size = i_ret;
+ }
+ }
+ *pp_byte = p_input->p_current_data;
+ return( i_size );
+}
+
+/*****************************************************************************
+ * input_SplitBuffer: give a pointer to a data packet containing i_size bytes
+ * Returns the number of bytes read, or -1 in case of error
+ *****************************************************************************/
+ssize_t input_SplitBuffer( input_thread_t * p_input,
+ data_packet_t ** pp_data, size_t i_size )
+{
+ if( p_input->p_last_data - p_input->p_current_data < i_size )
+ {
+ /* Go to the next buffer */
+ ssize_t i_ret = input_FillBuffer( p_input );
+
+ if( i_ret == -1 )
+ {
+ return( -1 );
+ }
+ else if( i_ret < i_size )
+ {
+ i_size = i_ret;
+ }
+ }
+
+ *pp_data = input_ShareBuffer( p_input->p_method_data,
+ p_input->p_data_buffer );
+
+ (*pp_data)->p_demux_start = (*pp_data)->p_payload_start
+ = p_input->p_current_data;
+ (*pp_data)->p_payload_end = (*pp_data)->p_demux_start + i_size;
+
+ p_input->p_current_data += i_size;
+
+ return( i_size );
+}
+
+/*****************************************************************************
+ * input_AccessInit: initialize access plug-in wrapper structures
+ *****************************************************************************/
+int input_AccessInit( input_thread_t * p_input )
+{
+ p_input->p_method_data = input_BuffersInit();
+ if( p_input->p_method_data == NULL ) return( -1 );
+ p_input->p_data_buffer = NULL;
+ p_input->p_current_data = NULL;
+ p_input->p_last_data = NULL;
+ return( 0 );
+}
+
+/*****************************************************************************
+ * input_AccessReinit: reinit structures after a random seek
+ *****************************************************************************/
+void input_AccessReinit( input_thread_t * p_input )
+{
+ if( p_input->p_data_buffer != NULL )
+ {
+ ReleaseBuffer( p_input->p_method_data, p_input->p_data_buffer );
+ }
+ p_input->p_data_buffer = NULL;
+ p_input->p_current_data = NULL;
+ p_input->p_last_data = NULL;
+}
+
+/*****************************************************************************
+ * input_AccessEnd: free access plug-in wrapper structures
+ *****************************************************************************/
+void input_AccessEnd( input_thread_t * p_input )
+{
+ if( p_input->p_data_buffer != NULL )
+ {
+ ReleaseBuffer( p_input->p_method_data, p_input->p_data_buffer );
+ }
+
+ input_BuffersEnd( p_input->p_method_data );
+}
+
+
+/*
+ * Optional file descriptor management functions, for use by access plug-ins
+ * base on file descriptors (file, udp, http...).
+ */
+
+/*****************************************************************************
+ * input_FDClose: close the target
+ *****************************************************************************/
+void input_FDClose( input_thread_t * p_input )
+{
+ input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
+
+ intf_WarnMsg( 2, "input: closing `%s/%s:%s'",
+ p_input->psz_access, p_input->psz_demux, p_input->psz_name );
+
+ close( p_access_data->i_handle );
+ free( p_access_data );
+}
+
+/*****************************************************************************
+ * input_FDRead: standard read on a file descriptor.
+ *****************************************************************************/
+ssize_t input_FDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
+{
+ input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
+
+ ssize_t i_ret = read( p_access_data->i_handle, p_buffer, i_len );
+
+ if( i_ret > 0 )
+ {
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.p_selected_area->i_tell += i_ret;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+
+ if( i_ret < 0 )
+ {
+ intf_ErrMsg( "input error: read() failed (%s)", strerror(errno) );
+ }
+
+ return( i_ret );
+}
+
+/*****************************************************************************
+ * NetworkSelect: Checks whether data is available on a file descriptor
+ *****************************************************************************/
+static __inline__ int NetworkSelect( input_thread_t * p_input )
+{
+ input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
+ struct timeval timeout;
+ fd_set fds;
+ int i_ret;
+
+ /* Initialize file descriptor set */
+ FD_ZERO( &fds );
+ FD_SET( p_access_data->i_handle, &fds );
+
+ /* We'll wait 0.5 second if nothing happens */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500000;
+
+ /* Find if some data is available */
+ i_ret = select( p_access_data->i_handle + 1, &fds,
+ NULL, NULL, &timeout );
+
+ if( i_ret == -1 )
+ {
+ intf_ErrMsg( "input error: network select error (%s)", strerror(errno) );
+ }
+
+ return( i_ret );
+}
+
+/*****************************************************************************
+ * input_FDNetworkRead: read on a file descriptor, checking periodically
+ * p_input->b_die
+ *****************************************************************************/
+ssize_t input_FDNetworkRead( input_thread_t * p_input, byte_t * p_buffer,
+ size_t i_len )
+{
+ if( NetworkSelect( p_input ) > 0 )
+ {
+ input_socket_t * p_access_data
+ = (input_socket_t *)p_input->p_access_data;
+
+ ssize_t i_ret = recv( p_access_data->i_handle, p_buffer, i_len, 0 );
+
+ if( i_ret > 0 )
+ {
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.p_selected_area->i_tell += i_ret;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+
+ if( i_ret < 0 )
+ {
+ intf_ErrMsg( "input error: recv() failed (%s)", strerror(errno) );
+ }
+
+ return( i_ret );
+ }
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * input_FDSeek: seek to a specific location in a file
+ *****************************************************************************/
+void input_FDSeek( input_thread_t * p_input, off_t i_pos )
+{
+ input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
+
+ lseek( p_access_data->i_handle, i_pos, SEEK_SET );
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.p_selected_area->i_tell = i_pos;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+}
+
+
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: mpeg_system.c,v 1.80 2002/02/24 20:51:10 gbazin Exp $
+ * $Id: mpeg_system.c,v 1.81 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
!= PES_HEADER_SIZE )
{
intf_WarnMsg( 1, "input: PES packet too short to have a header" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
/* packet_start_code_prefix != 0x000001 */
intf_ErrMsg( "input error: data loss, "
"PES packet doesn't start with 0x000001" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
}
else
{
intf_WarnMsg( 1,
"PES packet too short to have a MPEG-2 header" );
- p_input->pf_delete_pes( p_input->p_method_data,
+ input_DeletePES( p_input->p_method_data,
p_pes );
p_pes = NULL;
return;
{
intf_WarnMsg( 1,
"PES packet too short to have a MPEG-2 header" );
- p_input->pf_delete_pes( p_input->p_method_data,
+ input_DeletePES( p_input->p_method_data,
p_pes );
p_pes = NULL;
return;
{
intf_WarnMsg( 1,
"PES packet too short to have a MPEG-2 header" );
- p_input->pf_delete_pes( p_input->p_method_data,
+ input_DeletePES( p_input->p_method_data,
p_pes );
p_pes = NULL;
return;
{
intf_WarnMsg( 1,
"PES packet too short to have a MPEG-1 header" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
if( i_pes_header_size == 23 )
{
intf_ErrMsg( "input error: too much MPEG-1 stuffing" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 1, "input: PES packet too short "
"to have a MPEG-1 header" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 1, "input: PES packet too short "
"to have a MPEG-1 header" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 1, "input: PES packet too short "
"to have a MPEG-1 header" );
- p_input->pf_delete_pes( p_input->p_method_data,
+ input_DeletePES( p_input->p_method_data,
p_pes );
p_pes = NULL;
return;
if( (p_data = p_data->p_next) == NULL )
{
intf_ErrMsg( "input error: PES header bigger than payload" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
if( i_payload_size < i_pes_header_size )
{
intf_ErrMsg( "input error: PES header bigger than payload" );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_ErrMsg( "input error: no fifo to receive PES %p "
"(who wrote this damn code ?)", p_pes );
- p_input->pf_delete_pes( p_input->p_method_data, p_pes );
+ input_DeletePES( p_input->p_method_data, p_pes );
}
p_pes = NULL;
}
if( !b_unit_start && p_pes == NULL )
{
/* Random access... */
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
+ input_DeletePacket( p_input->p_method_data, p_data );
}
else
{
* packet. This is also here that we can synchronize with the
* stream if we lost packets or if the decoder has just
* started. */
- if( (p_pes = p_input->pf_new_pes( p_input->p_method_data ) ) == NULL )
+ if( (p_pes = input_NewPES( p_input->p_method_data ) ) == NULL )
{
intf_ErrMsg( "input error: out of memory" );
p_input->b_error = 1;
/* Trash the packet if it has no payload or if it isn't selected */
if( b_trash )
{
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
+ input_DeletePacket( p_input->p_method_data, p_data );
p_input->stream.c_packets_trashed++;
}
}
/* Trash the packet if it has no payload or if it isn't selected */
if( b_trash )
{
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
+ input_DeletePacket( p_input->p_method_data, p_data );
p_input->stream.c_packets_trashed++;
}
else
#undef p_psi
#undef p
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
+ input_DeletePacket( p_input->p_method_data, p_data );
return ;
}
* modules.c : Built-in and plugin modules management functions
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: modules.c,v 1.54 2002/02/24 20:51:10 gbazin Exp $
+ * $Id: modules.c,v 1.55 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Ethan C. Baldridge <BaldridgeE@cadmus.com>
/* Test the requested capability */
switch( i_capability )
{
- case MODULE_CAPABILITY_INPUT:
- i_ret = p_first->p_module->p_functions->input.functions.
- input.pf_probe( (input_thread_t *)p_data );
+ case MODULE_CAPABILITY_ACCESS:
+ i_ret = p_first->p_module->p_functions->access.functions.
+ access.pf_open( (struct input_thread_s *)p_data );
+ break;
+
+ case MODULE_CAPABILITY_DEMUX:
+ i_ret = p_first->p_module->p_functions->demux.functions.
+ demux.pf_init( (struct input_thread_s *)p_data );
+ break;
+
+ case MODULE_CAPABILITY_NETWORK:
+ i_ret = p_first->p_module->p_functions->network.functions.
+ network.pf_open( (struct network_socket_s *)p_data );
break;
case MODULE_CAPABILITY_DECODER:
case MODULE_CAPABILITY_INTF:
i_ret = p_first->p_module->p_functions->intf.functions.
- intf.pf_open( (intf_thread_t *)p_data );
+ intf.pf_open( (struct intf_thread_s *)p_data );
break;
case MODULE_CAPABILITY_AOUT:
i_ret = p_first->p_module->p_functions->aout.functions.
- aout.pf_open( (aout_thread_t *)p_data );
+ aout.pf_open( (struct aout_thread_s *)p_data );
break;
case MODULE_CAPABILITY_VOUT:
i_ret = p_first->p_module->p_functions->vout.functions.
- vout.pf_create( (vout_thread_t *)p_data );
+ vout.pf_create( (struct vout_thread_s *)p_data );
break;
case MODULE_CAPABILITY_CHROMA:
i_ret = p_first->p_module->p_functions->chroma.functions.
- chroma.pf_init( (vout_thread_t *)p_data );
+ chroma.pf_init( (struct vout_thread_s *)p_data );
break;
case MODULE_CAPABILITY_IDCT:
* modules_plugin.h : Plugin management functions used by the core application.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: modules_plugin.h,v 1.12 2002/02/24 21:36:20 jobi Exp $
+ * $Id: modules_plugin.h,v 1.13 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
(p_symbols)->input_DemuxTS = input_DemuxTS; \
(p_symbols)->input_DemuxPSI = input_DemuxPSI; \
(p_symbols)->input_ClockManageControl = input_ClockManageControl; \
+ (p_symbols)->input_FDSeek = input_FDSeek; \
+ (p_symbols)->input_FDClose = input_FDClose; \
+ (p_symbols)->input_FDRead = input_FDRead; \
+ (p_symbols)->input_FDNetworkRead = input_FDNetworkRead; \
+ (p_symbols)->input_BuffersInit = input_BuffersInit; \
+ (p_symbols)->input_BuffersEnd = input_BuffersEnd; \
+ (p_symbols)->input_NewBuffer = input_NewBuffer; \
+ (p_symbols)->input_ReleaseBuffer = input_ReleaseBuffer; \
+ (p_symbols)->input_ShareBuffer = input_ShareBuffer; \
+ (p_symbols)->input_NewPacket = input_NewPacket; \
+ (p_symbols)->input_DeletePacket = input_DeletePacket; \
+ (p_symbols)->input_NewPES = input_NewPES; \
+ (p_symbols)->input_DeletePES = input_DeletePES; \
+ (p_symbols)->input_FillBuffer = input_FillBuffer; \
+ (p_symbols)->input_Peek = input_Peek; \
+ (p_symbols)->input_SplitBuffer = input_SplitBuffer; \
+ (p_symbols)->input_AccessInit = input_AccessInit; \
+ (p_symbols)->input_AccessReinit = input_AccessReinit; \
+ (p_symbols)->input_AccessEnd = input_AccessEnd; \
(p_symbols)->aout_CreateFifo = aout_CreateFifo; \
(p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \
(p_symbols)->vout_CreateThread = vout_CreateThread; \
* thread, and destroy a previously oppened video output thread.
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: video_output.c,v 1.162 2002/02/27 18:19:21 sam Exp $
+ * $Id: video_output.c,v 1.163 2002/03/01 00:33:18 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
{
p_vout->p_picture[i_index].i_status = FREE_PICTURE;
p_vout->p_picture[i_index].i_type = EMPTY_PICTURE;
- vlc_mutex_init( &p_vout->p_picture[i_index].lock_deccount );
}
for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++)
{
free( p_vout->p_picture[i_index].p_data );
}
- vlc_mutex_destroy( &p_vout->p_picture[i_index].lock_deccount );
}
/* Destroy all remaining subpictures */