]> git.sesse.net Git - vlc/commitdiff
Input III (Episode 1).
authorChristophe Massiot <massiot@videolan.org>
Fri, 1 Mar 2002 00:33:18 +0000 (00:33 +0000)
committerChristophe Massiot <massiot@videolan.org>
Fri, 1 Mar 2002 00:33:18 +0000 (00:33 +0000)
- Major rewrite of the buffer core functions
- Modularity of access plugins (file, udp, http)
- Modularity of network stack (ipv4, soon ipv6)
- Autodetection of the type of stream

And a new killing feature : HTTP streams are now seekable.

Please note that dvd, dvdread and vcd plug-ins are broken and thus disabled.

40 files changed:
Makefile
configure
configure.in
include/common.h
include/input_ext-dec.h
include/input_ext-intf.h
include/input_ext-plugins.h
include/modules.h
include/network.h [moved from plugins/mpeg_system/input_es.h with 57% similarity]
include/threads.h
include/video.h
plugins/access/.cvsignore [new file with mode: 0644]
plugins/access/Makefile [new file with mode: 0644]
plugins/access/file.c [new file with mode: 0644]
plugins/access/http.c [new file with mode: 0644]
plugins/access/udp.c [new file with mode: 0644]
plugins/dummy/dummy.c
plugins/dummy/input_dummy.c
plugins/dvd/dvd.c
plugins/gtk/gtk_display.c
plugins/mpeg_system/Makefile
plugins/mpeg_system/input_es.c [deleted file]
plugins/mpeg_system/input_ps.c [deleted file]
plugins/mpeg_system/input_ps.h [deleted file]
plugins/mpeg_system/input_ts.c [deleted file]
plugins/mpeg_system/input_ts.h [deleted file]
plugins/mpeg_system/mpeg_es.c
plugins/mpeg_system/mpeg_ps.c
plugins/mpeg_system/mpeg_ts.c
plugins/network/.cvsignore [new file with mode: 0644]
plugins/network/Makefile [new file with mode: 0644]
plugins/network/ipv4.c [new file with mode: 0644]
src/input/input.c
src/input/input_dec.c
src/input/input_ext-dec.c
src/input/input_ext-plugins.c [new file with mode: 0644]
src/input/mpeg_system.c
src/misc/modules.c
src/misc/modules_plugin.h
src/video_output/video_output.c

index de249c3808a9a127e05ae12d05f8bfff003fe2e0..8a40af987f728d96e87dacee6a87a4e35557893b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@ endif
 #
 PLUGINS_DIR := ac3_adec \
                ac3_spdif \
+               access \
                alsa \
                arts \
                beos \
@@ -57,6 +58,9 @@ PLUGINS_DIR :=        ac3_adec \
 
 PLUGINS_TARGETS := ac3_adec/ac3_adec \
                ac3_spdif/ac3_spdif \
+               access/file \
+               access/udp \
+               access/http \
                alsa/alsa \
                arts/arts \
                beos/beos \
@@ -119,6 +123,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
                mpeg_system/mpeg_ts \
                mpeg_adec/mpeg_adec \
                mpeg_vdec/mpeg_vdec \
+               network/ipv4 \
                qnx/qnx \
                qt/qt \
                sdl/sdl \
@@ -136,7 +141,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
 # 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
index 24c574c7fd5a67ec205f84854ea3ef42d7c4ebf5..6e83f50b30329238caebacbd2371b8c083c1cf21 100755 (executable)
--- a/configure
+++ b/configure
@@ -5399,7 +5399,7 @@ case x"${target_cpu}" in
     ;;
 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"
@@ -6387,7 +6387,7 @@ if test "${with_dvdcss+set}" = set; then
    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
@@ -6398,7 +6398,7 @@ if test "${with_dvdcss+set}" = set; then
     ;;
     xlocal-shared)
       # local libdvdcss, dynamically linked
-      PLUGINS="${PLUGINS} dvd"
+      #PLUGINS="${PLUGINS} dvd"
       if test x${CAN_BUILD_LIBDVDCSS} = x1
       then
         NEED_LIBDVDCSS=1
@@ -6408,7 +6408,7 @@ if test "${with_dvdcss+set}" = set; then
     ;;
     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"
