summaryrefslogtreecommitdiffstats
path: root/core/OgmMux.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/OgmMux.c')
-rw-r--r--core/OgmMux.c396
1 files changed, 0 insertions, 396 deletions
diff --git a/core/OgmMux.c b/core/OgmMux.c
deleted file mode 100644
index e99a494f5..000000000
--- a/core/OgmMux.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/* $Id: OgmMux.c,v 1.13 2004/05/13 21:10:56 titer Exp $
-
- 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 "HBInternal.h"
-
-#include <ogg/ogg.h>
-
-static int OgmStart( HBMux * );
-static int OgmMux( HBMux *, void *, HBBuffer * );
-static int OgmEnd( HBMux * );
-
-struct HBMux
-{
- HB_MUX_COMMON_MEMBERS
-
- HBHandle * handle;
- HBTitle * title;
- FILE * file;
-};
-
-typedef struct
-{
- int codec;
- ogg_stream_state os;
- int i_packet_no;
-
-} OgmMuxData;
-
-typedef struct __attribute__((__packed__))
-{
- uint8_t i_packet_type;
-
- char stream_type[8];
- char sub_type[4];
-
- int32_t i_size;
-
- int64_t i_time_unit;
- int64_t i_samples_per_unit;
- int32_t i_default_len;
-
- int32_t i_buffer_size;
- int16_t i_bits_per_sample;
- int16_t i_padding_0; // hum hum
- union
- {
- struct
- {
- int32_t i_width;
- int32_t i_height;
-
- } video;
- struct
- {
- int16_t i_channels;
- int16_t i_block_align;
- int32_t i_avgbytespersec;
- } audio;
- } header;
-
-} ogg_stream_header_t;
-
-#define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v)
-static void _SetWLE( uint8_t *p, uint16_t i_dw )
-{
- p[1] = ( i_dw >> 8 )&0xff;
- p[0] = ( i_dw )&0xff;
-}
-
-#define SetDWLE( p, v ) _SetDWLE( (uint8_t*)p, v)
-static void _SetDWLE( uint8_t *p, uint32_t i_dw )
-{
- p[3] = ( i_dw >> 24 )&0xff;
- p[2] = ( i_dw >> 16 )&0xff;
- p[1] = ( i_dw >> 8 )&0xff;
- p[0] = ( i_dw )&0xff;
-}
-#define SetQWLE( p, v ) _SetQWLE( (uint8_t*)p, v)
-static void _SetQWLE( uint8_t *p, uint64_t i_qw )
-{
- SetDWLE( p, i_qw&0xffffffff );
- SetDWLE( p+4, ( i_qw >> 32)&0xffffffff );
-}
-
-HBMux * HBOgmMuxInit( HBHandle * handle, HBTitle * title )
-{
- HBMux * m;
- HBAudio * audio;
- int i;
-
- if( !( m = calloc( sizeof( HBMux ), 1 ) ) )
- {
- HBLog( "HBOgmMux: malloc failed, gonna crash" );
- return NULL;
- }
- m->start = OgmStart;
- m->muxVideo = OgmMux;
- m->muxAudio = OgmMux;
- m->end = OgmEnd;
-
- m->handle = handle;
- m->title = title;
-
- /* Alloc muxer data */
- title->muxData = calloc( sizeof( OgmMuxData ), 1 );
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
- audio->muxData = calloc( sizeof( OgmMuxData ), 1 );
- }
-
- return m;
-}
-
-void HBOgmMuxClose( HBMux ** _m )
-{
- HBMux * m = *_m;
- HBTitle * title = m->title;
- HBAudio * audio;
- int i;
-
- /* Free muxer data */
- free( title->muxData );
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
- free( audio->muxData );
- }
-
- free( m );
- *_m = NULL;
-}
-
-static int OgmFlush( HBMux * m, OgmMuxData * muxData )
-{
- for( ;; )
- {
- ogg_page og;
- if( ogg_stream_flush( &muxData->os, &og ) == 0 )
- {
- break;
- }
- if( fwrite( og.header, og.header_len, 1, m->file ) <= 0 ||
- fwrite( og.body, og.body_len, 1, m->file ) <= 0 )
- {
- return -1;
- }
- }
- return 0;
-}
-
-static int OgmStart( HBMux * m )
-{
- HBTitle * title = m->title;
- HBAudio * audio;
- OgmMuxData * muxData;
- ogg_packet op;
- ogg_stream_header_t h;
- int i;
-
- /* Open output file */
- if( ( m->file = fopen( title->file, "wb" ) ) == NULL )
- {
- HBLog( "HBOgmMux: failed to open `%s'", title->file );
- /* FIXME */
- HBErrorOccured( m->handle, HB_ERROR_AVI_WRITE );
- return -1;
- }
- HBLog( "HBOgmMux: `%s' opened", title->file );
-
- /* Init tracks */
-
- /* Video */
- muxData = (OgmMuxData *) title->muxData;
- muxData->codec = title->codec;
- muxData->i_packet_no = 0;
- ogg_stream_init( &muxData->os, 0 );
-
- /* Audio */
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- HBAudio * audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
- muxData = (OgmMuxData *) audio->muxData;
-
- muxData->codec = audio->outCodec;
- muxData->i_packet_no = 0;
- ogg_stream_init( &muxData->os, i + 1 );
-
- }
-
- /* First pass: all b_o_s packets */
-
- /* Video */
- muxData = (OgmMuxData *) title->muxData;
- memset( &h, 0, sizeof( ogg_stream_header_t ) );
- h.i_packet_type = 0x01;
- memcpy( h.stream_type, "video ", 8 );
- if( muxData->codec == HB_CODEC_X264 )
- {
- memcpy( h.sub_type, "H264", 4 );
- }
- else
- {
- memcpy( h.sub_type, "XVID", 4 );
- }
- SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
- SetQWLE( &h.i_time_unit, (int64_t)10*1000*1000*(int64_t)title->rateBase/(int64_t)title->rate );
- 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, title->outWidth );
- SetDWLE( &h.header.video.i_height, title->outHeight );
- op.packet = (char*)&h;
- op.bytes = sizeof( ogg_stream_header_t );
- op.b_o_s = 1;
- op.e_o_s = 0;
- op.granulepos = 0;
- op.packetno = muxData->i_packet_no++;
- ogg_stream_packetin( &muxData->os, &op );
- OgmFlush( m, muxData );
-
- /* Audio */
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
- muxData = (OgmMuxData *) audio->muxData;
- memset( &h, 0, sizeof( ogg_stream_header_t ) );
- switch( muxData->codec )
- {
- case HB_CODEC_MP3:
- {
- h.i_packet_type = 0x01;
- memcpy( h.stream_type, "audio ", 8 );
- memcpy( h.sub_type, "55 ", 4 );
-
- SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
- SetQWLE( &h.i_time_unit, 0 );
- SetQWLE( &h.i_samples_per_unit, audio->outSampleRate );
- SetDWLE( &h.i_default_len, 1 );
- SetDWLE( &h.i_buffer_size, 30*1024 );
- SetWLE ( &h.i_bits_per_sample, 0 );
-
- SetDWLE( &h.header.audio.i_channels, 2 );
- SetDWLE( &h.header.audio.i_block_align, 0 );
- SetDWLE( &h.header.audio.i_avgbytespersec,
- audio->outBitrate / 8 );
-
- op.packet = (char*)&h;
- op.bytes = sizeof( ogg_stream_header_t );
- op.b_o_s = 1;
- op.e_o_s = 0;
- op.granulepos = 0;
- op.packetno = muxData->i_packet_no++;
- ogg_stream_packetin( &muxData->os, &op );
- break;
- }
- case HB_CODEC_VORBIS:
- {
- HBBuffer *h = HBFifoPop( audio->outFifo );
-
- memcpy( &op, h->data, sizeof( ogg_packet ) );
- op.packet = h->data + sizeof( ogg_packet );
- ogg_stream_packetin( &muxData->os, &op );
- break;
- }
- default:
- HBLog( "HBOgmMux: unhandled codec" );
- break;
- }
- OgmFlush( m, muxData );
- }
-
- /* second pass: all non b_o_s packets */
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
- if( audio->outCodec == HB_CODEC_VORBIS )
- {
- HBBuffer *h;
- int j;
- muxData = (OgmMuxData *) audio->muxData;
-
- for( j = 0; j < 2; j++ )
- {
- h = HBFifoPop( audio->outFifo );
-
- memcpy( &op, h->data, sizeof( ogg_packet ) );
- op.packet = h->data + sizeof( ogg_packet );
- ogg_stream_packetin( &muxData->os, &op );
-
- OgmFlush( m, muxData );
- }
- }
- }
-
- HBLog( "HBOgmMux: headers written" );
- return 0;
-}
-
-static int OgmMux( HBMux * m, void * _muxData, HBBuffer * buffer )
-{
- OgmMuxData * muxData = (OgmMuxData *) _muxData;
- ogg_packet op;
-
- switch( muxData->codec )
- {
- case HB_CODEC_FFMPEG:
- case HB_CODEC_XVID:
- case HB_CODEC_X264:
- op.bytes = buffer->size + 1;
- op.packet = malloc( op.bytes );
- op.packet[0] = buffer->keyFrame ? 0x08 : 0x00;
- memcpy( &op.packet[1], buffer->data, buffer->size );
- op.b_o_s = 0;
- op.e_o_s = 0;
- op.granulepos = muxData->i_packet_no;
- op.packetno = muxData->i_packet_no++;
- break;
- case HB_CODEC_MP3:
- op.bytes = buffer->size + 1;
- op.packet = malloc( op.bytes );
- op.packet[0] = 0x08;
- memcpy( &op.packet[1], buffer->data, buffer->size );
- op.b_o_s = 0;
- op.e_o_s = 0;
- op.granulepos = muxData->i_packet_no * 1152;
- op.packetno = muxData->i_packet_no++;
- break;
- case HB_CODEC_VORBIS:
- memcpy( &op, buffer->data, sizeof( ogg_packet ) );
- op.packet = malloc( op.bytes );
- memcpy( op.packet, buffer->data + sizeof( ogg_packet ), op.bytes );
- break;
-
- default:
- HBLog( "HBOgmMux: unhandled codec" );
- op.bytes = 0;
- op.packet = NULL;
- break;
- }
-
- if( op.packet )
- {
- ogg_stream_packetin( &muxData->os, &op );
-
- for( ;; )
- {
- ogg_page og;
- if( ogg_stream_pageout( &muxData->os, &og ) == 0 )
- {
- break;
- }
-
- if( fwrite( og.header, og.header_len, 1, m->file ) <= 0 ||
- fwrite( og.body, og.body_len, 1, m->file ) <= 0 )
- {
- HBLog( "HBOgmMux: write failed" );
- break;
- }
- }
- free( op.packet );
- }
- return 0;
-}
-
-static int OgmEnd( HBMux * m )
-{
- HBTitle * title = m->title;
- HBAudio * audio;
- OgmMuxData * muxData;
- int i;
-
- muxData = (OgmMuxData *) title->muxData;
- if( OgmFlush( m, muxData ) < 0 )
- {
- return -1;
- }
- for( i = 0; i < HBListCount( title->ripAudioList ); i++ )
- {
- audio = (HBAudio *) HBListItemAt( title->ripAudioList, i );
- muxData = (OgmMuxData *) audio->muxData;
- if( OgmFlush( m, muxData ) < 0 )
- {
- return -1;
- }
- }
-
- fclose( m->file );
- HBLog( "HBOgmMux: `%s' closed", title->file );
- return 0;
-}
-