Commit 9bdee3da authored by Gildas Bazin's avatar Gildas Bazin

* modules/stream_out/transcode.c: added a floating point "scale" option for...

* modules/stream_out/transcode.c: added a floating point "scale" option for video transcoding. When specified, you don't need to specify the width and height of the output video.
 Also changed the width and height options so that if only one of them is specified, the other one is calculated automatically so as to keep the aspect ratio of the video.
* modules/mux/ogg.c: fixed crash when removing streams.
* modules/codec/theora.c: for now the theora encoder requires a width and height which are multiple of 16.
parent 52c090f1
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* theora.c: theora decoder module making use of libtheora. * theora.c: theora decoder module making use of libtheora.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: theora.c,v 1.18 2003/12/07 18:15:46 gbazin Exp $ * $Id: theora.c,v 1.19 2003/12/08 13:02:39 gbazin Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -447,6 +447,15 @@ static int OpenEncoder( vlc_object_t *p_this ) ...@@ -447,6 +447,15 @@ static int OpenEncoder( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( p_enc->fmt_in.video.i_width % 16 ||
p_enc->fmt_in.video.i_height % 16 )
{
msg_Err( p_enc, "Theora video encoding requires dimensions which are "
"multiples of 16. Which is not the case here (%dx%d)",
p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height );
return VLC_EGENERIC;
}
/* Allocate the memory needed to store the decoder's structure */ /* Allocate the memory needed to store the decoder's structure */
if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ogg.c: ogg muxer module for vlc * ogg.c: ogg muxer module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: ogg.c,v 1.25 2003/12/07 17:09:33 gbazin Exp $ * $Id: ogg.c,v 1.26 2003/12/08 13:02:40 gbazin Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@netcourrier.com>
...@@ -485,7 +485,8 @@ static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -485,7 +485,8 @@ static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
{ {
int i; int i;
if( ( p_og = OggStreamFlush( p_mux, &p_stream->os, 0 ) ) ) if( !p_stream->b_new &&
( p_og = OggStreamFlush( p_mux, &p_stream->os, 0 ) ) )
{ {
OggSetDate( p_og, p_stream->i_dts, p_stream->i_length ); OggSetDate( p_og, p_stream->i_dts, p_stream->i_length );
sout_AccessOutWrite( p_mux->p_access, p_og ); sout_AccessOutWrite( p_mux->p_access, p_og );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* transcode.c * transcode.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: transcode.c,v 1.62 2003/12/07 19:09:37 jpsaman Exp $ * $Id: transcode.c,v 1.63 2003/12/08 13:02:40 gbazin Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@netcourrier.com>
...@@ -94,6 +94,7 @@ struct sout_stream_sys_t ...@@ -94,6 +94,7 @@ struct sout_stream_sys_t
vlc_fourcc_t i_vcodec; /* " video " " " " */ vlc_fourcc_t i_vcodec; /* " video " " " " */
int i_vbitrate; int i_vbitrate;
int i_vtolerance; int i_vtolerance;
double f_scale;
int i_width; int i_width;
int i_height; int i_height;
int i_b_frames; int i_b_frames;
...@@ -128,6 +129,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -128,6 +129,7 @@ static int Open( vlc_object_t *p_this )
memset( p_sys, 0, sizeof(struct sout_stream_sys_t) ); memset( p_sys, 0, sizeof(struct sout_stream_sys_t) );
p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next ); p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
p_sys->f_scale = 1;
p_sys->i_vtolerance = -1; p_sys->i_vtolerance = -1;
p_sys->i_key_int = -1; p_sys->i_key_int = -1;
p_sys->i_qmin = 2; p_sys->i_qmin = 2;
...@@ -178,6 +180,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -178,6 +180,10 @@ static int Open( vlc_object_t *p_this )
p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
if( ( val = sout_cfg_find_value( p_stream->p_cfg, "scale" ) ) )
{
p_sys->f_scale = atof( val );
}
if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) ) if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
{ {
p_sys->i_width = atoi( val ); p_sys->i_width = atoi( val );
...@@ -274,9 +280,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -274,9 +280,8 @@ static int Open( vlc_object_t *p_this )
p_sys->i_qmax = atoi( val ); p_sys->i_qmax = atoi( val );
} }
msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s", msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
fcc, fcc, p_sys->i_width, p_sys->i_height, p_sys->f_scale,
p_sys->i_width, p_sys->i_height,
p_sys->i_vbitrate / 1024 ); p_sys->i_vbitrate / 1024 );
} }
...@@ -286,10 +291,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -286,10 +291,10 @@ static int Open( vlc_object_t *p_this )
free( p_sys ); free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_stream->pf_add = Add; p_stream->pf_add = Add;
p_stream->pf_del = Del; p_stream->pf_del = Del;
p_stream->pf_send = Send; p_stream->pf_send = Send;
p_stream->p_sys = p_sys; p_stream->p_sys = p_sys;
avcodec_init(); avcodec_init();
...@@ -407,8 +412,8 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt ) ...@@ -407,8 +412,8 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
/* create dst format */ /* create dst format */
id->f_dst.i_cat = VIDEO_ES; id->f_dst.i_cat = VIDEO_ES;
id->f_dst.i_codec = p_sys->i_vcodec; id->f_dst.i_codec = p_sys->i_vcodec;
id->f_dst.video.i_width = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */ id->f_dst.video.i_width = p_sys->i_width;
id->f_dst.video.i_height= p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */ id->f_dst.video.i_height= p_sys->i_height;
id->f_dst.i_bitrate = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000; id->f_dst.i_bitrate = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
id->f_dst.i_extra = 0; id->f_dst.i_extra = 0;
id->f_dst.p_extra = NULL; id->f_dst.p_extra = NULL;
...@@ -474,11 +479,17 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, ...@@ -474,11 +479,17 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
sout_buffer_t *p_buffer_out; sout_buffer_t *p_buffer_out;
if( id->f_src.i_cat == AUDIO_ES ) if( id->f_src.i_cat == AUDIO_ES )
{ {
transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out ); transcode_audio_ffmpeg_process( p_stream, id, p_buffer,
&p_buffer_out );
} }
else if( id->f_src.i_cat == VIDEO_ES ) else if( id->f_src.i_cat == VIDEO_ES )
{ {
transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out ); if( transcode_video_ffmpeg_process( p_stream, id, p_buffer,
&p_buffer_out ) != VLC_SUCCESS )
{
sout_BufferDelete( p_stream->p_sout, p_buffer );
return VLC_EGENERIC;
}
} }
sout_BufferDelete( p_stream->p_sout, p_buffer ); sout_BufferDelete( p_stream->p_sout, p_buffer );
...@@ -1023,21 +1034,12 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream, ...@@ -1023,21 +1034,12 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
/* Initialization of encoder format structures */ /* Initialization of encoder format structures */
es_format_Init( &id->p_encoder->fmt_in, es_format_Init( &id->p_encoder->fmt_in,
id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) ); id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width;
id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height;
if( id->p_encoder->fmt_in.video.i_width <= 0 ) /* The dimensions will be set properly later on.
{ * Just put sensible values so we can test if there is an encoder. */
id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width = id->p_encoder->fmt_in.video.i_width = 16;
id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right; id->p_encoder->fmt_in.video.i_height = 16;
}
if( id->p_encoder->fmt_in.video.i_height <= 0 )
{
id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height =
id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
}
id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */ id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
id->p_encoder->fmt_in.video.i_frame_rate_base= 1; id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
...@@ -1212,23 +1214,40 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, ...@@ -1212,23 +1214,40 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
if( !id->b_enc_inited ) if( !id->b_enc_inited )
{ {
/* XXX hack because of copy packetizer and mpeg4video that can fail /* Hack because of the copy packetizer which can fail to detect the
* detecting size */ * proper size (which forces us to wait until the 1st frame
if( id->p_encoder->fmt_in.video.i_width <= 0 ) * is decoded) */
int i_width = id->ff_dec_c->width - p_sys->i_crop_left -
p_sys->i_crop_right;
int i_height = id->ff_dec_c->height - p_sys->i_crop_top -
p_sys->i_crop_bottom;
if( id->f_dst.video.i_width <= 0 && id->f_dst.video.i_height <= 0 )
{ {
id->p_encoder->fmt_in.video.i_width = /* Apply the scaling */
id->p_encoder->fmt_out.video.i_width = id->f_dst.video.i_width = id->f_dst.video.i_width = i_width * p_sys->f_scale;
id->ff_dec_c->width - p_sys->i_crop_left - id->f_dst.video.i_height = i_height * p_sys->f_scale;
p_sys->i_crop_right;
} }
if( id->p_encoder->fmt_in.video.i_height <= 0 ) else if( id->f_dst.video.i_width > 0 &&
id->f_dst.video.i_height <= 0 )
{ {
id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height =
id->p_encoder->fmt_out.video.i_height = id->f_dst.video.i_height = id->f_dst.video.i_width / (double)i_width * i_height;
id->ff_dec_c->height - p_sys->i_crop_top - }
p_sys->i_crop_bottom; else if( id->f_dst.video.i_width <= 0 &&
id->f_dst.video.i_height > 0 )
{
id->f_dst.video.i_width =
id->f_dst.video.i_height / (double)i_height * i_width;
} }
id->p_encoder->fmt_in.video.i_width =
id->p_encoder->fmt_out.video.i_width =
id->f_dst.video.i_width;
id->p_encoder->fmt_in.video.i_height =
id->p_encoder->fmt_out.video.i_height =
id->f_dst.video.i_height;
id->p_encoder->fmt_out.i_extra = 0; id->p_encoder->fmt_out.i_extra = 0;
id->p_encoder->fmt_out.p_extra = NULL; id->p_encoder->fmt_out.p_extra = NULL;
...@@ -1238,6 +1257,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, ...@@ -1238,6 +1257,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
{ {
vlc_object_destroy( id->p_encoder ); vlc_object_destroy( id->p_encoder );
msg_Err( p_stream, "cannot find encoder" ); msg_Err( p_stream, "cannot find encoder" );
id->b_transcode = VLC_FALSE;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -1343,7 +1363,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, ...@@ -1343,7 +1363,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
if( id->ff_dec_c->width != id->f_dst.video.i_width || if( id->ff_dec_c->width != id->f_dst.video.i_width ||
id->ff_dec_c->height != id->f_dst.video.i_height || id->ff_dec_c->height != id->f_dst.video.i_height ||
p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 || p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
p_sys->i_crop_left > 0 || p_sys->i_crop_right ) p_sys->i_crop_left > 0 || p_sys->i_crop_right > 0 )
{ {
if( id->p_ff_pic_tmp2 == NULL ) if( id->p_ff_pic_tmp2 == NULL )
{ {
......
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