]> granicus.if.org Git - handbrake/commitdiff
Theora.
authorsaintdev <no-reply@handbrake.fr>
Thu, 20 Mar 2008 02:40:02 +0000 (02:40 +0000)
committersaintdev <no-reply@handbrake.fr>
Thu, 20 Mar 2008 02:40:02 +0000 (02:40 +0000)
This adds the theora encoder to the Xcode project as well. It does not enable
anything in the Mac GUI, just allows it to build.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1350 b64f7644-9d1e-0410-96f1-a4d463321fa5

15 files changed:
Jamfile
contrib/Jamfile
contrib/version_libtheora.txt [new file with mode: 0644]
libhb/Jamfile
libhb/Makefile
libhb/common.h
libhb/enctheora.c [new file with mode: 0644]
libhb/hb.c
libhb/hb.h
libhb/internal.h
libhb/muxmkv.c
libhb/muxogm.c
libhb/work.c
macosx/HandBrake.xcodeproj/project.pbxproj
test/test.c

diff --git a/Jamfile b/Jamfile
index 6a2c5c59d4afcd666e78fe6e1c8cffd134c00903..f463bf2b95089d1464bd2e9e211c8ea83c621ce2 100644 (file)
--- a/Jamfile
+++ b/Jamfile
@@ -16,7 +16,8 @@ HANDBRAKE_LIBS = libhb.a
           contrib/lib/libvorbis.a     contrib/lib/libvorbisenc.a
           contrib/lib/libogg.a        contrib/lib/libsamplerate.a
           contrib/lib/libx264.a       contrib/lib/libxvidcore.a
-          contrib/lib/libmkv.a        contrib/lib/libswscale.a ;
+          contrib/lib/libmkv.a        contrib/lib/libswscale.a
+          contrib/lib/libtheora.a ;
 
 if $(OS) = UNKNOWN
 {
index 06cb557ec74b1d3d1b6b6828adf90abc1a5df679..891483102053b23e4f24ad4ef601b11a3c5fe7d4 100644 (file)
@@ -336,6 +336,24 @@ actions LibVorbisEnc
 }
 LibVorbisEnc $(SUBDIR)/lib/libvorbisenc.a : $(SUBDIR)/lib/libvorbis.a ;
 
+# libtheora
+rule LibTheora
+{
+    Depends $(<) : $(>) ;
+    Depends lib  : $(<) ;
+}
+actions LibTheora
+{
+    cd `dirname $(>)` && CONTRIB=`pwd` && rm -rf libtheora &&
+    (gzip -dc libtheora.tar.gz | tar xf - ) && cd libtheora &&
+    ./configure --prefix=$CONTRIB --with-ogg=$CONTRIB --with-vorbis=$CONTRIB --cache-file=$CONTRIB/config.cache --disable-shared \
+            --disable-oggtest --disable-vorbistest --disable-sdltest --disable-examples &&
+    $(MAKE) && $(MAKE) install &&
+    $(STRIP) $CONTRIB/lib/libtheora.a
+}
+Wget      $(SUBDIR)/libtheora.tar.gz : $(SUBDIR)/version_libtheora.txt ;
+LibTheora $(SUBDIR)/lib/libtheora.a  : $(SUBDIR)/libtheora.tar.gz ;
+
 # libx264
 rule LibX264
 {
diff --git a/contrib/version_libtheora.txt b/contrib/version_libtheora.txt
new file mode 100644 (file)
index 0000000..30401af
--- /dev/null
@@ -0,0 +1,2 @@
+http://download.m0k.org/handbrake/contrib/libtheora-1.0beta2.tar.gz
+
index bcf4a547122e328f5e4e7a83bd7d26aca09b27b1..4f20701c66937e319e70453a01587966a1b96a18 100644 (file)
@@ -11,7 +11,7 @@ ipodutil.cpp common.c hb.c ports.c scan.c work.c decmpeg2.c encavcodec.c update.
 demuxmpeg.c fifo.c render.c reader.c muxcommon.c muxmp4.c sync.c stream.c
 decsub.c deca52.c decdca.c encfaac.c declpcm.c encx264.c decavcodec.c encxvid.c
 muxavi.c enclame.c muxogm.c encvorbis.c dvd.c muxmkv.c deblock.c deinterlace.c 
-denoise.c detelecine.c lang.c ;
+denoise.c detelecine.c lang.c enctheora.c ;
 
 Library libhb : $(LIBHB_SRC) ;
 
index 5b193854b27e310a9772178cd4c8d96442fb5b5b..fb05e5a50cecb7fe2862442d9f7072b0c27c5e6f 100644 (file)
@@ -21,7 +21,7 @@ ifeq ($(SYSTEM),Linux)
        LDFLAGS += -lpthread -lm -ldl
 endif
 
-SRCS = common.c hb.c ports.c scan.c work.c decmpeg2.c encavcodec.c \
+SRCS = common.c hb.c ports.c scan.c work.c decmpeg2.c encavcodec.c enctheora.c \
           update.c demuxmpeg.c fifo.c render.c reader.c muxcommon.c stream.c \
           muxmp4.c sync.c decsub.c deca52.c decdca.c encfaac.c declpcm.c encx264.c \
           decavcodec.c encxvid.c muxmkv.c muxavi.c enclame.c muxogm.c encvorbis.c \
@@ -39,7 +39,8 @@ CONTRIBS = ../contrib/lib/liba52.a ../contrib/lib/libavformat.a \
                   ../contrib/lib/libvorbisfile.a ../contrib/lib/libogg.a \
                   ../contrib/lib/libsamplerate.a ../contrib/lib/libx264.a \
                   ../contrib/lib/libxvidcore.a  ../contrib/lib/libmp4v2.a \
-                  ../contrib/lib/libmkv.a ../contrib/lib/libswscale.a
+                  ../contrib/lib/libmkv.a ../contrib/lib/libswscale.a \
+                  ../contrib/lib/libtheora.a
 else
 CONTRIBS = ../contrib/lib/liba52.a ../contrib/lib/libavformat.a \
                   ../contrib/lib/libavcodec.a ../contrib/lib/libavutil.a \
@@ -51,7 +52,7 @@ CONTRIBS = ../contrib/lib/liba52.a ../contrib/lib/libavformat.a \
                   ../contrib/lib/libogg.a ../contrib/lib/libsamplerate.a \
                   ../contrib/lib/libx264.a ../contrib/lib/libxvidcore.a \
                   ../contrib/lib/libmp4v2.a ../contrib/lib/libmkv.a \
-                  ../contrib/lib/libswscale.a
+                  ../contrib/lib/libswscale.a ../contrib/lib/libtheora.a
 endif
 
 CFLAGS += -I../contrib/include -D__LIBHB__ -DUSE_PTHREAD -DHB_VERSION=\"$(HB_VERSION)\" -DHB_BUILD=$(HB_BUILD) $(SYSDEF)
index 953c243be3030f2b022bf139156052ed267dd0c4..aa4cfc084e70b3ac6da61e8c445df165cf5312c0 100644 (file)
@@ -160,6 +160,7 @@ struct hb_job_s
 #define HB_VCODEC_FFMPEG 0x000001
 #define HB_VCODEC_XVID   0x000002
 #define HB_VCODEC_X264   0x000004
+#define HB_VCODEC_THEORA 0x000008
 
     int             vcodec;
     float           vquality;
@@ -526,6 +527,7 @@ extern hb_work_object_t hb_render;
 extern hb_work_object_t hb_encavcodec;
 extern hb_work_object_t hb_encxvid;
 extern hb_work_object_t hb_encx264;
+extern hb_work_object_t hb_enctheora;
 extern hb_work_object_t hb_deca52;
 extern hb_work_object_t hb_decdca;
 extern hb_work_object_t hb_decavcodec;
diff --git a/libhb/enctheora.c b/libhb/enctheora.c
new file mode 100644 (file)
index 0000000..3773b70
--- /dev/null
@@ -0,0 +1,170 @@
+/* This file is part of the HandBrake source code.
+   Homepage: <http://handbrake.m0k.org/>.
+   It may be used under the terms of the GNU General Public License. */
+
+#include "hb.h"
+#include "theora/theora.h"
+
+int  enctheoraInit( hb_work_object_t *, hb_job_t * );
+int  enctheoraWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void enctheoraClose( hb_work_object_t * );
+
+hb_work_object_t hb_enctheora =
+{
+    WORK_ENCTHEORA,
+    "Theora encoder (libtheora)",
+    enctheoraInit,
+    enctheoraWork,
+    enctheoraClose
+};
+
+struct hb_work_private_s
+{
+    hb_job_t * job;
+
+    theora_state theora;
+};
+
+int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
+{
+    hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    w->private_data = pv;
+
+    pv->job = job;
+
+    theora_info ti;
+    theora_comment tc;
+    ogg_packet op;
+    theora_info_init( &ti );
+
+    ti.width = ti.frame_width = job->width;
+    ti.height = ti.frame_height = job->height;
+    ti.offset_x = ti.offset_y = 0;
+    ti.fps_numerator = job->vrate;
+    ti.fps_denominator = job->vrate_base;
+    if (job->pixel_ratio)
+    {
+        ti.aspect_numerator = job->pixel_aspect_width;
+        ti.aspect_denominator = job->pixel_aspect_height;
+    }
+    else
+    {
+        ti.aspect_numerator = ti.aspect_denominator = 1;
+    }
+    ti.colorspace = OC_CS_UNSPECIFIED;
+    ti.pixelformat = OC_PF_420;
+    ti.keyframe_auto_p = 1;
+    ti.keyframe_frequency = (job->vrate / job->vrate_base) + 1;
+    ti.keyframe_frequency_force = (10 * job->vrate / job->vrate_base) + 1;
+    /* From encoder_example.c */
+    ti.quick_p = 1;
+    ti.dropframes_p = 0;
+    ti.keyframe_auto_threshold = 80;
+    ti.keyframe_mindistance = 8;
+    ti.noise_sensitivity = 1;
+    ti.sharpness = 0;
+    if (job->vquality < 0.0 || job->vquality > 1.0)
+    {
+        ti.target_bitrate = job->vbitrate * 1000;
+        ti.keyframe_data_target_bitrate = job->vbitrate * 1000 * 1.5;
+        ti.quality = 0;
+    }
+    else
+    {
+        ti.target_bitrate = 0;
+        ti.quality = 63 * job->vquality;
+    }
+
+    theora_encode_init( &pv->theora, &ti );
+    theora_info_clear( &ti );
+
+    theora_encode_header( &pv->theora, &op );
+    memcpy(w->config->theora.headers[0], &op, sizeof(op));
+    memcpy(w->config->theora.headers[0] + sizeof(op), op.packet, op.bytes );
+
+    theora_comment_init(&tc);
+    theora_encode_comment(&tc,&op);
+    memcpy(w->config->theora.headers[1], &op, sizeof(op));
+    memcpy(w->config->theora.headers[1] + sizeof(op), op.packet, op.bytes );
+    free(op.packet);
+
+    theora_encode_tables(&pv->theora, &op);
+    memcpy(w->config->theora.headers[2], &op, sizeof(op));
+    memcpy(w->config->theora.headers[2] + sizeof(op), op.packet, op.bytes );
+
+    return 0;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+void enctheoraClose( hb_work_object_t * w )
+{
+    hb_work_private_t * pv = w->private_data;
+    /* TODO: Free alloc'd */
+
+    free( pv );
+    w->private_data = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+int enctheoraWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                 hb_buffer_t ** buf_out )
+{
+    hb_work_private_t * pv = w->private_data;
+    hb_job_t * job = pv->job;
+    hb_buffer_t * in = *buf_in, * buf;
+    yuv_buffer yuv;
+    ogg_packet op;
+    static int last_p = 0;
+
+    memset(&op, 0, sizeof(op));
+    memset(&yuv, 0, sizeof(yuv));
+
+    /* If this is the last empty frame, we're done */
+    if(!in->data)
+    {
+        if (!last_p)
+        {
+            last_p++;
+            goto finish;
+        }
+       *buf_out        = NULL;
+       return HB_WORK_DONE;
+    }
+
+    yuv.y_width = job->width;
+    yuv.y_height = job->height;
+    yuv.y_stride = job->width;
+
+    yuv.uv_width = job->width / 2;
+    yuv.uv_height = job->height / 2;
+    yuv.uv_stride = job->width / 2;
+
+    yuv.y = in->data;
+    yuv.u = in->data + job->width * job->height;
+    yuv.v = in->data + job->width * job->height * 5/4;
+
+    theora_encode_YUVin(&pv->theora, &yuv);
+
+finish:
+    theora_encode_packetout(&pv->theora, last_p, &op);
+
+    buf = hb_buffer_init( op.bytes + sizeof(op) );
+    memcpy(buf->data, &op, sizeof(op));
+    memcpy(buf->data + sizeof(op), op.packet, op.bytes);
+    buf->frametype = ( theora_packet_iskeyframe(&op) ) ? HB_FRAME_KEY : HB_FRAME_REF;
+    buf->start = in->start;
+    buf->stop  = in->stop;
+
+    *buf_out = buf;
+
+    return HB_WORK_OK;
+}
+
index fd02d06c976414825662d3099f8b1b0f81a542d2..62fe9c4f50d7bd60c0d53b47ff2ce936fff3e4ad 100644 (file)
@@ -216,6 +216,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
        hb_register( &hb_encavcodec );
        hb_register( &hb_encxvid );
        hb_register( &hb_encx264 );
+    hb_register( &hb_enctheora );
        hb_register( &hb_deca52 );
        hb_register( &hb_decdca );
        hb_register( &hb_decavcodec );
index 8324ca5f552fa9d76022bb32280241f8524468f6..7454b634b72c0370d978e6eb228b538f64196ce3 100644 (file)
@@ -25,6 +25,7 @@ hb_register( &hb_render ); \
 hb_register( &hb_encavcodec ); \
 hb_register( &hb_encxvid ); \
 hb_register( &hb_encx264 ); \
+hb_register( &hb_enctheora ); \
 hb_register( &hb_deca52 ); \
 hb_register( &hb_decdca ); \
 hb_register( &hb_decavcodec ); \
index 8dfc3afac2748c5ab7fd13e164cc2f3108941328..a2b479929e609a7381ecb8e4d0663c0efb112aa5 100644 (file)
@@ -164,6 +164,11 @@ union hb_esconfig_u
            int       pps_length;
        } h264;
 
+    struct
+    {
+        uint8_t headers[3][HB_CONFIG_MAX_SIZE];
+    } theora;
+
     struct
     {
         uint8_t bytes[HB_CONFIG_MAX_SIZE];
@@ -199,6 +204,7 @@ enum
     WORK_ENCAVCODEC,
     WORK_ENCXVID,
     WORK_ENCX264,
+    WORK_ENCTHEORA,
     WORK_DECA52,
     WORK_DECDCA,
     WORK_DECAVCODEC,
index 58de30fa13623b0532fc8758a7fd46ef2d625b7c..6ed6a6decc3d208b44f85498a4642f3cbb044a2f 100644 (file)
@@ -106,6 +106,28 @@ static int MKVInit( hb_mux_object_t * m )
             track->codecPrivate = job->config.mpeg4.bytes;
             track->codecPrivateSize = job->config.mpeg4.length;
             break;
+        case HB_VCODEC_THEORA:
+            {
+                int i;
+                uint64_t cp_size = 0;
+                track->codecID = MK_VCODEC_THEORA;
+                uint64_t  header_sizes[3];
+                for (i = 0; i < 3; ++i)
+                {
+                    ogg_headers[i] = (ogg_packet *)job->config.theora.headers[i];
+                    ogg_headers[i]->packet = (unsigned char *)&job->config.theora.headers[i] + sizeof( ogg_packet );
+                    header_sizes[i] = ogg_headers[i]->bytes;
+                }
+                track->codecPrivate = mk_laceXiph(header_sizes, 2, &cp_size);
+                track->codecPrivate = realloc(track->codecPrivate, cp_size + ogg_headers[0]->bytes + ogg_headers[1]->bytes + ogg_headers[2]->bytes);
+                for(i = 0; i < 3; ++i)
+                {
+                    memcpy(track->codecPrivate + cp_size, ogg_headers[i]->packet, ogg_headers[i]->bytes);
+                    cp_size += ogg_headers[i]->bytes;
+                }
+                track->codecPrivateSize = cp_size;
+            }
+            break;
         default:
             *job->die = 1;
             hb_error("muxmkv: Unknown video codec: %x", job->vcodec);
@@ -177,7 +199,7 @@ static int MKVInit( hb_mux_object_t * m )
                 {
                     track->codecPrivate = NULL;
                     track->codecPrivateSize = 0;
-                    track->codecID = MK_ACODEC_AC3; 
+                    track->codecID = MK_ACODEC_AC3;
                 }
                 else
                 {
@@ -224,12 +246,14 @@ static int MKVInit( hb_mux_object_t * m )
 static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
                    hb_buffer_t * buf )
 {
+    ogg_packet  *op = NULL;
     hb_job_t * job = m->job;
     hb_title_t * title = job->title;
     uint64_t   timecode = 0;
     hb_chapter_t *chapter_data;
     char tmp_buffer[1024];
     char *string = tmp_buffer;
+
     if (mux_data == job->mux_data)
     {
         /* Video */
@@ -264,6 +288,21 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
             }
             mux_data->prev_chapter_tc = timecode;
         }
+
+        if (job->vcodec == HB_VCODEC_THEORA)
+        {
+            /* ughhh, theora is a pain :( */
+            op = (ogg_packet *)buf->data;
+            op->packet = buf->data + sizeof( ogg_packet );
+            if (mk_startFrame(m->file, mux_data->track) < 0)
+            {
+                hb_error( "Failed to write frame to output file, Disk Full?" );
+                *job->die = 1;
+            }
+            mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
+            mk_setFrameFlags(m->file, mux_data->track, timecode, 1);
+            return 0;
+        }
     }
     else
     {
@@ -272,11 +311,13 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
         if (job->acodec == HB_ACODEC_VORBIS)
         {
             /* ughhh, vorbis is a pain :( */
-            ogg_packet  *op;
-
             op = (ogg_packet *)buf->data;
             op->packet = buf->data + sizeof( ogg_packet );
-            mk_startFrame(m->file, mux_data->track);
+            if (mk_startFrame(m->file, mux_data->track))
+            {
+                hb_error( "Failed to write frame to output file, Disk Full?" );
+                *job->die = 1;
+            }
             mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
             mk_setFrameFlags(m->file, mux_data->track, timecode, 1);
             return 0;
index 16c2d4625639f7097da6b958d08fccceed8fbd45..433122448358db6281050e386fc7568714340c18 100644 (file)
@@ -143,40 +143,57 @@ static int OGMInit( hb_mux_object_t * m )
 
 
     /* First pass: all b_o_s packets */
-
+    hb_log("muxogm: Writing b_o_s header packets");
     /* Video */
     mux_data = job->mux_data;
-    memset( &h, 0, sizeof( ogg_stream_header_t ) );
-    h.i_packet_type = 0x01;
-    memcpy( h.stream_type, "video    ", 8 );
-    if( mux_data->codec == HB_VCODEC_X264 )
-    {
-        memcpy( h.sub_type, "H264", 4 );
-    }
-    else if( mux_data->codec == HB_VCODEC_XVID )
+    switch( job->vcodec )
     {
-        memcpy( h.sub_type, "XVID", 4 );
-    }
-    else
-    {
-        memcpy( h.sub_type, "DX50", 4 );
+        case HB_VCODEC_THEORA:
+            memcpy(&op, job->config.theora.headers[0], sizeof(op));
+            op.packet = job->config.theora.headers[0] + sizeof(op);
+            ogg_stream_packetin( &mux_data->os, &op );
+            break;
+        case HB_VCODEC_XVID:
+        case HB_VCODEC_X264:
+        case HB_VCODEC_FFMPEG:
+        {
+                memset( &h, 0, sizeof( ogg_stream_header_t ) );
+                h.i_packet_type = 0x01;
+                memcpy( h.stream_type, "video    ", 8 );
+                if( mux_data->codec == HB_VCODEC_X264 )
+                {
+                    memcpy( h.sub_type, "H264", 4 );
+                }
+                else if( mux_data->codec == HB_VCODEC_XVID )
+                {
+                    memcpy( h.sub_type, "XVID", 4 );
+                }
+                else
+                {
+                    memcpy( h.sub_type, "DX50", 4 );
+                }
+                SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
+                SetQWLE( &h.i_time_unit, (int64_t) 10 * 1000 * 1000 *
+                         (int64_t) job->vrate_base / (int64_t) job->vrate );
+                SetQWLE( &h.i_samples_per_unit, 1 );
+                SetDWLE( &h.i_default_len, 0 );
+                SetDWLE( &h.i_buffer_size, 1024*1024 );
+                SetWLE ( &h.i_bits_per_sample, 0 );
+                SetDWLE( &h.header.video.i_width,  job->width );
+                SetDWLE( &h.header.video.i_height, job->height );
+                op.packet   = (unsigned char*)&h;
+                op.bytes    = sizeof( ogg_stream_header_t );
+                op.b_o_s    = 1;
+                op.e_o_s    = 0;
+                op.granulepos = 0;
+                op.packetno = mux_data->i_packet_no++;
+                ogg_stream_packetin( &mux_data->os, &op );
+                break;
+            }
+        default:
+            hb_error( "muxogm: unhandled video codec" );
+            *job->die = 1;
     }
-    SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
-    SetQWLE( &h.i_time_unit, (int64_t) 10 * 1000 * 1000 *
-             (int64_t) job->vrate_base / (int64_t) job->vrate );
-    SetQWLE( &h.i_samples_per_unit, 1 );
-    SetDWLE( &h.i_default_len, 0 );
-    SetDWLE( &h.i_buffer_size, 1024*1024 );
-    SetWLE ( &h.i_bits_per_sample, 0 );
-    SetDWLE( &h.header.video.i_width,  job->width );
-    SetDWLE( &h.header.video.i_height, job->height );
-    op.packet   = (unsigned char*)&h;
-    op.bytes    = sizeof( ogg_stream_header_t );
-    op.b_o_s    = 1;
-    op.e_o_s    = 0;
-    op.granulepos = 0;
-    op.packetno = mux_data->i_packet_no++;
-    ogg_stream_packetin( &mux_data->os, &op );
     OGMFlush( m, mux_data );
 
     /* Audio */
@@ -231,6 +248,30 @@ static int OGMInit( hb_mux_object_t * m )
     }
 
     /* second pass: all non b_o_s packets */
+    hb_log("muxogm: Writing non b_o_s header packets");
+    /* Video */
+    mux_data = job->mux_data;
+    switch( job->vcodec )
+    {
+        case HB_VCODEC_THEORA:
+            for (i = 1; i < 3; i++)
+            {
+                memcpy(&op, job->config.theora.headers[i], sizeof(op));
+                op.packet = job->config.theora.headers[i] + sizeof(op);
+                ogg_stream_packetin( &mux_data->os, &op );
+                OGMFlush( m, mux_data );
+            }
+            break;
+        case HB_VCODEC_XVID:
+        case HB_VCODEC_X264:
+        case HB_VCODEC_FFMPEG:
+            break;
+        default:
+            hb_error( "muxogm: unhandled video codec" );
+            *job->die = 1;
+    }
+
+    /* Audio */
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
@@ -263,6 +304,11 @@ static int OGMMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
 
     switch( mux_data->codec )
     {
+        case HB_VCODEC_THEORA:
+            memcpy( &op, buf->data, sizeof( ogg_packet ) );
+            op.packet = malloc( op.bytes );
+            memcpy( op.packet, buf->data + sizeof( ogg_packet ), op.bytes );
+            break;
         case HB_VCODEC_FFMPEG:
         case HB_VCODEC_XVID:
         case HB_VCODEC_X264:
index c6357aeb6c6a735b46a9eaf72864fdb2408c75a1..9ebc33bf681b4656f63010e47b452b21f2915d7f 100644 (file)
@@ -264,6 +264,10 @@ static void do_job( hb_job_t * job, int cpu_count )
                 hb_log( "   + x264 options: %s", job->x264opts);
             w = getWork( WORK_ENCX264 );
             break;
+        case HB_VCODEC_THEORA:
+            hb_log( " + encoder Theora" );
+            w = getWork( WORK_ENCTHEORA );
+            break;
     }
     w->fifo_in  = job->fifo_render;
     w->fifo_out = job->fifo_mpeg4;
index 555e0e43a86d598c68e22413bb082ffbc797a05a..7cc5b5265142fa0553ef7cd72b26cb70456d3742 100644 (file)
@@ -92,6 +92,8 @@
                59CBD2650BBB4D1B004A3BE3 /* ChapterTitles.m in Sources */ = {isa = PBXBuildFile; fileRef = 593034EA0BBA39A100172349 /* ChapterTitles.m */; };
                A22C85EC0D05D35000C10E36 /* HBPresets.h in Headers */ = {isa = PBXBuildFile; fileRef = A22C85EA0D05D35000C10E36 /* HBPresets.h */; };
                A22C85ED0D05D35100C10E36 /* HBPresets.m in Sources */ = {isa = PBXBuildFile; fileRef = A22C85EB0D05D35000C10E36 /* HBPresets.m */; };
+               A25289E60D87A27D00461D5B /* enctheora.c in Sources */ = {isa = PBXBuildFile; fileRef = A25289E50D87A27D00461D5B /* enctheora.c */; };
+               A25289E70D87A2CB00461D5B /* enctheora.c in Sources */ = {isa = PBXBuildFile; fileRef = A25289E50D87A27D00461D5B /* enctheora.c */; };
                A273E0510C57B39A00493A45 /* Pause.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A273E04A0C57B39A00493A45 /* Pause.tiff */; };
                A273E0520C57B39A00493A45 /* Play.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A273E04B0C57B39A00493A45 /* Play.tiff */; };
                A273E0530C57B39A00493A45 /* Stop.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A273E04C0C57B39A00493A45 /* Stop.tiff */; };
                59CBD2360BBB44DA004A3BE3 /* parsecsv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = parsecsv.c; path = ../test/parsecsv.c; sourceTree = SOURCE_ROOT; };
                A22C85EA0D05D35000C10E36 /* HBPresets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBPresets.h; sourceTree = "<group>"; };
                A22C85EB0D05D35000C10E36 /* HBPresets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBPresets.m; sourceTree = "<group>"; };
+               A25289E50D87A27D00461D5B /* enctheora.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = enctheora.c; path = ../libhb/enctheora.c; sourceTree = SOURCE_ROOT; };
                A273E04A0C57B39A00493A45 /* Pause.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Pause.tiff; sourceTree = "<group>"; };
                A273E04B0C57B39A00493A45 /* Play.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Play.tiff; sourceTree = "<group>"; };
                A273E04C0C57B39A00493A45 /* Stop.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Stop.tiff; sourceTree = "<group>"; };
                526FBC8D0B4CA9F90064E04C /* libhb Sources */ = {
                        isa = PBXGroup;
                        children = (
+                               A25289E50D87A27D00461D5B /* enctheora.c */,
                                B48359A70C82960500E04440 /* lang.c */,
                                EAA526920C3B25D200944FF2 /* stream.c */,
                                0DFA5C7E0B8DD3B60020BC09 /* declpcm.c */,
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               A25289E70D87A2CB00461D5B /* enctheora.c in Sources */,
                                D4D49FED0C83355600F01215 /* lang.c in Sources */,
                                0DFA5CD90B8DD4210020BC09 /* declpcm.c in Sources */,
                                0DFA5CDA0B8DD4210020BC09 /* decmpeg2.c in Sources */,
                                FC8519520C59A02C0073812C /* deblock.c in Sources */,
                                FC8519530C59A02C0073812C /* detelecine.c in Sources */,
                                B48359A80C82960500E04440 /* lang.c in Sources */,
+                               A25289E60D87A27D00461D5B /* enctheora.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                        ../contrib/lib/libdca.a,
                                        ../contrib/lib/libmkv.a,
                                        ../contrib/lib/libswscale.a,
+                                       ../contrib/lib/libtheora.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
                                        ../contrib/lib/libdca.a,
                                        ../contrib/lib/libmkv.a,
                                        ../contrib/lib/libswscale.a,
+                                       ../contrib/lib/libtheora.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libdca.a,
                                        ../contrib/lib/libmkv.a,
                                        ../contrib/lib/libswscale.a,
+                                       ../contrib/lib/libtheora.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libdca.a,
                                        ../contrib/lib/libmkv.a,
                                        ../contrib/lib/libswscale.a,
+                                       ../contrib/lib/libtheora.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libdca.a,
                                        ../contrib/lib/libmkv.a,
                                        ../contrib/lib/libswscale.a,
+                                       ../contrib/lib/libtheora.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
                                        ../contrib/lib/libdca.a,
                                        ../contrib/lib/libmkv.a,
                                        ../contrib/lib/libswscale.a,
+                                       ../contrib/lib/libtheora.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
index b0da8893dfa329b8b05832134da9c2e52d773880..e6c978cd3b01575779adb245b0a7be8afd3187f2 100644 (file)
@@ -1178,7 +1178,7 @@ static void ShowHelp()
 
        "### Video Options------------------------------------------------------------\n\n"
        "    -e, --encoder <string>  Set video library encoder (ffmpeg,xvid,\n"
-    "                            x264,x264b13,x264b30 default: ffmpeg)\n"
+    "                            x264,x264b13,x264b30,theora default: ffmpeg)\n"
        "    -q, --quality <float>   Set video quality (0.0..1.0)\n"
        "    -Q, --cqp               Use with -q for CQP instead of CRF\n"
     "    -S, --size <MB>         Set target size\n"
@@ -1586,6 +1586,10 @@ static int ParseOptions( int argc, char ** argv )
                     vcodec = HB_VCODEC_X264;
                     h264_30 = 1;
                 }
+                else if( !strcasecmp( optarg, "theora" ) )
+                {
+                    vcodec = HB_VCODEC_THEORA;
+                }
                 else
                 {
                     fprintf( stderr, "invalid codec (%s)\n", optarg );