* src/video_output/vout_pictures.c, include/video_output.h: added a vout_InitPicture...
authorGildas Bazin <gbazin@videolan.org>
Sun, 27 Apr 2003 23:16:35 +0000 (23:16 +0000)
committerGildas Bazin <gbazin@videolan.org>
Sun, 27 Apr 2003 23:16:35 +0000 (23:16 +0000)
* modules/encoder/ffmpeg/video.c: misc improvements. Should also be able to handle more input chroma format.
* modules/codec/rawvideo.c: a few fixes.
* modules/access/v4l/v4l.c: misc improvments and cleanup. Should be able to handle more source chroma formats. On the fly video encoding is also working perfectly now.

include/video_output.h
modules/access/v4l/v4l.c
modules/codec/rawvideo.c
modules/encoder/ffmpeg/encoder.c
modules/encoder/ffmpeg/video.c
src/video_output/vout_pictures.c

index 2d7d100..d05080f 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously opened video output thread.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_output.h,v 1.93 2003/03/24 23:50:46 gbazin Exp $
+ * $Id: video_output.h,v 1.94 2003/04/27 23:16:35 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -155,6 +155,7 @@ VLC_EXPORT( int, vout_VarCallback, ( vlc_object_t *, const char *, vlc_value_t,
 VLC_EXPORT( int,             vout_ChromaCmp,      ( uint32_t, uint32_t ) );
 
 VLC_EXPORT( picture_t *,     vout_CreatePicture,  ( vout_thread_t *, vlc_bool_t, vlc_bool_t, vlc_bool_t ) );
+VLC_EXPORT( void,            vout_InitPicture,    ( vlc_object_t *, picture_t *, int, int, uint32_t ) );
 VLC_EXPORT( void,            vout_AllocatePicture,( vout_thread_t *, picture_t *, int, int, uint32_t ) );
 VLC_EXPORT( void,            vout_DestroyPicture, ( vout_thread_t *, picture_t * ) );
 VLC_EXPORT( void,            vout_DisplayPicture, ( vout_thread_t *, picture_t * ) );
index 501135b..31edd56 100644 (file)
@@ -2,7 +2,7 @@
  * v4l.c : Video4Linux input module for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: v4l.c,v 1.7 2003/04/09 09:59:59 titer Exp $
+ * $Id: v4l.c,v 1.8 2003/04/27 23:16:35 gbazin Exp $
  *
  * Author: Samuel Hocevar <sam@zoy.org>
  *
@@ -74,13 +74,14 @@ static int  Demux      ( input_thread_t * );
 vlc_module_begin();
     set_description( _("Video4Linux input") );
     add_category_hint( N_("v4l"), NULL, VLC_TRUE );
-        add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL,
-                     CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
-    add_submodule();
-        add_shortcut( "v4l" );
-        set_capability( "access", 0 );
-        set_callbacks( AccessOpen, AccessClose );
+    add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL,
+                 CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
+    add_shortcut( "v4l" );
+    set_capability( "access", 10 );
+    set_callbacks( AccessOpen, AccessClose );
+
     add_submodule();
+        set_description( _("Video4Linux demuxer") );
         add_shortcut( "v4l" );
         set_capability( "demux", 200 );
         set_callbacks( DemuxOpen, DemuxClose );
@@ -114,6 +115,7 @@ struct access_sys_t
     uint8_t *p_video_mmap;
     int     i_frame_pos;
     struct video_mmap   vid_mmap;
+    struct video_picture vid_picture;
 
     uint8_t *p_video_frame;
     int     i_video_frame_size;
@@ -240,8 +242,8 @@ static int AccessOpen( vlc_object_t *p_this )
             *psz_parser++ = '\0';
             if( !strncmp( psz_parser, "channel=", strlen( "channel=" ) ) )
             {
-                p_sys->i_channel =
-                    strtol( psz_parser + strlen( "channel=" ), &psz_parser, 0 );
+                p_sys->i_channel = strtol( psz_parser + strlen( "channel=" ),
+                                           &psz_parser, 0 );
             }
             else if( !strncmp( psz_parser, "norm=", strlen( "norm=" ) ) )
             {
@@ -271,14 +273,17 @@ static int AccessOpen( vlc_object_t *p_this )
                     p_sys->i_norm = strtol( psz_parser, &psz_parser, 0 );
                 }
             }
-            else if( !strncmp( psz_parser, "frequency=", strlen( "frequency=" ) ) )
+            else if( !strncmp( psz_parser, "frequency=",
+                               strlen( "frequency=" ) ) )
             {
                 p_sys->i_frequency =
-                    strtol( psz_parser + strlen( "frequency=" ), &psz_parser, 0 );
+                    strtol( psz_parser + strlen( "frequency=" ),
+                            &psz_parser, 0 );
             }
             else if( !strncmp( psz_parser, "audio=", strlen( "audio=" ) ) )
             {
-                p_sys->i_audio = strtol( psz_parser + strlen( "audio=" ), &psz_parser, 0 );
+                p_sys->i_audio = strtol( psz_parser + strlen( "audio=" ),
+                                         &psz_parser, 0 );
             }
             else if( !strncmp( psz_parser, "size=", strlen( "size=" ) ) )
             {
@@ -319,14 +324,17 @@ static int AccessOpen( vlc_object_t *p_this )
                     p_sys->i_width = strtol( psz_parser, &psz_parser, 0 );
                     if( *psz_parser == 'x' || *psz_parser == 'X')
                     {
-                        p_sys->i_height = strtol( psz_parser + 1, &psz_parser, 0 );
+                        p_sys->i_height = strtol( psz_parser + 1,
+                                                  &psz_parser, 0 );
                     }
-                    msg_Dbg( p_input, "WxH %dx%d", p_sys->i_width, p_sys->i_height );
+                    msg_Dbg( p_input, "WxH %dx%d", p_sys->i_width,
+                             p_sys->i_height );
                 }
             }
             else if( !strncmp( psz_parser, "tuner=", strlen( "tuner=" ) ) )
             {
-                p_sys->i_tuner = strtol( psz_parser + strlen( "tuner=" ), &psz_parser, 0 );
+                p_sys->i_tuner = strtol( psz_parser + strlen( "tuner=" ),
+                                         &psz_parser, 0 );
             }
             else if( !strncmp( psz_parser, "codec=", strlen( "codec=" ) ) )
             {
@@ -363,9 +371,12 @@ static int AccessOpen( vlc_object_t *p_this )
 
                 psz_parser += i_len;
             }
