Index: test/test.c =================================================================== --- test/test.c (revision 1335) +++ test/test.c (working copy) @@ -1178,7 +1178,7 @@ "### Video Options------------------------------------------------------------\n\n" " -e, --encoder Set video library encoder (ffmpeg,xvid,\n" - " x264,x264b13,x264b30 default: ffmpeg)\n" + " x264,x264b13,x264b30,theora default: ffmpeg)\n" " -q, --quality Set video quality (0.0..1.0)\n" " -Q, --cqp Use with -q for CQP instead of CRF\n" " -S, --size Set target size\n" @@ -1586,6 +1586,10 @@ vcodec = HB_VCODEC_X264; h264_30 = 1; } + else if( !strcasecmp( optarg, "theora" ) ) + { + vcodec = HB_VCODEC_THEORA; + } else { fprintf( stderr, "invalid codec (%s)\n", optarg ); Index: libhb/Jamfile =================================================================== --- libhb/Jamfile (revision 1335) +++ libhb/Jamfile (working copy) @@ -11,7 +11,7 @@ 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: libhb/hb.c =================================================================== --- libhb/hb.c (revision 1335) +++ libhb/hb.c (working copy) @@ -216,6 +216,7 @@ 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: libhb/Makefile =================================================================== --- libhb/Makefile (revision 1335) +++ libhb/Makefile (working copy) @@ -21,7 +21,7 @@ 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 @@ ../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 @@ ../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: libhb/hb.h =================================================================== --- libhb/hb.h (revision 1335) +++ libhb/hb.h (working copy) @@ -25,6 +25,7 @@ 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: libhb/enctheora.c =================================================================== --- libhb/enctheora.c (revision 0) +++ libhb/enctheora.c (revision 0) @@ -0,0 +1,170 @@ +/* This file is part of the HandBrake source code. + Homepage: . + 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: libhb/muxogm.c =================================================================== --- libhb/muxogm.c (revision 1335) +++ libhb/muxogm.c (working copy) @@ -143,40 +143,57 @@ /* 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 ) + switch( job->vcodec ) { - memcpy( h.sub_type, "H264", 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; } - 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 ); OGMFlush( m, mux_data ); /* Audio */ @@ -231,6 +248,30 @@ } /* 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 @@ 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: libhb/internal.h =================================================================== --- libhb/internal.h (revision 1335) +++ libhb/internal.h (working copy) @@ -166,6 +166,11 @@ struct { + uint8_t headers[3][HB_CONFIG_MAX_SIZE]; + } theora; + + struct + { uint8_t bytes[HB_CONFIG_MAX_SIZE]; int length; } aac; @@ -199,6 +204,7 @@ WORK_ENCAVCODEC, WORK_ENCXVID, WORK_ENCX264, + WORK_ENCTHEORA, WORK_DECA52, WORK_DECDCA, WORK_DECAVCODEC, Index: libhb/work.c =================================================================== --- libhb/work.c (revision 1335) +++ libhb/work.c (working copy) @@ -264,6 +264,10 @@ 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: libhb/muxmkv.c =================================================================== --- libhb/muxmkv.c (revision 1335) +++ libhb/muxmkv.c (working copy) @@ -106,6 +106,28 @@ 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); @@ -224,12 +246,14 @@ 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 @@ } 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 @@ 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: libhb/common.h =================================================================== --- libhb/common.h (revision 1335) +++ libhb/common.h (working copy) @@ -160,6 +160,7 @@ #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_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; Index: macosx/HandBrake.xcodeproj/project.pbxproj =================================================================== --- macosx/HandBrake.xcodeproj/project.pbxproj (revision 1335) +++ macosx/HandBrake.xcodeproj/project.pbxproj (working copy) @@ -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 */; }; @@ -258,6 +260,7 @@ 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 = ""; }; A22C85EB0D05D35000C10E36 /* HBPresets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBPresets.m; sourceTree = ""; }; + 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 = ""; }; A273E04B0C57B39A00493A45 /* Play.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Play.tiff; sourceTree = ""; }; A273E04C0C57B39A00493A45 /* Stop.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Stop.tiff; sourceTree = ""; }; @@ -429,6 +432,7 @@ 526FBC8D0B4CA9F90064E04C /* libhb Sources */ = { isa = PBXGroup; children = ( + A25289E50D87A27D00461D5B /* enctheora.c */, B48359A70C82960500E04440 /* lang.c */, EAA526920C3B25D200944FF2 /* stream.c */, 0DFA5C7E0B8DD3B60020BC09 /* declpcm.c */, @@ -748,6 +752,7 @@ 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 */, @@ -828,6 +833,7 @@ FC8519520C59A02C0073812C /* deblock.c in Sources */, FC8519530C59A02C0073812C /* detelecine.c in Sources */, B48359A80C82960500E04440 /* lang.c in Sources */, + A25289E60D87A27D00461D5B /* enctheora.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1189,6 +1195,7 @@ ../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; @@ -1235,6 +1242,7 @@ ../contrib/lib/libdca.a, ../contrib/lib/libmkv.a, ../contrib/lib/libswscale.a, + ../contrib/lib/libtheora.a, ); PREBINDING = NO; PRODUCT_NAME = HandBrakeCLI; @@ -1355,6 +1363,7 @@ ../contrib/lib/libdca.a, ../contrib/lib/libmkv.a, ../contrib/lib/libswscale.a, + ../contrib/lib/libtheora.a, ); PREBINDING = NO; PRODUCT_NAME = HandBrakeCLI; @@ -1398,6 +1407,7 @@ ../contrib/lib/libdca.a, ../contrib/lib/libmkv.a, ../contrib/lib/libswscale.a, + ../contrib/lib/libtheora.a, ); PREBINDING = NO; PRODUCT_NAME = HandBrakeCLI; @@ -1453,6 +1463,7 @@ ../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; @@ -1512,6 +1523,7 @@ ../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: contrib/Jamfile =================================================================== --- contrib/Jamfile (revision 1335) +++ contrib/Jamfile (working copy) @@ -336,6 +336,25 @@ } LibVorbisEnc $(SUBDIR)/lib/libvorbisenc.a : $(SUBDIR)/lib/libvorbis.a ; +# libtheora +rule LibTheora +{ + Depends $(<) : $(>) ; + Depends lib : $(<) ; +} +actions LibTheora +{ + cd `dirname $(>)` && CONTRIB=`pwd` && + rm -rf libtheora-1.0beta2 && (gzip -dc libtheora.tar.gz | tar xf - ) && + cd libtheora-1.0beta2 && + ./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 { Index: contrib/version_libtheora.txt =================================================================== --- contrib/version_libtheora.txt (revision 0) +++ contrib/version_libtheora.txt (revision 0) @@ -0,0 +1 @@ +http://downloads.xiph.org/releases/theora/libtheora-1.0beta2.tar.gz Index: Jamfile =================================================================== --- Jamfile (revision 1335) +++ Jamfile (working copy) @@ -16,7 +16,8 @@ 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 {