Commit c556378f authored by Gildas Bazin's avatar Gildas Bazin

* src/video_output/vout_pictures.c, include/video_output.h: added a vout_InitPicture() function that initializes a picture_t structure based on the given chroma and sizes.
* 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.
parent 15fb1485
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* thread, and destroy a previously opened video output thread. * thread, and destroy a previously opened video output thread.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@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, ...@@ -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( 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( 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_AllocatePicture,( vout_thread_t *, picture_t *, int, int, uint32_t ) );
VLC_EXPORT( void, vout_DestroyPicture, ( vout_thread_t *, picture_t * ) ); VLC_EXPORT( void, vout_DestroyPicture, ( vout_thread_t *, picture_t * ) );
VLC_EXPORT( void, vout_DisplayPicture, ( vout_thread_t *, picture_t * ) ); VLC_EXPORT( void, vout_DisplayPicture, ( vout_thread_t *, picture_t * ) );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* v4l.c : Video4Linux input module for vlc * v4l.c : Video4Linux input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Author: Samuel Hocevar <sam@zoy.org>
* *
...@@ -76,11 +76,12 @@ vlc_module_begin(); ...@@ -76,11 +76,12 @@ vlc_module_begin();
add_category_hint( N_("v4l"), NULL, VLC_TRUE ); add_category_hint( N_("v4l"), NULL, VLC_TRUE );
add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL, add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL,
CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
add_submodule();
add_shortcut( "v4l" ); add_shortcut( "v4l" );
set_capability( "access", 0 ); set_capability( "access", 10 );
set_callbacks( AccessOpen, AccessClose ); set_callbacks( AccessOpen, AccessClose );
add_submodule(); add_submodule();
set_description( _("Video4Linux demuxer") );
add_shortcut( "v4l" ); add_shortcut( "v4l" );
set_capability( "demux", 200 ); set_capability( "demux", 200 );
set_callbacks( DemuxOpen, DemuxClose ); set_callbacks( DemuxOpen, DemuxClose );
...@@ -114,6 +115,7 @@ struct access_sys_t ...@@ -114,6 +115,7 @@ struct access_sys_t
uint8_t *p_video_mmap; uint8_t *p_video_mmap;
int i_frame_pos; int i_frame_pos;
struct video_mmap vid_mmap; struct video_mmap vid_mmap;
struct video_picture vid_picture;
uint8_t *p_video_frame; uint8_t *p_video_frame;
int i_video_frame_size; int i_video_frame_size;
...@@ -240,8 +242,8 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -240,8 +242,8 @@ static int AccessOpen( vlc_object_t *p_this )
*psz_parser++ = '\0'; *psz_parser++ = '\0';
if( !strncmp( psz_parser, "channel=", strlen( "channel=" ) ) ) if( !strncmp( psz_parser, "channel=", strlen( "channel=" ) ) )
{ {
p_sys->i_channel = p_sys->i_channel = strtol( psz_parser + strlen( "channel=" ),
strtol( psz_parser + strlen( "channel=" ), &psz_parser, 0 ); &psz_parser, 0 );
} }
else if( !strncmp( psz_parser, "norm=", strlen( "norm=" ) ) ) else if( !strncmp( psz_parser, "norm=", strlen( "norm=" ) ) )
{ {
...@@ -271,14 +273,17 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -271,14 +273,17 @@ static int AccessOpen( vlc_object_t *p_this )
p_sys->i_norm = strtol( psz_parser, &psz_parser, 0 ); 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 = 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=" ) ) ) 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=" ) ) ) else if( !strncmp( psz_parser, "size=", strlen( "size=" ) ) )
{ {
...@@ -319,14 +324,17 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -319,14 +324,17 @@ static int AccessOpen( vlc_object_t *p_this )
p_sys->i_width = strtol( psz_parser, &psz_parser, 0 ); p_sys->i_width = strtol( psz_parser, &psz_parser, 0 );
if( *psz_parser == 'x' || *psz_parser == 'X') 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=" ) ) ) 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=" ) ) ) else if( !strncmp( psz_parser, "codec=", strlen( "codec=" ) ) )
{ {
...@@ -363,9 +371,12 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -363,9 +371,12 @@ static int AccessOpen( vlc_object_t *p_this )
psz_parser += i_len; 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" ) ) ) else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )
{ {
...@@ -509,16 +520,12 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -509,16 +520,12 @@ static int AccessOpen( vlc_object_t *p_this )
msg_Err( p_input, "cannot get tuner" ); msg_Err( p_input, "cannot get tuner" );
goto failed; goto failed;
} }
msg_Dbg( p_input, msg_Dbg( p_input, "tuner %s low=%d high=%d, flags=0x%x "
"tuner %s low=%d high=%d, flags=0x%x mode=0x%x signal=0x%x", "mode=0x%x signal=0x%x",
vid_tuner.name, vid_tuner.name, vid_tuner.rangelow, vid_tuner.rangehigh,
vid_tuner.rangelow, vid_tuner.rangehigh, vid_tuner.flags, vid_tuner.mode, vid_tuner.signal );
vid_tuner.flags,
vid_tuner.mode,
vid_tuner.signal );
msg_Dbg( p_input, msg_Dbg( p_input, "setting tuner %s (%d)",
"setting tuner %s (%d)",
vid_tuner.name, vid_tuner.tuner ); vid_tuner.name, vid_tuner.tuner );
//vid_tuner.mode = p_sys->i_norm; /* FIXME FIXME to be checked FIXME FIXME */ //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 ) ...@@ -576,20 +583,23 @@ static int AccessOpen( vlc_object_t *p_this )
} }
i_format = AFMT_S16_LE; i_format = AFMT_S16_LE;
if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format ) < 0 || if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format ) < 0
i_format != AFMT_S16_LE ) || 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; 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" ); msg_Err( p_input, "cannot set audio channels count" );
goto failed; 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" ); msg_Err( p_input, "cannot set audio sample rate" );
goto failed; goto failed;
...@@ -603,7 +613,8 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -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 = 0;
p_sys->i_audio_frame_size_allocated = 10*1024; 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 #endif
} }
...@@ -625,6 +636,104 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -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 ); 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 ) if( ioctl( p_sys->fd, VIDIOCGMBUF, &p_sys->vid_mbuf ) < 0 )
{ {
msg_Err( p_input, "mmap unsupported" ); msg_Err( p_input, "mmap unsupported" );
...@@ -632,10 +741,8 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -632,10 +741,8 @@ static int AccessOpen( vlc_object_t *p_this )
} }
p_sys->p_video_mmap = mmap( 0, p_sys->vid_mbuf.size, p_sys->p_video_mmap = mmap( 0, p_sys->vid_mbuf.size,
PROT_READ|PROT_WRITE, PROT_READ|PROT_WRITE, MAP_SHARED,
MAP_SHARED, p_sys->fd, 0 );
p_sys->fd,
0 );
if( p_sys->p_video_mmap == MAP_FAILED ) if( p_sys->p_video_mmap == MAP_FAILED )
{ {
/* FIXME -> normal read */ /* FIXME -> normal read */
...@@ -643,37 +750,18 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -643,37 +750,18 @@ static int AccessOpen( vlc_object_t *p_this )
goto failed; goto failed;
} }
p_sys->p_video_frame = NULL;
/* init grabbing */ /* init grabbing */
p_sys->vid_mmap.frame = 0; p_sys->vid_mmap.frame = 0;
p_sys->vid_mmap.width = p_sys->i_width; p_sys->vid_mmap.width = p_sys->i_width;
p_sys->vid_mmap.height = p_sys->i_height; p_sys->vid_mmap.height = p_sys->i_height;
p_sys->vid_mmap.format = VIDEO_PALETTE_YUV420P; p_sys->vid_mmap.format = p_sys->vid_picture.palette;
p_sys->i_chroma = VLC_FOURCC( 'I', '4', '2', '0' );
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 ) if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 )
{ {
msg_Warn( p_input, "%4.4s refused", (char*)&p_sys->i_chroma ); msg_Warn( p_input, "%4.4s refused", (char*)&p_sys->i_chroma );
msg_Err( p_input, "chroma selection failed" ); msg_Err( p_input, "chroma selection failed" );
goto 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;
}
/* encoder part */ /* encoder part */
if( p_sys->i_codec != VLC_FOURCC( 0, 0, 0, 0 ) ) if( p_sys->i_codec != VLC_FOURCC( 0, 0, 0, 0 ) )
{ {
...@@ -690,13 +778,11 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -690,13 +778,11 @@ static int AccessOpen( vlc_object_t *p_this )
p_enc->i_aspect= 0; p_enc->i_aspect= 0;
p_enc->p_module = module_Need( p_enc, p_enc->p_module = module_Need( p_enc, "video encoder",
"video encoder",
"$video-encoder" ); "$video-encoder" );
if( !p_enc->p_module ) if( !p_enc->p_module )
{ {
msg_Warn( p_input, msg_Warn( p_input, "no suitable encoder to %4.4s",
"no suitable encoder to %4.4s",
(char*)&p_enc->i_codec ); (char*)&p_enc->i_codec );
vlc_object_destroy( p_enc ); vlc_object_destroy( p_enc );
goto failed; goto failed;
...@@ -713,7 +799,7 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -713,7 +799,7 @@ static int AccessOpen( vlc_object_t *p_this )
/* *** alloacted buffer *** */ /* *** alloacted buffer *** */
if( p_enc->i_buffer_size <= 0 ) 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 = p_enc->i_buffer_size;
p_sys->i_video_frame_size_allocated = 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 ) ...@@ -722,31 +808,6 @@ static int AccessOpen( vlc_object_t *p_this )
msg_Err( p_input, "out of memory" ); msg_Err( p_input, "out of memory" );
goto failed; 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 #undef p_enc
} }
else else
...@@ -884,7 +945,8 @@ static int GrabAudio( input_thread_t * p_input, ...@@ -884,7 +945,8 @@ static int GrabAudio( input_thread_t * p_input,
return VLC_EGENERIC; 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 ) if( i_read <= 0 )
{ {
...@@ -900,13 +962,13 @@ static int GrabAudio( input_thread_t * p_input, ...@@ -900,13 +962,13 @@ static int GrabAudio( input_thread_t * p_input,
} }
#endif #endif
static int GrabVideo( input_thread_t * p_input, static int GrabVideo( input_thread_t * p_input, uint8_t **pp_data,
uint8_t **pp_data,
int *pi_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( ;; ) for( ;; )
{ {
if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) >= 0 ) if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) >= 0 )
...@@ -932,21 +994,26 @@ static int GrabVideo( input_thread_t * p_input, ...@@ -932,21 +994,26 @@ static int GrabVideo( input_thread_t * p_input,
if( p_sys->p_encoder ) 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]; int i;
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[0].p_pixels = p_sys->p_video_mmap +
p_sys->pic.p[2].p_pixels = p_sys->pic.p[1].p_pixels + p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
p_sys->pic.p[1].i_pitch * p_sys->pic.p[1].i_lines;
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->i_video_frame_size = p_sys->i_video_frame_size_allocated;
p_sys->p_encoder->pf_encode( p_sys->p_encoder, p_sys->p_encoder->pf_encode( p_sys->p_encoder, &p_sys->pic,
&p_sys->pic,
p_sys->p_video_frame, p_sys->p_video_frame,
&p_sys->i_video_frame_size ); &p_sys->i_video_frame_size );
} }
else 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; *pp_data = p_sys->p_video_frame;
...@@ -960,17 +1027,16 @@ static int GrabVideo( input_thread_t * p_input, ...@@ -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 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* bytes. * bytes.
*****************************************************************************/ *****************************************************************************/
static int Read( input_thread_t * p_input, byte_t * p_buffer, static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
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_data = 0;
int i_stream; 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 ) while( i_len > 0 )
{ {
/* First copy header if any */ /* First copy header if any */
if( i_len > 0 && p_sys->i_header_pos < p_sys->i_header_size ) 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, ...@@ -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, i_copy = __MIN( p_sys->i_header_size - p_sys->i_header_pos,
(int)i_len ); (int)i_len );
memcpy( p_buffer, memcpy( p_buffer, &p_sys->p_header[p_sys->i_header_pos], i_copy );
&p_sys->p_header[p_sys->i_header_pos],
i_copy );
p_sys->i_header_pos += i_copy; p_sys->i_header_pos += i_copy;
p_buffer += i_copy; p_buffer += i_copy;
...@@ -996,9 +1060,7 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, ...@@ -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, i_copy = __MIN( p_sys->i_data_size - p_sys->i_data_pos,
(int)i_len ); (int)i_len );
memcpy( p_buffer, memcpy( p_buffer, &p_sys->p_data[p_sys->i_data_pos], i_copy );
&p_sys->p_data[p_sys->i_data_pos],
i_copy );
p_sys->i_data_pos += i_copy; p_sys->i_data_pos += i_copy;
p_buffer += i_copy; p_buffer += i_copy;
...@@ -1006,18 +1068,28 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, ...@@ -1006,18 +1068,28 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
i_data += i_copy; i_data += i_copy;
} }
/* The caller got what he wanted */
if( i_len <= 0 ) if( i_len <= 0 )
{ {
return( i_data ); 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 */ /* re fill data by grabbing audio/video */
p_sys->i_data_pos = 0; p_sys->i_data_pos = 0;
/* try grabbing audio frames */ /* try grabbing audio frames */
#ifdef _V4L_AUDIO_ #ifdef _V4L_AUDIO_
i_stream = 1; 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 */ /* and then get video frame if no audio */
i_stream = 0; i_stream = 0;
...@@ -1050,7 +1122,7 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, ...@@ -1050,7 +1122,7 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
****************************************************************************/ ****************************************************************************/
#define MAX_PACKETS_IN_FIFO 3 #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; input_thread_t *p_input = (input_thread_t *)p_this;
//demux_sys_t *p_sys; //demux_sys_t *p_sys;
...@@ -1100,7 +1172,8 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -1100,7 +1172,8 @@ static int DemuxOpen ( vlc_object_t *p_this )
p_input->stream.i_mux_rate = 0; p_input->stream.i_mux_rate = 0;
i_streams = GetDWBE( &p_peek[4] ); 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)" ); msg_Err( p_input, "v4l plugin discarded (cannot peek)" );
return( VLC_EGENERIC ); return( VLC_EGENERIC );
...@@ -1111,14 +1184,16 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -1111,14 +1184,16 @@ static int DemuxOpen ( vlc_object_t *p_this )
{ {
es_descriptor_t *p_es; es_descriptor_t *p_es;
p_es = input_AddES( p_input,
p_es = input_AddES( p_input, p_input->stream.pp_programs[0], i + 1, 0 ); p_input->stream.pp_programs[0], i + 1, 0 );
p_es->i_stream_id = i + 1; p_es->i_stream_id = i + 1;
if( !strncmp( p_peek, "auds", 4 ) ) if( !strncmp( p_peek, "auds", 4 ) )
{ {
#define wf ((WAVEFORMATEX*)p_es->p_waveformatex) #define wf ((WAVEFORMATEX*)p_es->p_waveformatex)
p_es->i_cat = AUDIO_ES; 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 ) ); p_es->p_waveformatex= malloc( sizeof( WAVEFORMATEX ) );
wf->wFormatTag = WAVE_FORMAT_UNKNOWN; wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
...@@ -1130,8 +1205,7 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -1130,8 +1205,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
wf->cbSize = 0; wf->cbSize = 0;
msg_Dbg( p_input, "added new audio es %d channels %dHz", msg_Dbg( p_input, "added new audio es %d channels %dHz",
wf->nChannels, wf->nChannels, wf->nSamplesPerSec );
wf->nSamplesPerSec );
input_SelectES( p_input, p_es ); input_SelectES( p_input, p_es );
#undef wf #undef wf
...@@ -1140,7 +1214,8 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -1140,7 +1214,8 @@ static int DemuxOpen ( vlc_object_t *p_this )
{ {
#define bih ((BITMAPINFOHEADER*)p_es->p_bitmapinfoheader) #define bih ((BITMAPINFOHEADER*)p_es->p_bitmapinfoheader)
p_es->i_cat = VIDEO_ES; 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 ) ); p_es->p_bitmapinfoheader = malloc( sizeof( BITMAPINFOHEADER ) );
...@@ -1157,9 +1232,7 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -1157,9 +1232,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
bih->biClrImportant = 0; bih->biClrImportant = 0;
msg_Dbg( p_input, "added new video es %4.4s %dx%d", msg_Dbg( p_input, "added new video es %4.4s %dx%d",
(char*)&p_es->i_fourcc, (char*)&p_es->i_fourcc, bih->biWidth, bih->biHeight );
bih->biWidth,
bih->biHeight );
input_SelectES( p_input, p_es ); input_SelectES( p_input, p_es );
#undef bih #undef bih
...@@ -1180,13 +1253,12 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -1180,13 +1253,12 @@ static int DemuxOpen ( vlc_object_t *p_this )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void DemuxClose ( vlc_object_t *p_this ) static void DemuxClose( vlc_object_t *p_this )
{ {
return; return;
} }
static int Demux( input_thread_t *p_input )
static int Demux ( input_thread_t *p_input )
{ {
es_descriptor_t *p_es; es_descriptor_t *p_es;
pes_packet_t *p_pes; pes_packet_t *p_pes;
...@@ -1204,7 +1276,7 @@ static int Demux ( input_thread_t *p_input ) ...@@ -1204,7 +1276,7 @@ static int Demux ( input_thread_t *p_input )
i_stream = GetDWBE( &p_peek[0] ); i_stream = GetDWBE( &p_peek[0] );
i_size = GetDWBE( &p_peek[4] ); 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 = input_FindES( p_input, i_stream );
p_es = p_input->stream.p_selected_program->pp_es[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 ) ...@@ -1227,8 +1299,7 @@ static int Demux ( input_thread_t *p_input )
data_packet_t *p_data; data_packet_t *p_data;
int i_read; int i_read;
if( (i_read = input_SplitBuffer( p_input, if( (i_read = input_SplitBuffer( p_input, &p_data,
&p_data,
__MIN( i_size, 10000 ) ) ) <= 0 ) __MIN( i_size, 10000 ) ) ) <= 0 )
{ {
input_DeletePES( p_input->p_method_data, p_pes ); input_DeletePES( p_input->p_method_data, p_pes );
...@@ -1256,7 +1327,8 @@ static int Demux ( input_thread_t *p_input ) ...@@ -1256,7 +1327,8 @@ static int Demux ( input_thread_t *p_input )
if( p_es->p_decoder_fifo->i_depth >= MAX_PACKETS_IN_FIFO ) if( p_es->p_decoder_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
{ {
/* Wait for the decoder. */ /* 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 ); vlc_mutex_unlock( &p_es->p_decoder_fifo->data_lock );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* rawvideo.c: Pseudo audio decoder; for raw video data * rawvideo.c: Pseudo audio decoder; for raw video data
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -161,7 +161,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -161,7 +161,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
*****************************************************************************/ *****************************************************************************/
static int InitThread( vdec_thread_t * p_vdec ) static int InitThread( vdec_thread_t * p_vdec )
{ {
picture_t *p_pic; picture_t pic;
int i; int i;
#define bih ((BITMAPINFOHEADER*)p_vdec->p_fifo->p_bitmapinfoheader) #define bih ((BITMAPINFOHEADER*)p_vdec->p_fifo->p_bitmapinfoheader)
...@@ -187,27 +187,19 @@ static int InitThread( vdec_thread_t * p_vdec ) ...@@ -187,27 +187,19 @@ static int InitThread( vdec_thread_t * p_vdec )
if( p_vdec->p_vout == NULL ) if( p_vdec->p_vout == NULL )
{ {
msg_Err( p_vdec->p_fifo, "failled created vout" ); msg_Err( p_vdec->p_fifo, "failed 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" );
return( VLC_EGENERIC ); 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; 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_vdec->i_raw_size += pic.p[i].i_lines * pic.p[i].i_visible_pitch;
* p_pic->p[i].i_pixel_pitch;
} }
vout_DestroyPicture( p_vdec->p_vout, p_pic );
return( VLC_SUCCESS ); return( VLC_SUCCESS );
#undef bih #undef bih
} }
...@@ -284,8 +276,9 @@ static void DecodeThread( vdec_thread_t *p_vdec ) ...@@ -284,8 +276,9 @@ static void DecodeThread( vdec_thread_t *p_vdec )
if( i_size < p_vdec->i_raw_size ) 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 ); msg_Warn( p_vdec->p_fifo, "invalid frame size (%d < %d)",
input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes ); i_size, p_vdec->i_raw_size );
//input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
return; return;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* encoder.c : audio/video encoder using ffmpeg library * encoder.c : audio/video encoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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 * Authors: Laurent Aimar
* *
...@@ -48,10 +48,8 @@ void E_( CloseEncoderAudio )( vlc_object_t * ); ...@@ -48,10 +48,8 @@ void E_( CloseEncoderAudio )( vlc_object_t * );
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); vlc_module_begin();
set_description( _("ffmpeg encoder") ); set_description( _("ffmpeg video encoder") );
add_shortcut( "ffmpeg" ); add_shortcut( "ffmpeg" );
add_submodule();
set_capability( "video encoder", 100 ); set_capability( "video encoder", 100 );
set_callbacks( E_( OpenEncoderVideo ), E_( CloseEncoderVideo ) ); set_callbacks( E_( OpenEncoderVideo ), E_( CloseEncoderVideo ) );
add_category_hint( "video setting", NULL, VLC_TRUE ); add_category_hint( "video setting", NULL, VLC_TRUE );
...@@ -61,6 +59,7 @@ vlc_module_begin(); ...@@ -61,6 +59,7 @@ vlc_module_begin();
add_integer( "encoder-ffmpeg-video-max-quant", 31, NULL, "max quantizer", "range 1-31", VLC_TRUE ); add_integer( "encoder-ffmpeg-video-max-quant", 31, NULL, "max quantizer", "range 1-31", VLC_TRUE );
add_submodule(); add_submodule();
set_description( _("ffmpeg audio encoder") );
set_capability( "audio encoder", 50 ); set_capability( "audio encoder", 50 );
set_callbacks( E_( OpenEncoderAudio ), E_( CloseEncoderAudio ) ); set_callbacks( E_( OpenEncoderAudio ), E_( CloseEncoderAudio ) );
add_category_hint( "audio setting", NULL, VLC_TRUE ); add_category_hint( "audio setting", NULL, VLC_TRUE );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video.c : video encoder using ffmpeg library * video.c : video encoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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 * Authors: Laurent Aimar
* *
...@@ -91,16 +91,27 @@ int E_( OpenEncoderVideo ) ( vlc_object_t *p_this ) ...@@ -91,16 +91,27 @@ int E_( OpenEncoderVideo ) ( vlc_object_t *p_this )
avcodec_register_all(); avcodec_register_all();
/* *** fix parameters *** */ /* *** 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 ) switch( p_encoder->i_chroma )
{ {
case VLC_FOURCC( 'I', '4', '2', '0' ): /* Planar YUV formats */
case VLC_FOURCC( 'I', '4', '2', '2' ): case VLC_FOURCC('I','4','4','4'):
case VLC_FOURCC( 'Y', 'U', 'Y', '2' ): 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; break;
default: default:
p_encoder->i_chroma = VLC_FOURCC( 'I', '4', '2', '0' );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
#if 0 #if 0
...@@ -161,7 +172,8 @@ static int Init ( video_encoder_t *p_encoder ) ...@@ -161,7 +172,8 @@ static int Init ( video_encoder_t *p_encoder )
} }
if( ( p_sys->p_codec = avcodec_find_encoder( i_codec ) ) == NULL ) 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; return VLC_EGENERIC;
} }
...@@ -185,7 +197,8 @@ static int Init ( video_encoder_t *p_encoder ) ...@@ -185,7 +197,8 @@ static int Init ( video_encoder_t *p_encoder )
if( avcodec_open( p_context, p_encoder->p_sys->p_codec ) < 0 ) 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; return VLC_EGENERIC;
} }
...@@ -193,15 +206,59 @@ static int Init ( video_encoder_t *p_encoder ) ...@@ -193,15 +206,59 @@ static int Init ( video_encoder_t *p_encoder )
switch( p_encoder->i_chroma ) switch( p_encoder->i_chroma )
{ {
case VLC_FOURCC( 'I', '4', '2', '0' ): /* Planar YUV formats */
p_frame->pict_type = PIX_FMT_YUV420P; case VLC_FOURCC('I','4','4','4'):
p_frame->pict_type = PIX_FMT_YUV444P;
break; break;
case VLC_FOURCC( 'I', '4', '2', '2' ):
case VLC_FOURCC('I','4','2','2'):
p_frame->pict_type = PIX_FMT_YUV422P; p_frame->pict_type = PIX_FMT_YUV422P;
break; 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; p_frame->pict_type = PIX_FMT_YUV422;
break; 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: default:
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -217,14 +274,14 @@ static int Init ( video_encoder_t *p_encoder ) ...@@ -217,14 +274,14 @@ static int Init ( video_encoder_t *p_encoder )
***************************************************************************** *****************************************************************************
* *
*****************************************************************************/ *****************************************************************************/
static int Encode ( 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 )
{ {
#define p_frame p_encoder->p_sys->p_frame #define p_frame p_encoder->p_sys->p_frame
#define p_context p_encoder->p_sys->p_context #define p_context p_encoder->p_sys->p_context
int i; 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->linesize[i] = p_pic->p[i].i_pitch;
p_frame->data[i] = p_pic->p[i].p_pixels; p_frame->data[i] = p_pic->p[i].p_pixels;
...@@ -241,7 +298,7 @@ static int Encode ( video_encoder_t *p_encoder, ...@@ -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 ); avcodec_close( p_encoder->p_sys->p_context );
free( p_encoder->p_sys->p_context ); free( p_encoder->p_sys->p_context );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_pictures.c : picture management functions * vout_pictures.c : picture management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -438,6 +438,44 @@ void vout_AllocatePicture( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -438,6 +438,44 @@ void vout_AllocatePicture( vout_thread_t *p_vout, picture_t *p_pic,
{ {
int i_bytes, i_index; 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 */ /* Store default values */
for( i_index = 0; i_index < VOUT_MAX_PLANES; i_index++ ) 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, ...@@ -588,35 +626,12 @@ void vout_AllocatePicture( vout_thread_t *p_vout, picture_t *p_pic,
break; break;
default: 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 ); i_chroma, (char*)&i_chroma );
p_pic->i_planes = 0; p_pic->i_planes = 0;
return; 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;
}
} }
/***************************************************************************** /*****************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment