]> git.sesse.net Git - vlc/blobdiff - modules/codec/theora.c
* modules/stream_out/transcode.c: added a floating point "scale" option for video...
[vlc] / modules / codec / theora.c
index 5ab139cb40217cbfeafd87f9ff3d7a634daf083a..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.15 2003/11/22 23:39:14 fenrir Exp $
+ * $Id: theora.c,v 1.19 2003/12/08 13:02:39 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -26,6 +26,7 @@
  *****************************************************************************/
 #include <vlc/vlc.h>
 #include <vlc/decoder.h>
+#include "input_ext-plugins.h"
 
 #include <ogg/ogg.h>
 
@@ -199,7 +200,7 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         p_dec->fmt_out.video.i_height = p_sys->ti.height;
 
         if( p_sys->ti.aspect_denominator )
-            p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
+            p_dec->fmt_out.video.i_aspect = ((int64_t)VOUT_ASPECT_FACTOR) *
                 p_sys->ti.aspect_numerator / p_sys->ti.aspect_denominator;
         else
             p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
@@ -446,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 )
     {
@@ -462,8 +472,6 @@ static int OpenEncoder( vlc_object_t *p_this )
 #define frame_y_offset 0
 #define video_hzn 25
 #define video_hzd 1
-#define video_an 4
-#define video_ad 3
 #define video_q 5
 
     theora_info_init( &p_sys->ti );
@@ -476,9 +484,18 @@ static int OpenEncoder( vlc_object_t *p_this )
     p_sys->ti.offset_y = frame_y_offset;
     p_sys->ti.fps_numerator = video_hzn;
     p_sys->ti.fps_denominator = video_hzd;
-    p_sys->ti.aspect_numerator = video_an;
-    p_sys->ti.aspect_denominator = video_ad;
-    p_sys->ti.colorspace = not_specified;
+
+    if( p_enc->fmt_in.video.i_aspect )
+    {
+        p_sys->ti.aspect_numerator = p_enc->fmt_in.video.i_aspect;
+        p_sys->ti.aspect_denominator = VOUT_ASPECT_FACTOR;
+    }
+    else
+    {
+        p_sys->ti.aspect_numerator = 4;
+        p_sys->ti.aspect_denominator = 3;
+    }
+
     p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
     p_sys->ti.quality = video_q;
 
@@ -514,19 +531,27 @@ static block_t *Headers( encoder_t *p_enc )
     /* Create theora headers */
     if( !p_sys->b_headers )
     {
-        ogg_packet oggpackets[3];
+        ogg_packet oggpackets;
         int i;
 
-        theora_encode_header( &p_sys->td, &oggpackets[0] );
-        theora_encode_comment( &p_sys->tc, &oggpackets[1] );
-        theora_encode_tables( &p_sys->td, &oggpackets[2] );
-
         /* Ogg packet to block */
         for( i = 0; i < 3; i++ )
         {
-            block_t *p_block = block_New( p_enc, oggpackets[i].bytes );
-            memcpy( p_block->p_buffer, oggpackets[i].packet,
-                    oggpackets[i].bytes );
+            switch( i )
+            {
+            case 0:
+                theora_encode_header( &p_sys->td, &oggpackets );
+                break;
+            case 1:
+                theora_encode_comment( &p_sys->tc, &oggpackets );
+                break;
+            case 2:
+                theora_encode_tables( &p_sys->td, &oggpackets );
+                break;
+            }
+
+            block_t *p_block = block_New( p_enc, oggpackets.bytes );
+            memcpy( p_block->p_buffer, oggpackets.packet, oggpackets.bytes );
             p_block->i_dts = p_block->i_pts = p_block->i_length = 0;
             block_ChainAppend( &p_chain, p_block );
         }