]> git.sesse.net Git - vlc/commitdiff
* modules/stream_out/transcode.c: added a floating point "scale" option for video...
authorGildas Bazin <gbazin@videolan.org>
Mon, 8 Dec 2003 13:02:40 +0000 (13:02 +0000)
committerGildas Bazin <gbazin@videolan.org>
Mon, 8 Dec 2003 13:02:40 +0000 (13:02 +0000)
 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.

modules/codec/theora.c
modules/mux/ogg.c
modules/stream_out/transcode.c

index 9f8f8250a7b8f2b85f114a2a6f17dc18c08716e9..9cf88858574987066b6a8bb039804c041c5ba43a 100644 (file)
@@ -2,7 +2,7 @@
  * theora.c: theora decoder module making use of libtheora.
  *****************************************************************************
  * 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>
  *
@@ -447,6 +447,15 @@ static int OpenEncoder( vlc_object_t *p_this )
         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 */
     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
     {
index dd02beacc7028b7ee061b36dc86b3a62bad94251..83e8014c1f3e4facbc071e97a36a3eeb07b02f42 100644 (file)
@@ -2,7 +2,7 @@
  * ogg.c: ogg muxer module for vlc
  *****************************************************************************
  * 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>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -485,7 +485,8 @@ static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
     {
         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 );
             sout_AccessOutWrite( p_mux->p_access, p_og );
index ef8bf2167e98aae5c968f0e897eff84fa2ec1512..e532aa5b83ba438d5a065afd0168c3e1de4517f0 100644 (file)
@@ -2,7 +2,7 @@
  * transcode.c
  *****************************************************************************
  * 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>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -94,6 +94,7 @@ struct sout_stream_sys_t
     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
     int             i_vbitrate;
     int             i_vtolerance;
+    double          f_scale;
     int             i_width;
     int             i_height;
     int             i_b_frames;
@@ -128,6 +129,7 @@ static int Open( vlc_object_t *p_this )
     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->f_scale      = 1;
     p_sys->i_vtolerance = -1;
     p_sys->i_key_int    = -1;
     p_sys->i_qmin       = 2;
@@ -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] );
 
+        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" ) ) )
         {
             p_sys->i_width = atoi( val );
@@ -274,9 +280,8 @@ static int Open( vlc_object_t *p_this )
             p_sys->i_qmax   = atoi( val );
         }
 
-        msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
-                 fcc,
-                 p_sys->i_width, p_sys->i_height,
+        msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
+                 fcc, p_sys->i_width, p_sys->i_height, p_sys->f_scale,
                  p_sys->i_vbitrate / 1024 );
     }
 
@@ -286,10 +291,10 @@ static int Open( vlc_object_t *p_this )
         free( p_sys );
         return VLC_EGENERIC;
     }
+
     p_stream->pf_add    = Add;
     p_stream->pf_del    = Del;
     p_stream->pf_send   = Send;
-
     p_stream->p_sys     = p_sys;
 
     avcodec_init();
@@ -407,8 +412,8 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
         /* create dst format */
         id->f_dst.i_cat         = VIDEO_ES;
         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_height= p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
+        id->f_dst.video.i_width = p_sys->i_width;
+        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_extra       = 0;
         id->f_dst.p_extra       = NULL;
@@ -474,11 +479,17 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
         sout_buffer_t *p_buffer_out;
         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 )
         {
-            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 );
 
@@ -1023,21 +1034,12 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
 
     /* Initialization of encoder format structures */
     es_format_Init( &id->p_encoder->fmt_in,
-                   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;
+                    id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
 
-    if( id->p_encoder->fmt_in.video.i_width <= 0 )
-    {
-        id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width =
-            id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
-    }
-    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;
-    }
+    /* 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 = 16;
+    id->p_encoder->fmt_in.video.i_height = 16;
 
     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;
@@ -1212,23 +1214,40 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
 
         if( !id->b_enc_inited )
         {
-            /* XXX hack because of copy packetizer and mpeg4video that can fail
-             * detecting size */
-            if( id->p_encoder->fmt_in.video.i_width <= 0 )
+            /* Hack because of the copy packetizer which can fail to detect the
+             * proper size (which forces us to wait until the 1st frame
+             * 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 =
-                  id->p_encoder->fmt_out.video.i_width = id->f_dst.video.i_width =
-                    id->ff_dec_c->width - p_sys->i_crop_left -
-                      p_sys->i_crop_right;
+                /* Apply the scaling */
+                id->f_dst.video.i_width = i_width * p_sys->f_scale;
+                id->f_dst.video.i_height = i_height * p_sys->f_scale;
             }
-            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->p_encoder->fmt_out.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->f_dst.video.i_height =
+                    id->f_dst.video.i_width / (double)i_width * i_height;
+            }
+            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.p_extra = NULL;
 
@@ -1238,6 +1257,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
             {
                 vlc_object_destroy( id->p_encoder );
                 msg_Err( p_stream, "cannot find encoder" );
+                id->b_transcode = VLC_FALSE;
                 return VLC_EGENERIC;
             }
 
@@ -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 ||
             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_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 )
             {