-            else if( !strncmp( psz_parser, "samplerate=", strlen( "samplerate=" ) ) )
+            else if( !strncmp( psz_parser, "samplerate=",
+                               strlen( "samplerate=" ) ) )
             {
-                p_sys->i_sample_rate = strtol( psz_parser + strlen( "samplerate=" ), &psz_parser, 0 );
+                p_sys->i_sample_rate =
+                    strtol( psz_parser + strlen( "samplerate=" ),
+                            &psz_parser, 0 );
             }
             else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )
             {
@@ -509,16 +520,12 @@ static int AccessOpen( vlc_object_t *p_this )
                 msg_Err( p_input, "cannot get tuner" );
                 goto failed;
             }
-            msg_Dbg( p_input,
-                     "tuner %s low=%d high=%d, flags=0x%x mode=0x%x signal=0x%x",
-                     vid_tuner.name,
-                     vid_tuner.rangelow, vid_tuner.rangehigh,
-                     vid_tuner.flags,
-                     vid_tuner.mode,
-                     vid_tuner.signal );
-
-            msg_Dbg( p_input,
-                     "setting tuner %s (%d)",
+            msg_Dbg( p_input, "tuner %s low=%d high=%d, flags=0x%x "
+                     "mode=0x%x signal=0x%x",
+                     vid_tuner.name, vid_tuner.rangelow, vid_tuner.rangehigh,
+                     vid_tuner.flags, vid_tuner.mode, vid_tuner.signal );
+
+            msg_Dbg( p_input, "setting tuner %s (%d)",
                      vid_tuner.name, vid_tuner.tuner );
 
             //vid_tuner.mode = p_sys->i_norm; /* FIXME FIXME to be checked FIXME FIXME */
@@ -576,20 +583,23 @@ static int AccessOpen( vlc_object_t *p_this )
                 }
 
                 i_format = AFMT_S16_LE;
-                if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format ) < 0 ||
-                    i_format != AFMT_S16_LE )
+                if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format ) < 0
+                    || i_format != AFMT_S16_LE )
                 {
-                    msg_Err( p_input, "cannot set audio format (16b little endian)" );
+                    msg_Err( p_input,
+                             "cannot set audio format (16b little endian)" );
                     goto failed;
                 }
 
-                if( ioctl( p_sys->fd_audio, SNDCTL_DSP_STEREO, &p_sys->b_stereo ) < 0 )
+                if( ioctl( p_sys->fd_audio, SNDCTL_DSP_STEREO,
+                           &p_sys->b_stereo ) < 0 )
                 {
                     msg_Err( p_input, "cannot set audio channels count" );
                     goto failed;
                 }
 
-                if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate ) < 0 )
+                if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED,
+                           &p_sys->i_sample_rate ) < 0 )
                 {
                     msg_Err( p_input, "cannot set audio sample rate" );
                     goto failed;
@@ -603,7 +613,8 @@ static int AccessOpen( vlc_object_t *p_this )
 
                 p_sys->i_audio_frame_size = 0;
                 p_sys->i_audio_frame_size_allocated = 10*1024;
-                p_sys->p_audio_frame = malloc( p_sys->i_audio_frame_size_allocated );
+                p_sys->p_audio_frame =
+                    malloc( p_sys->i_audio_frame_size_allocated );
             }
 #endif
         }
@@ -625,6 +636,104 @@ static int AccessOpen( vlc_object_t *p_this )
         msg_Dbg( p_input, "will use %dx%d", p_sys->i_width, p_sys->i_height );
     }
 