@@ -6417,7 +6417,7 @@ if test "${with_dvdcss+set}" = set; then
     ;;
     *)
       # existing libdvdcss
-      PLUGINS="${PLUGINS} dvd"
+      #PLUGINS="${PLUGINS} dvd"
       if test "x$withval" != "xyes"
       then
         LIB_DVD="${LIB_DVD} -L"$withval"/lib"
@@ -6430,14 +6430,14 @@ else
   # 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"
@@ -6467,11 +6467,11 @@ if test "${with_dvdread+set}" = set; then
     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 
@@ -6489,7 +6489,7 @@ if test "${with_dvdread+set}" = set; then
       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
@@ -6521,7 +6521,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "cdrom_msf0" >/dev/null 2>&1; then
   rm -rf conftest*
   
-    BUILTINS="${BUILTINS} vcd"
+    #BUILTINS="${BUILTINS} vcd"
   
 fi
 rm -f conftest*
@@ -6530,12 +6530,13 @@ 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
 
@@ -6605,17 +6606,17 @@ if test "${with_mad+set}" = set; then
 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*
@@ -6645,7 +6646,7 @@ fi
 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
@@ -6653,7 +6654,7 @@ else
   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
@@ -6664,7 +6665,7 @@ int main() {
 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
@@ -6721,17 +6722,17 @@ then
 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*
@@ -6754,7 +6755,7 @@ EOF
  
     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
@@ -6762,14 +6763,14 @@ else
   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
@@ -6805,7 +6806,7 @@ if test "${enable_esd+set}" = set; then
      # 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
@@ -6856,7 +6857,7 @@ if test "${enable_arts+set}" = set; then
      # 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
@@ -6914,17 +6915,17 @@ 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*
@@ -6969,17 +6970,17 @@ fi
 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*
@@ -7022,17 +7023,17 @@ if test "x$enableval" != "xno" -a x$SYS != xmingw32
 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*
@@ -7120,7 +7121,7 @@ fi
   # 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
@@ -7160,7 +7161,7 @@ fi
     # 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
@@ -7201,7 +7202,7 @@ fi
     # 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
@@ -7247,17 +7248,17 @@ fi
 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*
@@ -7327,17 +7328,17 @@ fi
 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*
@@ -7366,7 +7367,7 @@ done
 
     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"
@@ -7475,7 +7476,7 @@ if test "${enable_gnome+set}" = set; then
     # 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
@@ -7520,17 +7521,17 @@ fi
 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*
@@ -7590,7 +7591,7 @@ fi
   # 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
@@ -7629,7 +7630,7 @@ fi
     # 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
@@ -7679,17 +7680,17 @@ fi
 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*
@@ -7747,17 +7748,17 @@ if test x$enable_x11 != xno &&
 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*
@@ -7810,17 +7811,17 @@ if test x$enable_xvideo != xno &&
 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*
@@ -7844,7 +7845,7 @@ EOF
     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
@@ -7852,7 +7853,7 @@ else
   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
@@ -7863,7 +7864,7 @@ int main() {
 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
@@ -7910,17 +7911,17 @@ if test x$enable_lirc = xyes
 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*
@@ -7937,7 +7938,7 @@ fi
 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
@@ -7945,7 +7946,7 @@ else
   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
@@ -7956,7 +7957,7 @@ int main() {
 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
@@ -7996,17 +7997,17 @@ if test "${enable_alsa+set}" = set; then
    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*
@@ -8023,7 +8024,7 @@ fi
 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
@@ -8031,14 +8032,14 @@ else
   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
index 371a59fbcf7c660d234f736e1d226ed6b0ce2c0c..85e51ab057452e0ab647f59962374b937d162226 100644 (file)
@@ -443,7 +443,7 @@ esac
 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
@@ -788,7 +788,7 @@ AC_ARG_WITH(dvdcss,
   [ 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
@@ -799,7 +799,7 @@ AC_ARG_WITH(dvdcss,
     ;;
     xlocal-shared)
       # local libdvdcss, dynamically linked
-      PLUGINS="${PLUGINS} dvd"
+      #PLUGINS="${PLUGINS} dvd"
       if test x${CAN_BUILD_LIBDVDCSS} = x1
       then
         NEED_LIBDVDCSS=1
@@ -809,7 +809,7 @@ AC_ARG_WITH(dvdcss,
     ;;
     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"
@@ -818,7 +818,7 @@ AC_ARG_WITH(dvdcss,
     ;;
     *)
       # existing libdvdcss
-      PLUGINS="${PLUGINS} dvd"
+      #PLUGINS="${PLUGINS} dvd"
       if test "x$withval" != "xyes"
       then
         LIB_DVD="${LIB_DVD} -L"$withval"/lib"
@@ -830,14 +830,14 @@ AC_ARG_WITH(dvdcss,
   # 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"
@@ -868,11 +868,11 @@ AC_ARG_WITH(dvdread,
     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 
@@ -890,7 +890,7 @@ AC_ARG_WITH(dvdread,
       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
@@ -911,18 +911,19 @@ AC_ARG_ENABLE(vcd,
 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
 
index 9265e9a1786a9907f96db4710526bea13396310b..d96099d16e48f8eb6faf9b41455afe31cfd3198e 100644 (file)
@@ -3,7 +3,7 @@
  * 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>
@@ -171,6 +171,8 @@ struct pgrm_descriptor_s;
 struct pes_packet_s;
 struct input_area_s;
 struct bit_stream_s;
+struct input_buffers_s;
+struct network_socket_s;
 struct intf_subscription_s;
 
 /*****************************************************************************
@@ -537,10 +539,31 @@ typedef struct module_symbols_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 * );
index af36722caf4a58663a70aaff2c6b7df354d0c3f8..c4e03932ad1bf4690c5b1ad9e4c582c17682c323 100644 (file)
@@ -2,7 +2,7 @@
  * 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;
 
 /*****************************************************************************
@@ -113,10 +109,8 @@ typedef struct decoder_fifo_s
     /* 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;
 
 /*****************************************************************************
index 6be18d24de6df7ee1bdefe34ad776f98a3d5f9b0..3f24764059f4d7ebd6dbb368a294456a5556b331 100644 (file)
@@ -4,7 +4,7 @@
  * 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>
  *
@@ -261,49 +261,45 @@ typedef struct input_thread_s
     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;
index 9727a4a4a7bea442e972e3a47d652b6f42519805..8fc70e69f1d65b8fcbdfc90281d7dda09eed1f11 100644 (file)
@@ -2,8 +2,8 @@
  * 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>
  *
@@ -31,6 +31,8 @@
                                  * 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
 
 /*****************************************************************************
@@ -72,6 +74,7 @@ int  input_UnselectES( struct input_thread_s *, struct es_descriptor_s * );
  * 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 * );
@@ -98,6 +101,44 @@ mtime_t input_ClockGetTS( struct input_thread_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
  *****************************************************************************/
@@ -107,8 +148,7 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
     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");
@@ -129,7 +169,7 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
     }
     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;
@@ -145,683 +185,6 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
 }
 
 
-/*
- * 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
  */
@@ -938,3 +301,32 @@ void input_DemuxPSI  ( struct input_thread_s *, struct data_packet_s *,
 #   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
+
index 4f806fc3e39cbbedcdf8eb149c9372086edf9637..3816f4ecd273a608c8d1415b7f3685553163055c 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -52,10 +52,10 @@ static __inline__ char *GetCapabilityName( unsigned int i_capa )
 #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",
@@ -174,38 +174,33 @@ typedef struct function_list_s
             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
@@ -312,8 +307,8 @@ typedef struct module_functions_s
     /* 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;
similarity index 57%
rename from plugins/mpeg_system/input_es.h
rename to include/network.h
index 6d150577edc72f244c59726d1bed183a929cf48a..dfaf7f658da482263fda3013216fa9236243315a 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * 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
+
index a03da32d8955cf53b5b9241c4a01f3aa459fcb3a..54c262916dcb8a4a7b4cc346d64ac429b990baf6 100644 (file)
@@ -3,7 +3,7 @@
  * 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 );
 
@@ -716,15 +720,21 @@ static __inline__ int _vlc_cond_wait( char * psz_file, int i_line,
         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
 
index 3c01da1b43c453da59ae65c47b30e5ee1eb7aa59..52662edb9a86c3ffb822c7affec572053e85bd74 100644 (file)
@@ -4,7 +4,7 @@
  * 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>
  *
@@ -84,11 +84,6 @@ typedef struct picture_s
     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;
diff --git a/plugins/access/.cvsignore b/plugins/access/.cvsignore
new file mode 100644 (file)
index 0000000..435f39e
--- /dev/null
@@ -0,0 +1,4 @@
+.dep
+*.lo
+*.o.*
+*.lo.*
diff --git a/plugins/access/Makefile b/plugins/access/Makefile
new file mode 100644 (file)
index 0000000..fda8268
--- /dev/null
@@ -0,0 +1,3 @@
+file_SOURCES = file.c
+udp_SOURCES = udp.c
+http_SOURCES = http.c
diff --git a/plugins/access/file.c b/plugins/access/file.c
new file mode 100644 (file)
index 0000000..f0b97db
--- /dev/null
@@ -0,0 +1,194 @@
+/*****************************************************************************
+ * 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 );
+}
+
diff --git a/plugins/access/http.c b/plugins/access/http.c
new file mode 100644 (file)
index 0000000..befd1b2
--- /dev/null
@@ -0,0 +1,420 @@
+/*****************************************************************************
+ * 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 );
+}
+
diff --git a/plugins/access/udp.c b/plugins/access/udp.c
new file mode 100644 (file)
index 0000000..307383e
--- /dev/null
@@ -0,0 +1,247 @@
+/*****************************************************************************
+ * 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 );
+}
+
index 34a54943c9dbbe1a2c766e1b0c266dc6d7548f42..9f35c05e1e3867d44badeabcc8e66733050fb0c5 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -32,7 +32,8 @@
 /*****************************************************************************
  * 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 );
@@ -48,17 +49,19 @@ MODULE_INIT_START
     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 );
index 7a892b740ff8a201e9917c7e7adc1ac5e737d446..b5561dd37279b2294e803805950db5c97d895189 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * 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
@@ -75,48 +69,37 @@ typedef struct dummy_data_s
  * 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 );
 }
 
 /*****************************************************************************
@@ -124,41 +107,28 @@ static void DummyOpen( input_thread_t * p_input )
  *****************************************************************************/
 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 */
@@ -166,7 +136,7 @@ static void DummyInit( struct input_thread_s *p_input )
     {
         intf_WarnMsg( 2, "input: command `nop'" );
         p_method->i_command = COMMAND_NOP;
-        return;
+        return( 0 );
     }
 
     /* Check for a "vlc:quit" command */
@@ -174,7 +144,7 @@ static void DummyInit( struct input_thread_s *p_input )
     {
         intf_WarnMsg( 2, "input: command `quit'" );
         p_method->i_command = COMMAND_QUIT;
-        return;
+        return( 0 );
     }
 
     /* Check for a "vlc:loop" command */
@@ -182,7 +152,7 @@ static void DummyInit( struct input_thread_s *p_input )
     {
         intf_WarnMsg( 2, "input: command `loop'" );
         p_method->i_command = COMMAND_LOOP;
-        return;
+        return( 0 );
     }
 
     /* Check for a "vlc:pause:***" command */
@@ -192,14 +162,14 @@ static void DummyInit( struct input_thread_s *p_input )
         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 );
 }
 
 /*****************************************************************************
@@ -207,21 +177,20 @@ static void DummyInit( struct input_thread_s *p_input )
  *****************************************************************************/
 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:
@@ -246,8 +215,6 @@ static int DummyRead( struct input_thread_s *p_input, data_packet_t **pp_data )
             break;
     }
 
-    *pp_data = NULL;
-
-    return 0;
+    return 1;
 }
 
index 2e2b857f1f011add352f92c8720f0cd8a913848b..86ab196b16a1931aa2ae8b5237a49cbda4970f36 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -37,7 +37,8 @@
 /*****************************************************************************
  * 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.
@@ -57,16 +58,17 @@ MODULE_CONFIG_STOP
 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
index 9b265bc672840ba013ea869db79d71c4d5fff62f..6bc6ea619461fb2d8e5efc10f4551f246a021802 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -131,7 +131,7 @@ gint GtkModeManage( intf_thread_t * p_intf )
                             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" );
@@ -144,7 +144,7 @@ gint GtkModeManage( intf_thread_t * p_intf )
                             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 ) )
@@ -164,7 +164,7 @@ gint GtkModeManage( intf_thread_t * p_intf )
                             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;
         }
     
index 4db156a75c72624f247b1fdb3a20ecc6236ff8d2..b6eeaa91c8aa034bb94b1404f6f3820f0fa39736 100644 (file)
@@ -1,3 +1,3 @@
-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
diff --git a/plugins/mpeg_system/input_es.c b/plugins/mpeg_system/input_es.c
deleted file mode 100644 (file)
index c28f59c..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/*****************************************************************************
- * 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 );
-}
-
diff --git a/plugins/mpeg_system/input_ps.c b/plugins/mpeg_system/input_ps.c
deleted file mode 100644 (file)
index 85af714..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/*****************************************************************************
- * 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;
-}
-
diff --git a/plugins/mpeg_system/input_ps.h b/plugins/mpeg_system/input_ps.h
deleted file mode 100644 (file)
index bc1108e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*****************************************************************************
- * 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
diff --git a/plugins/mpeg_system/input_ts.c b/plugins/mpeg_system/input_ts.c
deleted file mode 100644 (file)
index 27230cc..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/*****************************************************************************
- * 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 );
-}
-
diff --git a/plugins/mpeg_system/input_ts.h b/plugins/mpeg_system/input_ts.h
deleted file mode 100644 (file)
index f59acba..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*****************************************************************************
- * 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
-
index a4644abd7470f73b0a5bf18b7e0481ebb9c9abfc..714bfc80efb1d3b39f17492bccd2c05fcbf00987 100644 (file)
@@ -2,7 +2,7 @@
  * 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.
@@ -41,15 +58,165 @@ MODULE_CONFIG_START
 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 );
+}
+
index 3216d443a97f8c028b9fd6321c35a498958c7285..16526811e467b67e8f666d051544c8def3e60a19 100644 (file)
@@ -2,7 +2,7 @@
  * 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.
@@ -42,14 +58,371 @@ MODULE_CONFIG_STOP
 
 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 );
+}
+
index 83e9702c38b2174b0ad17a6bc8a91c33cf4f58df..d918f2680d81a68bfe83a5bc6b914ba96f4ab56b 100644 (file)
@@ -2,7 +2,7 @@
  * 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.
@@ -42,14 +58,170 @@ MODULE_CONFIG_STOP
 
 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 );
+}
+
diff --git a/plugins/network/.cvsignore b/plugins/network/.cvsignore
new file mode 100644 (file)
index 0000000..435f39e
--- /dev/null
@@ -0,0 +1,4 @@
+.dep
+*.lo
+*.o.*
+*.lo.*
diff --git a/plugins/network/Makefile b/plugins/network/Makefile
new file mode 100644 (file)
index 0000000..2046f87
--- /dev/null
@@ -0,0 +1 @@
+ipv4_SOURCES = ipv4.c
diff --git a/plugins/network/ipv4.c b/plugins/network/ipv4.c
new file mode 100644 (file)
index 0000000..99a445d
--- /dev/null
@@ -0,0 +1,352 @@
+/*****************************************************************************
+ * 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 );
+    }
+}
index 1fe90fa61b1c04fa1096bc7525e3553d200726c3..fd3e64deb1ad362fb21c333a58ec37ace1bee3ff 100644 (file)
@@ -4,9 +4,10 @@
  * 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
@@ -85,15 +62,6 @@ static void CloseThread     ( input_thread_t *p_input );
 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.
  *****************************************************************************/
@@ -156,7 +124,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
     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;
@@ -165,7 +133,6 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
     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 );
@@ -205,7 +172,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
                                              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",
@@ -306,8 +273,7 @@ static int RunThread( input_thread_t *p_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++;
 
@@ -362,8 +328,10 @@ static int RunThread( input_thread_t *p_input )
         {
             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++ )
                 {
@@ -376,6 +344,9 @@ static int RunThread( input_thread_t *p_input )
                     /* 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;
         }
@@ -408,19 +379,8 @@ static int RunThread( input_thread_t *p_input )
 
         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 )
         {
@@ -452,90 +412,139 @@ static int RunThread( input_thread_t *p_input )
  *****************************************************************************/
 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 );
 }
 
@@ -583,12 +592,10 @@ static void EndThread( input_thread_t * p_input )
 
     /* 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 );
 }
 
 /*****************************************************************************
@@ -596,32 +603,12 @@ static void EndThread( input_thread_t * p_input )
  *****************************************************************************/
 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 );
 }
 
 /*****************************************************************************
@@ -633,681 +620,3 @@ static void DestroyThread( input_thread_t * p_input )
     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 ) */
-
index 787a3d88db665df69d399262be90e22eea1a99e0..6e6f699608e00a7ae6ee0c6331c19980f52485b6 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -254,7 +254,6 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
     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;
 }
@@ -268,9 +267,8 @@ static void DeleteDecoderConfig( decoder_config_t * 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 );
index 93cbc1d79aa40b69c40927a3e948cbe3d2637bdf..449ad06ffa50b05e0db71bd92edfd9ecee30700e 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -96,7 +96,7 @@ void DecoderError( decoder_fifo_t * p_fifo )
     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;
 
@@ -132,8 +132,7 @@ static __inline__ boolean_t _NextDataPacket( decoder_fifo_t * p_fifo,
             /* 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--;
 
diff --git a/src/input/input_ext-plugins.c b/src/input/input_ext-plugins.c
new file mode 100644 (file)
index 0000000..5ff4683
--- /dev/null
@@ -0,0 +1,763 @@
+/*****************************************************************************
+ * 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 );
+}
+
+
index 5e7580c13f59bc39da0a8791af3b058e46a5f670..bf58fc0a96d5cfff1ab459d7921b83554f9ae31b 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -130,7 +130,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
             != 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;
     }
@@ -149,7 +149,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
         /* 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
@@ -195,7 +195,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                 {
                     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;
@@ -212,7 +212,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                     {
                         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;
@@ -230,7 +230,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                         {
                             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;
@@ -261,7 +261,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                     {
                         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;
                     }
@@ -269,7 +269,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                 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;
                 }
@@ -285,7 +285,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                     {
                         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;
                     }
@@ -305,7 +305,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                     {
                         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;
                     }
@@ -323,7 +323,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                         {
                             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;
@@ -365,7 +365,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
             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;
             }
@@ -376,7 +376,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
         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;
         }
@@ -392,7 +392,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
         {
             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;
     }
@@ -430,7 +430,7 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
     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
     {
@@ -441,7 +441,7 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
              * 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;
@@ -913,7 +913,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
     /* 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++;
     }
 }
@@ -1126,7 +1126,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
     /* 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
@@ -1282,7 +1282,7 @@ void input_DemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
 #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 ;
 }
index 063f9691544581c3e81d30a9b1d1df018858a447..99f08701e981356732a42b424e30540e306ef975 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -385,9 +385,19 @@ module_t * module_Need( int i_capability, char *psz_name, void *p_data )
         /* 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:
@@ -397,22 +407,22 @@ module_t * module_Need( int i_capability, char *psz_name, void *p_data )
 
             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:
index 8acfb6730e102d71f8bec1c2cb3bb8b11d1ccc38..fcf23b1c09c8bbb294ccd3555ca743097f9907f2 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -214,6 +214,25 @@ module_error( void )
     (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; \
index 741d1542fbdda48d43bdaf197d2e1d427fd5c82c..88e4c6870c7e1f0d3e8ad960cbc454766087c701 100644 (file)
@@ -5,7 +5,7 @@
  * 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>
  *
@@ -125,7 +125,6 @@ vout_thread_t * vout_CreateThread   ( int *pi_status,
     {
         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++)
@@ -641,7 +640,6 @@ static void EndThread( vout_thread_t *p_vout )
         {
             free( p_vout->p_picture[i_index].p_data );
         }
-        vlc_mutex_destroy( &p_vout->p_picture[i_index].lock_deccount );
     }
 
     /* Destroy all remaining subpictures */