+    p_sys->p_video_frame = NULL;
+
+    /* Find out video format used by device */
+    if( ioctl( p_sys->fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 )
+    {
+        int i_chroma, i;
+        struct video_picture vid_picture = p_sys->vid_picture;
+
+        /* Try to set the format to something easy to encode */
+        vid_picture.palette = VIDEO_PALETTE_YUV420P;
+        if( ioctl( p_sys->fd, VIDIOCSPICT, &vid_picture ) == 0 )
+        {
+            p_sys->vid_picture = vid_picture;
+        }
+        else
+        {
+            vid_picture.palette = VIDEO_PALETTE_YUV422P;
+            if( ioctl( p_sys->fd, VIDIOCSPICT, &vid_picture ) == 0 )
+            {
+                p_sys->vid_picture = vid_picture;
+            }
+        }
+
+        /* Find out final format */
+        switch( p_sys->vid_picture.palette )
+        {
+        case VIDEO_PALETTE_GREY:
+            i_chroma = VLC_FOURCC( 'G', 'R', 'E', 'Y' );
+            break;
+        case VIDEO_PALETTE_HI240:
+            i_chroma = VLC_FOURCC( 'I', '2', '4', '0' );
+            break;
+        case VIDEO_PALETTE_RGB565:
+            i_chroma = VLC_FOURCC( 'R', 'V', '1', '6' );
+            break;
+        case VIDEO_PALETTE_RGB555:
+            i_chroma = VLC_FOURCC( 'R', 'V', '1', '5' );
+            break;
+        case VIDEO_PALETTE_RGB24:
+            i_chroma = VLC_FOURCC( 'R', 'V', '2', '4' );
+            break;
+        case VIDEO_PALETTE_RGB32:
+            i_chroma = VLC_FOURCC( 'R', 'V', '3', '2' );
+            break;
+        case VIDEO_PALETTE_YUV422:
+            i_chroma = VLC_FOURCC( 'I', '4', '2', '2' );
+            break;
+        case VIDEO_PALETTE_YUYV:
+            i_chroma = VLC_FOURCC( 'Y', 'U', 'Y', 'V' );
+            break;
+        case VIDEO_PALETTE_UYVY:
+            i_chroma = VLC_FOURCC( 'U', 'Y', 'V', 'Y' );
+            break;
+        case VIDEO_PALETTE_YUV420:
+            i_chroma = VLC_FOURCC( 'I', '4', '2', 'N' );
+            break;
+        case VIDEO_PALETTE_YUV411:
+            i_chroma = VLC_FOURCC( 'I', '4', '1', 'N' );
+            break;
+        case VIDEO_PALETTE_RAW:
+            i_chroma = VLC_FOURCC( 'G', 'R', 'A', 'W' );
+            break;
+        case VIDEO_PALETTE_YUV422P:
+            i_chroma = VLC_FOURCC( 'I', '4', '2', '2' );
+            break;
+        case VIDEO_PALETTE_YUV411P:
+            i_chroma = VLC_FOURCC( 'I', '4', '1', '1' );
+            break;
+        }
+
+        p_sys->i_chroma = i_chroma;
+
+        /* Fill in picture_t fields */
+        vout_InitPicture( VLC_OBJECT(p_input), &p_sys->pic,
+                          p_sys->i_width, p_sys->i_height, p_sys->i_chroma );
+        if( !p_sys->pic.i_planes )
+        {
+            msg_Err( p_input, "unsupported chroma" );
+            goto failed;
+        }
+        p_sys->i_video_frame_size = 0;
+        for( i = 0; i < p_sys->pic.i_planes; i++ )
+        {
+            p_sys->i_video_frame_size += p_sys->pic.p[i].i_lines *
+              p_sys->pic.p[i].i_visible_pitch;
+        }
+
+        msg_Dbg( p_input, "v4l device uses frame size: %i",
+                 p_sys->i_video_frame_size );
+        msg_Dbg( p_input, "v4l device uses chroma: %4.4s", (char*)&i_chroma );
+    }
+    else
+    {
+        msg_Err( p_input, "ioctl VIDIOCGPICT failed" );
+        goto failed;
+    }
+
+    /* Allocate mmap buffer */
     if( ioctl( p_sys->fd, VIDIOCGMBUF, &p_sys->vid_mbuf ) < 0 )
     {
         msg_Err( p_input, "mmap unsupported" );
@@ -632,10 +741,8 @@ static int AccessOpen( vlc_object_t *p_this )
     }
 
     p_sys->p_video_mmap = mmap( 0, p_sys->vid_mbuf.size,
-                                PROT_READ|PROT_WRITE,
-                                MAP_SHARED,
-                                p_sys->fd,
-                                0 );
+                                PROT_READ|PROT_WRITE, MAP_SHARED,
+                                p_sys->fd, 0 );
     if( p_sys->p_video_mmap == MAP_FAILED )
     {
         /* FIXME -> normal read */
@@ -643,37 +750,18 @@ static int AccessOpen( vlc_object_t *p_this )
         goto failed;
     }
 
-    p_sys->p_video_frame = NULL;
-
     /* init grabbing */
     p_sys->vid_mmap.frame  = 0;
     p_sys->vid_mmap.width  = p_sys->i_width;
     p_sys->vid_mmap.height = p_sys->i_height;
-    p_sys->vid_mmap.format = VIDEO_PALETTE_YUV420P;
-    p_sys->i_chroma = VLC_FOURCC( 'I', '4', '2', '0' );
+    p_sys->vid_mmap.format = p_sys->vid_picture.palette;
     if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 )
     {
         msg_Warn( p_input, "%4.4s refused", (char*)&p_sys->i_chroma );
-
-        p_sys->vid_mmap.format = VIDEO_PALETTE_YUV422P;
-        p_sys->i_chroma = VLC_FOURCC( 'I', '4', '2', '2' );
-
-        if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 )
-        {
-            msg_Warn( p_input, "%4.4s refused", (char*)&p_sys->i_chroma );
-
-            msg_Err( p_input, "chroma selection failed" );
-            goto failed;
-        }
-        else
-        {
-            p_sys->i_video_frame_size = p_sys->i_width * p_sys->i_height * 2;
-        }
-    }
-    else
-    {
-        p_sys->i_video_frame_size = p_sys->i_width * p_sys->i_height * 3 / 2;
+        msg_Err( p_input, "chroma selection failed" );
+        goto failed;
     }
+
     /* encoder part */
     if( p_sys->i_codec != VLC_FOURCC( 0, 0, 0, 0 ) )
     {
@@ -690,13 +778,11 @@ static int AccessOpen( vlc_object_t *p_this )
         p_enc->i_aspect= 0;
 
 
-        p_enc->p_module = module_Need( p_enc,
-                                       "video encoder",
+        p_enc->p_module = module_Need( p_enc, "video encoder",
                                        "$video-encoder" );
         if( !p_enc->p_module )
         {
-            msg_Warn( p_input,
-                      "no suitable encoder to %4.4s",
+            msg_Warn( p_input, "no suitable encoder to %4.4s",
                       (char*)&p_enc->i_codec );
             vlc_object_destroy( p_enc );
             goto failed;
@@ -713,7 +799,7 @@ static int AccessOpen( vlc_object_t *p_this )
         /* *** alloacted buffer *** */
         if( p_enc->i_buffer_size <= 0 )
         {
-            p_enc->i_buffer_size = 10 * p_enc->i_width * p_enc->i_height;
+          p_enc->i_buffer_size = 1024 * 1024;// * p_enc->i_width * p_enc->i_height;
         }
         p_sys->i_video_frame_size = p_enc->i_buffer_size;
         p_sys->i_video_frame_size_allocated = p_enc->i_buffer_size;
@@ -722,31 +808,6 @@ static int AccessOpen( vlc_object_t *p_this )
             msg_Err( p_input, "out of memory" );
             goto failed;
         }
-
-        switch( p_sys->i_chroma )
-        {
-            case VLC_FOURCC( 'I', '4', '2', '0' ):
-                p_sys->pic.i_planes = 3;
-                p_sys->pic.p[0].i_pitch = p_sys->i_width;
-                p_sys->pic.p[0].i_lines = p_sys->i_height;
-                p_sys->pic.p[0].i_pixel_pitch = 1;
-                p_sys->pic.p[0].i_visible_pitch = p_sys->i_width;
-
-                p_sys->pic.p[1].i_pitch = p_sys->i_width / 2;
-                p_sys->pic.p[1].i_lines = p_sys->i_height / 2;
-                p_sys->pic.p[1].i_pixel_pitch = 1;
-                p_sys->pic.p[1].i_visible_pitch = p_sys->i_width / 2;
-
-                p_sys->pic.p[2].i_pitch = p_sys->i_width / 2;
-                p_sys->pic.p[2].i_lines = p_sys->i_height / 2;
-                p_sys->pic.p[2].i_pixel_pitch = 1;
-                p_sys->pic.p[2].i_visible_pitch = p_sys->i_width / 2;
-                break;
-            default:
-                msg_Err( p_input, "unsuported chroma" );
-                vlc_object_destroy( p_enc );
-                goto failed;
-        }
 #undef p_enc
     }
     else
@@ -884,7 +945,8 @@ static int GrabAudio( input_thread_t * p_input,
         return VLC_EGENERIC;
     }
 
-    i_read = read( p_sys->fd_audio, p_sys->p_audio_frame, p_sys->i_audio_frame_size_allocated );
+    i_read = read( p_sys->fd_audio, p_sys->p_audio_frame,
+                   p_sys->i_audio_frame_size_allocated );
 
     if( i_read <= 0 )
     {
@@ -900,13 +962,13 @@ static int GrabAudio( input_thread_t * p_input,
 }
 #endif
 
-static int GrabVideo( input_thread_t * p_input,
-                      uint8_t **pp_data,
-                      int      *pi_data )
+static int GrabVideo( input_thread_t * p_input, uint8_t **pp_data,
+                      int *pi_data )
 {
-    access_sys_t    *p_sys   = p_input->p_access_data;
+    access_sys_t *p_sys   = p_input->p_access_data;
 
-    p_sys->vid_mmap.frame = ( p_sys->i_frame_pos + 1 ) % p_sys->vid_mbuf.frames;
+    p_sys->vid_mmap.frame = ( p_sys->i_frame_pos + 1 ) %
+                            p_sys->vid_mbuf.frames;
     for( ;; )
     {
         if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) >= 0 )
@@ -932,21 +994,26 @@ static int GrabVideo( input_thread_t * p_input,
 
     if( p_sys->p_encoder )
     {
-        p_sys->pic.p[0].p_pixels = p_sys->p_video_mmap + p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
-        p_sys->pic.p[1].p_pixels = p_sys->pic.p[0].p_pixels +
-                                        p_sys->pic.p[0].i_pitch * p_sys->pic.p[0].i_lines;
-        p_sys->pic.p[2].p_pixels = p_sys->pic.p[1].p_pixels +
-                                        p_sys->pic.p[1].i_pitch * p_sys->pic.p[1].i_lines;
+        int i;
+
+        p_sys->pic.p[0].p_pixels = p_sys->p_video_mmap +
+            p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
+
+        for( i = 1; i < p_sys->pic.i_planes; i++ )
+        {
+            p_sys->pic.p[i].p_pixels = p_sys->pic.p[i-1].p_pixels +
+                p_sys->pic.p[i-1].i_pitch * p_sys->pic.p[i-1].i_lines;
+        }
 
         p_sys->i_video_frame_size = p_sys->i_video_frame_size_allocated;
-        p_sys->p_encoder->pf_encode( p_sys->p_encoder,
-                                     &p_sys->pic,
+        p_sys->p_encoder->pf_encode( p_sys->p_encoder, &p_sys->pic,
                                      p_sys->p_video_frame,
                                      &p_sys->i_video_frame_size );
     }
     else
     {
-        p_sys->p_video_frame = p_sys->p_video_mmap + p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
+        p_sys->p_video_frame = p_sys->p_video_mmap +
+                               p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
     }
 
     *pp_data = p_sys->p_video_frame;
@@ -960,17 +1027,16 @@ static int GrabVideo( input_thread_t * p_input,
  * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
  * bytes.
  *****************************************************************************/
-static int Read( input_thread_t * p_input, byte_t * p_buffer,
-                 size_t i_len )
+static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
 {
-    access_sys_t    *p_sys   = p_input->p_access_data;
+    access_sys_t *p_sys = p_input->p_access_data;
     int i_data = 0;
     int i_stream;
 
-    msg_Info( p_input, "access read" );
+    //msg_Info( p_input, "access read data_size %i, data_pos %i",
+                //p_sys->i_data_size, p_sys->i_data_pos );
     while( i_len > 0 )
     {
-
         /* First copy header if any */
         if( i_len > 0 && p_sys->i_header_pos < p_sys->i_header_size )
         {
@@ -978,9 +1044,7 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
 
             i_copy = __MIN( p_sys->i_header_size - p_sys->i_header_pos,
                             (int)i_len );
-            memcpy( p_buffer,
-                    &p_sys->p_header[p_sys->i_header_pos],
-                    i_copy );
+            memcpy( p_buffer, &p_sys->p_header[p_sys->i_header_pos], i_copy );
             p_sys->i_header_pos += i_copy;
 
             p_buffer += i_copy;
@@ -996,9 +1060,7 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
             i_copy = __MIN( p_sys->i_data_size - p_sys->i_data_pos,
                             (int)i_len );
 
-            memcpy( p_buffer,
-                    &p_sys->p_data[p_sys->i_data_pos],
-                    i_copy );
+            memcpy( p_buffer, &p_sys->p_data[p_sys->i_data_pos], i_copy );
             p_sys->i_data_pos += i_copy;
 
             p_buffer += i_copy;
@@ -1006,18 +1068,28 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
             i_data += i_copy;
         }
 
+        /* The caller got what he wanted */
         if( i_len <= 0 )
         {
             return( i_data );
         }
 
+        /* Read no more than one frame at a time.
+         * That kills latency, especially for encoded v4l streams */
+        if( p_sys->i_data_size && p_sys->i_data_pos == p_sys->i_data_size )
+        {
+            p_sys->i_data_pos = 0; p_sys->i_data_size = 0;
+            return( i_data );
+        }
+
         /* re fill data by grabbing audio/video */
         p_sys->i_data_pos = 0;
 
         /* try grabbing audio frames */
 #ifdef _V4L_AUDIO_
         i_stream = 1;
-        if( p_sys->fd_audio < 0 || GrabAudio( p_input, &p_sys->p_data, &p_sys->i_data_size ) )
+        if( p_sys->fd_audio < 0 ||
+            GrabAudio( p_input, &p_sys->p_data, &p_sys->i_data_size ) )
         {
             /* and then get video frame if no audio */
             i_stream = 0;
@@ -1050,7 +1122,7 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
  ****************************************************************************/
 #define MAX_PACKETS_IN_FIFO 3
 
-static int  DemuxOpen  ( vlc_object_t *p_this )
+static int DemuxOpen( vlc_object_t *p_this )
 {
     input_thread_t *p_input = (input_thread_t *)p_this;
     //demux_sys_t    *p_sys;
@@ -1100,7 +1172,8 @@ static int  DemuxOpen  ( vlc_object_t *p_this )
     p_input->stream.i_mux_rate =  0;
 
     i_streams = GetDWBE( &p_peek[4] );
-    if( input_Peek( p_input, &p_peek, 8 + 20 * i_streams ) < 8 + 20 * i_streams )
+    if( input_Peek( p_input, &p_peek, 8 + 20 * i_streams )
+        < 8 + 20 * i_streams )
     {
         msg_Err( p_input, "v4l plugin discarded (cannot peek)" );
         return( VLC_EGENERIC );
@@ -1111,14 +1184,16 @@ static int  DemuxOpen  ( vlc_object_t *p_this )
     {
         es_descriptor_t *p_es;
 
-
-        p_es = input_AddES( p_input, p_input->stream.pp_programs[0], i + 1, 0 );
+        p_es = input_AddES( p_input,
+                            p_input->stream.pp_programs[0], i + 1, 0 );
         p_es->i_stream_id   = i + 1;
         if( !strncmp( p_peek, "auds", 4 ) )
         {
 #define wf ((WAVEFORMATEX*)p_es->p_waveformatex)
             p_es->i_cat         = AUDIO_ES;
-            p_es->i_fourcc      = VLC_FOURCC( p_peek[4], p_peek[5], p_peek[6], p_peek[7] );
+            p_es->i_fourcc      =
+                VLC_FOURCC( p_peek[4], p_peek[5], p_peek[6], p_peek[7] );
+
             p_es->p_waveformatex= malloc( sizeof( WAVEFORMATEX ) );
 
             wf->wFormatTag      = WAVE_FORMAT_UNKNOWN;
@@ -1130,8 +1205,7 @@ static int  DemuxOpen  ( vlc_object_t *p_this )
             wf->cbSize          = 0;
 
             msg_Dbg( p_input, "added new audio es %d channels %dHz",
-                     wf->nChannels,
-                     wf->nSamplesPerSec );
+                     wf->nChannels, wf->nSamplesPerSec );
 
             input_SelectES( p_input, p_es );
 #undef wf
@@ -1140,7 +1214,8 @@ static int  DemuxOpen  ( vlc_object_t *p_this )
         {
 #define bih ((BITMAPINFOHEADER*)p_es->p_bitmapinfoheader)
             p_es->i_cat = VIDEO_ES;
-            p_es->i_fourcc      = VLC_FOURCC( p_peek[4], p_peek[5], p_peek[6], p_peek[7] );
+            p_es->i_fourcc  =
+                VLC_FOURCC( p_peek[4], p_peek[5], p_peek[6], p_peek[7] );
 
             p_es->p_bitmapinfoheader = malloc( sizeof( BITMAPINFOHEADER ) );
 
@@ -1157,9 +1232,7 @@ static int  DemuxOpen  ( vlc_object_t *p_this )
             bih->biClrImportant     = 0;
 
             msg_Dbg( p_input, "added new video es %4.4s %dx%d",
-                     (char*)&p_es->i_fourcc,
-                     bih->biWidth,
-                     bih->biHeight );
+                     (char*)&p_es->i_fourcc, bih->biWidth, bih->biHeight );
 
             input_SelectES( p_input, p_es );
 #undef bih
@@ -1180,13 +1253,12 @@ static int  DemuxOpen  ( vlc_object_t *p_this )
     return VLC_SUCCESS;
 }
 
-static void DemuxClose ( vlc_object_t *p_this )
+static void DemuxClose( vlc_object_t *p_this )
 {
     return;
 }
 
-
-static int  Demux      ( input_thread_t *p_input )
+static int Demux( input_thread_t *p_input )
 {
     es_descriptor_t *p_es;
     pes_packet_t    *p_pes;
@@ -1204,7 +1276,7 @@ static int  Demux      ( input_thread_t *p_input )
     i_stream = GetDWBE( &p_peek[0] );
     i_size   = GetDWBE( &p_peek[4] );
 
-    msg_Dbg( p_input, "stream=%d size=%d", i_stream, i_size );
+    //msg_Dbg( p_input, "stream=%d size=%d", i_stream, i_size );
 //    p_es = input_FindES( p_input, i_stream );
     p_es = p_input->stream.p_selected_program->pp_es[i_stream];
 
@@ -1227,8 +1299,7 @@ static int  Demux      ( input_thread_t *p_input )
         data_packet_t   *p_data;
         int i_read;
 
-        if( (i_read = input_SplitBuffer( p_input,
-                                         &p_data,
+        if( (i_read = input_SplitBuffer( p_input, &p_data,
                                          __MIN( i_size, 10000 ) ) ) <= 0 )
         {
             input_DeletePES( p_input->p_method_data, p_pes );
@@ -1256,7 +1327,8 @@ static int  Demux      ( input_thread_t *p_input )
     if( p_es->p_decoder_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
     {
         /* Wait for the decoder. */
-        vlc_cond_wait( &p_es->p_decoder_fifo->data_wait, &p_es->p_decoder_fifo->data_lock );
+        vlc_cond_wait( &p_es->p_decoder_fifo->data_wait,
+                       &p_es->p_decoder_fifo->data_lock );
     }
     vlc_mutex_unlock( &p_es->p_decoder_fifo->data_lock );
 
index de85678..1ac37d4 100644 (file)
@@ -2,7 +2,7 @@
  * rawvideo.c: Pseudo audio decoder; for raw video data
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: rawvideo.c,v 1.3 2003/04/27 17:53:20 gbazin Exp $
+ * $Id: rawvideo.c,v 1.4 2003/04/27 23:16:35 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -161,7 +161,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
  *****************************************************************************/
 static int InitThread( vdec_thread_t * p_vdec )
 {
-    picture_t *p_pic;
+    picture_t pic;
     int i;
 
 #define bih ((BITMAPINFOHEADER*)p_vdec->p_fifo->p_bitmapinfoheader)
@@ -187,27 +187,19 @@ static int InitThread( vdec_thread_t * p_vdec )
 
     if( p_vdec->p_vout == NULL )
     {
-        msg_Err( p_vdec->p_fifo, "failled created vout" );
-        return( VLC_EGENERIC );
-    }
-
-    /* Get a 1 picture to be able to compute p_vdec->i_raw_size */
-    p_pic = vout_CreatePicture( p_vdec->p_vout, 0, 0, 0 );
-    if( p_pic == NULL )
-    {
-        msg_Err( p_vdec->p_fifo, "failled to get a vout picture" );
+        msg_Err( p_vdec->p_fifo, "failed created vout" );
         return( VLC_EGENERIC );
     }
 
+    /* Find out p_vdec->i_raw_size */
+    vout_InitPicture( VLC_OBJECT(p_vdec->p_fifo), &pic,
+                      bih->biWidth, bih->biHeight, p_vdec->p_fifo->i_fourcc );
     p_vdec->i_raw_size = 0;
-    for( i = 0; i < p_pic->i_planes; i++ )
+    for( i = 0; i < pic.i_planes; i++ )
     {
-        p_vdec->i_raw_size += p_pic->p[i].i_lines * p_pic->p[i].i_visible_pitch
-            * p_pic->p[i].i_pixel_pitch;
+        p_vdec->i_raw_size += pic.p[i].i_lines * pic.p[i].i_visible_pitch;
     }
 
-    vout_DestroyPicture( p_vdec->p_vout, p_pic );
-
     return( VLC_SUCCESS );
 #undef bih
 }
@@ -284,8 +276,9 @@ static void DecodeThread( vdec_thread_t *p_vdec )
 
     if( i_size < p_vdec->i_raw_size )
     {
-        msg_Warn( p_vdec->p_fifo, "invalid frame size (%d < %d)", i_size, p_vdec->i_raw_size );
-        input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
+        msg_Warn( p_vdec->p_fifo, "invalid frame size (%d < %d)",
+                  i_size, p_vdec->i_raw_size );
+        //input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
         return;
     }
 
index b3c59d5..486170c 100644 (file)
@@ -2,7 +2,7 @@
  * encoder.c : audio/video encoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: encoder.c,v 1.3 2003/04/26 14:54:49 gbazin Exp $
+ * $Id: encoder.c,v 1.4 2003/04/27 23:16:35 gbazin Exp $
  *
  * Authors: Laurent Aimar
  *
@@ -48,19 +48,18 @@ void E_( CloseEncoderAudio )( vlc_object_t * );
  *****************************************************************************/
 
 vlc_module_begin();
-    set_description( _("ffmpeg encoder") );
+    set_description( _("ffmpeg video encoder") );
     add_shortcut( "ffmpeg" );
+    set_capability( "video encoder", 100 );
+    set_callbacks( E_( OpenEncoderVideo ), E_( CloseEncoderVideo ) );
+    add_category_hint( "video setting", NULL, VLC_TRUE );
+        add_integer( "encoder-ffmpeg-video-bitrate", 1000, NULL, "bitrate (kb/s)", "bitrate (kb/s)", VLC_TRUE );
+        add_integer( "encoder-ffmpeg-video-max-key-interval", 10, NULL, "max key interval", "maximum   value  of   frames  between   two  keyframes", VLC_TRUE );
+        add_integer( "encoder-ffmpeg-video-min-quant", 2, NULL, "min quantizer", "range 1-31", VLC_TRUE );
+        add_integer( "encoder-ffmpeg-video-max-quant", 31, NULL, "max quantizer", "range 1-31", VLC_TRUE );
 
     add_submodule();
-        set_capability( "video encoder", 100 );
-        set_callbacks( E_( OpenEncoderVideo ), E_( CloseEncoderVideo ) );
-        add_category_hint( "video setting", NULL, VLC_TRUE );
-            add_integer( "encoder-ffmpeg-video-bitrate", 1000, NULL, "bitrate (kb/s)", "bitrate (kb/s)", VLC_TRUE );
-            add_integer( "encoder-ffmpeg-video-max-key-interval", 10, NULL, "max key interval", "maximum   value  of   frames  between   two  keyframes", VLC_TRUE );
-            add_integer( "encoder-ffmpeg-video-min-quant", 2, NULL, "min quantizer", "range 1-31", VLC_TRUE );
-            add_integer( "encoder-ffmpeg-video-max-quant", 31, NULL, "max quantizer", "range 1-31", VLC_TRUE );
-
-    add_submodule();
+        set_description( _("ffmpeg audio encoder") );
         set_capability( "audio encoder", 50 );
         set_callbacks( E_( OpenEncoderAudio ), E_( CloseEncoderAudio ) );
         add_category_hint( "audio setting", NULL, VLC_TRUE );
index 18a4795..00475b3 100644 (file)
@@ -2,7 +2,7 @@
  * video.c : video encoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: video.c,v 1.3 2003/04/26 14:54:49 gbazin Exp $
+ * $Id: video.c,v 1.4 2003/04/27 23:16:35 gbazin Exp $
  *
  * Authors: Laurent Aimar
  *
@@ -49,7 +49,7 @@ void E_( CloseEncoderVideo )( vlc_object_t * );
  *****************************************************************************/
 static int  Init     ( video_encoder_t *p_encoder );
 static int  Encode   ( video_encoder_t *p_encoder,
-                               picture_t *p_pic, void *p_data, size_t *pi_data );
+                       picture_t *p_pic, void *p_data, size_t *pi_data );
 static void End      ( video_encoder_t *p_encoder );
 
 /*****************************************************************************
@@ -70,7 +70,7 @@ struct encoder_sys_t
  *****************************************************************************
  *
  *****************************************************************************/
-int  E_( OpenEncoderVideo ) ( vlc_object_t *p_this )
+int E_( OpenEncoderVideo ) ( vlc_object_t *p_this )
 {
     video_encoder_t *p_encoder = (video_encoder_t*)p_this;
 
@@ -91,16 +91,27 @@ int  E_( OpenEncoderVideo ) ( vlc_object_t *p_this )
     avcodec_register_all();
 
     /* *** fix parameters *** */
-    /* FIXME be clever, some codec support additional chroma */
-    if( p_encoder->i_chroma != VLC_FOURCC( 'I', '4', '2', '0' ) )
     switch( p_encoder->i_chroma )
     {
-        case VLC_FOURCC( 'I', '4', '2', '0' ):
-        case VLC_FOURCC( 'I', '4', '2', '2' ):
-        case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
+        /* Planar YUV formats */
+        case VLC_FOURCC('I','4','4','4'):
+        case VLC_FOURCC('I','4','2','2'):
+        case VLC_FOURCC('Y','V','1','2'):
+        case VLC_FOURCC('I','4','2','0'):
+        case VLC_FOURCC('I','Y','U','V'):
+        case VLC_FOURCC('I','4','1','1'):
+        case VLC_FOURCC('I','4','1','0'):
+        /* Packed YUV formats */
+        case VLC_FOURCC('Y','U','Y','2'):
+        case VLC_FOURCC('U','Y','V','Y'):
+        /* Packed RGB formats */
+        case VLC_FOURCC('R','V','3','2'):
+        case VLC_FOURCC('R','V','2','4'):
+        case VLC_FOURCC('R','V','1','6'):
+        case VLC_FOURCC('R','V','1','5'):
+        case VLC_FOURCC('R','G','B','2'):
             break;
         default:
-            p_encoder->i_chroma = VLC_FOURCC( 'I', '4', '2', '0' );
             return VLC_EGENERIC;
     }
 #if 0
@@ -161,7 +172,8 @@ static int  Init     ( video_encoder_t *p_encoder )
     }
     if( ( p_sys->p_codec = avcodec_find_encoder( i_codec ) ) == NULL )
     {
-        msg_Err( p_encoder, "cannot find encoder for %s", p_encoder->p_sys->psz_codec );
+        msg_Err( p_encoder, "cannot find encoder for %s",
+                 p_encoder->p_sys->psz_codec );
         return VLC_EGENERIC;
     }
 
@@ -185,7 +197,8 @@ static int  Init     ( video_encoder_t *p_encoder )
 
     if( avcodec_open( p_context, p_encoder->p_sys->p_codec ) < 0 )
     {
-        msg_Err( p_encoder, "failed to open %s codec", p_encoder->p_sys->psz_codec );
+        msg_Err( p_encoder, "failed to open %s codec",
+                 p_encoder->p_sys->psz_codec );
         return VLC_EGENERIC;
     }
 
@@ -193,15 +206,59 @@ static int  Init     ( video_encoder_t *p_encoder )
 
     switch( p_encoder->i_chroma )
     {
-        case VLC_FOURCC( 'I', '4', '2', '0' ):
-            p_frame->pict_type = PIX_FMT_YUV420P;
+        /* Planar YUV formats */
+        case VLC_FOURCC('I','4','4','4'):
+            p_frame->pict_type = PIX_FMT_YUV444P;
             break;
-        case VLC_FOURCC( 'I', '4', '2', '2' ):
+
+        case VLC_FOURCC('I','4','2','2'):
             p_frame->pict_type = PIX_FMT_YUV422P;
             break;
-        case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
+
+        case VLC_FOURCC('Y','V','1','2'):
+        case VLC_FOURCC('I','4','2','0'):
+        case VLC_FOURCC('I','Y','U','V'):
+            p_frame->pict_type = PIX_FMT_YUV420P;
+            break;
+
+        case VLC_FOURCC('I','4','1','1'):
+            p_frame->pict_type = PIX_FMT_YUV411P;
+            break;
+
+        case VLC_FOURCC('I','4','1','0'):
+            p_frame->pict_type = PIX_FMT_YUV410P;
+            break;
+
+        /* Packed YUV formats */
+
+        case VLC_FOURCC('Y','U','Y','2'):
+        case VLC_FOURCC('U','Y','V','Y'):
             p_frame->pict_type = PIX_FMT_YUV422;
             break;
+           
+        /* Packed RGB formats */
+
+        case VLC_FOURCC('R','V','3','2'):
+            p_frame->pict_type = PIX_FMT_RGBA32;
+            break;
+
+        case VLC_FOURCC('R','V','2','4'):
+            p_frame->pict_type = PIX_FMT_RGB24;
+            //p_frame->pict_type = PIX_FMT_BGR24;
+            break;
+
+        case VLC_FOURCC('R','V','1','6'):
+            p_frame->pict_type = PIX_FMT_RGB565;
+            break;
+
+        case VLC_FOURCC('R','V','1','5'):
+            p_frame->pict_type = PIX_FMT_RGB555;
+            break;
+
+        case VLC_FOURCC('R','G','B','2'):
+            p_frame->pict_type = PIX_FMT_GRAY8;
+            break;
+
         default:
             return VLC_EGENERIC;
     }
@@ -217,14 +274,14 @@ static int  Init     ( video_encoder_t *p_encoder )
  *****************************************************************************
  *
  *****************************************************************************/
-static int  Encode   ( video_encoder_t *p_encoder,
-                       picture_t *p_pic, void *p_data, size_t *pi_data )
+static int Encode( video_encoder_t *p_encoder,
+                   picture_t *p_pic, void *p_data, size_t *pi_data )
 {
 #define p_frame   p_encoder->p_sys->p_frame
 #define p_context p_encoder->p_sys->p_context
     int i;
 
-    for( i = 0; i < 3; i++ )
+    for( i = 0; i < p_pic->i_planes; i++ )
     {
         p_frame->linesize[i] = p_pic->p[i].i_pitch;
         p_frame->data[i]     = p_pic->p[i].p_pixels;
@@ -241,7 +298,7 @@ static int  Encode   ( video_encoder_t *p_encoder,
  *****************************************************************************
  *
  *****************************************************************************/
-static void End      ( video_encoder_t *p_encoder )
+static void End( video_encoder_t *p_encoder )
 {
     avcodec_close( p_encoder->p_sys->p_context );
     free( p_encoder->p_sys->p_context );
index 3dff161..71cbe6c 100644 (file)
@@ -2,7 +2,7 @@
  * vout_pictures.c : picture management functions
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: vout_pictures.c,v 1.38 2003/04/27 17:53:21 gbazin Exp $
+ * $Id: vout_pictures.c,v 1.39 2003/04/27 23:16:35 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -438,6 +438,44 @@ void vout_AllocatePicture( vout_thread_t *p_vout, picture_t *p_pic,
 {
     int i_bytes, i_index;
 
+    vout_InitPicture( VLC_OBJECT(p_vout), p_pic, i_width, i_height, i_chroma );
+
+    /* Calculate how big the new image should be */
+    for( i_bytes = 0, i_index = 0; i_index < p_pic->i_planes; i_index++ )
+    {
+        i_bytes += p_pic->p[ i_index ].i_lines * p_pic->p[ i_index ].i_pitch;
+    }
+
+    p_pic->p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_bytes );
+
+    if( p_pic->p_data == NULL )
+    {
+        p_pic->i_planes = 0;
+        return;
+    }
+
+    /* Fill the p_pixels field for each plane */
+    p_pic->p[ 0 ].p_pixels = p_pic->p_data;
+
+    for( i_index = 1; i_index < p_pic->i_planes; i_index++ )
+    {
+        p_pic->p[i_index].p_pixels = p_pic->p[i_index-1].p_pixels
+                                          + p_pic->p[i_index-1].i_lines
+                                             * p_pic->p[i_index-1].i_pitch;
+    }
+}
+
+/*****************************************************************************
+ * vout_InitPicture: initialise the picture_t fields given chroma/size.
+ *****************************************************************************
+ * This function initializes most of the picture_t fields given a chroma and
+ * size. It makes the assumption that stride == width.
+ *****************************************************************************/
+void vout_InitPicture( vlc_object_t *p_this, picture_t *p_pic,
+                       int i_width, int i_height, vlc_fourcc_t i_chroma )
+{
+    int i_index;
+
     /* Store default values */
     for( i_index = 0; i_index < VOUT_MAX_PLANES; i_index++ )
     {
@@ -588,35 +626,12 @@ void vout_AllocatePicture( vout_thread_t *p_vout, picture_t *p_pic,
             break;
 
         default:
-            msg_Err( p_vout, "unknown chroma type 0x%.8x (%4.4s)",
+            msg_Err( p_this, "unknown chroma type 0x%.8x (%4.4s)",
                              i_chroma, (char*)&i_chroma );
             p_pic->i_planes = 0;
             return;
     }
 
-    /* Calculate how big the new image should be */
-    for( i_bytes = 0, i_index = 0; i_index < p_pic->i_planes; i_index++ )
-    {
-        i_bytes += p_pic->p[ i_index ].i_lines * p_pic->p[ i_index ].i_pitch;
-    }
-
-    p_pic->p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_bytes );
-
-    if( p_pic->p_data == NULL )
-    {
-        p_pic->i_planes = 0;
-        return;
-    }
-
-    /* Fill the p_pixels field for each plane */
-    p_pic->p[ 0 ].p_pixels = p_pic->p_data;
-
-    for( i_index = 1; i_index < p_pic->i_planes; i_index++ )
-    {
-        p_pic->p[i_index].p_pixels = p_pic->p[i_index-1].p_pixels
-                                          + p_pic->p[i_index-1].i_lines
-                                             * p_pic->p[i_index-1].i_pitch;
-    }
 }
 
 /*****************************************************************************