diff options
author | prigaux <[email protected]> | 2007-02-11 20:00:15 +0000 |
---|---|---|
committer | prigaux <[email protected]> | 2007-02-11 20:00:15 +0000 |
commit | a74fd5a1ec37e53fe7008f022639af6ede0e82c9 (patch) | |
tree | 0a6a32640a840b72653149aa11efa264674df976 /libhb/muxavi.c | |
parent | f45dfeb2afb1b0bf46054959e8ea9494f3b7d14f (diff) |
Merge the 0.8.0_mpeg4ip branch into the trunk
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@285 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/muxavi.c')
-rw-r--r-- | libhb/muxavi.c | 551 |
1 files changed, 0 insertions, 551 deletions
diff --git a/libhb/muxavi.c b/libhb/muxavi.c deleted file mode 100644 index 8746a3cdd..000000000 --- a/libhb/muxavi.c +++ /dev/null @@ -1,551 +0,0 @@ -/* $Id: muxavi.c,v 1.10 2005/03/30 18:17:29 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 "hb.h" - -#define AVIF_HASINDEX 0x10 -#define AVIIF_KEYFRAME 0x10 -#define FOURCC(a) ((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0]) - -/* Structures definitions */ -typedef struct __attribute__((__packed__)) -{ - uint32_t FourCC; - uint32_t BytesCount; - uint32_t MicroSecPerFrame; - uint32_t MaxBytesPerSec; - uint32_t PaddingGranularity; - uint32_t Flags; - uint32_t TotalFrames; - uint32_t InitialFrames; - uint32_t Streams; - uint32_t SuggestedBufferSize; - uint32_t Width; - uint32_t Height; - uint32_t Reserved[4]; - -} hb_avi_main_header_t; - -typedef struct __attribute__((__packed__)) -{ - uint32_t FourCC; - uint32_t BytesCount; - uint32_t Type; - uint32_t Handler; - uint32_t Flags; - uint16_t Priority; - uint16_t Language; - uint32_t InitialFrames; - uint32_t Scale; - uint32_t Rate; - uint32_t Start; - uint32_t Length; - uint32_t SuggestedBufferSize; - uint32_t Quality; - uint32_t SampleSize; - int16_t Left; - int16_t Top; - int16_t Right; - int16_t Bottom; - -} hb_avi_stream_header_t; - -typedef struct __attribute__((__packed__)) -{ - uint32_t FourCC; - uint32_t BytesCount; - uint32_t Size; - uint32_t Width; - uint32_t Height; - uint16_t Planes; - uint16_t BitCount; - uint32_t Compression; - uint32_t SizeImage; - uint32_t XPelsPerMeter; - uint32_t YPelsPerMeter; - uint32_t ClrUsed; - uint32_t ClrImportant; - -} hb_bitmap_info_t; - -typedef struct __attribute__((__packed__)) -{ - uint32_t FourCC; - uint32_t BytesCount; - uint16_t FormatTag; - uint16_t Channels; - uint32_t SamplesPerSec; - uint32_t AvgBytesPerSec; - uint16_t BlockAlign; - uint16_t BitsPerSample; - uint16_t Size; - -} hb_wave_formatex_t; - -typedef struct __attribute__((__packed__)) -{ - uint16_t Id; - uint32_t Flags; - uint16_t BlockSize; - uint16_t FramesPerBlock; - uint16_t CodecDelay; - -} hb_wave_mp3_t; - -static void WriteBuffer( FILE * file, hb_buffer_t * buf ) -{ - fwrite( buf->data, buf->size, 1, file ); -} - -/* Little-endian write routines */ - -static void WriteInt8( FILE * file, uint8_t val ) -{ - fputc( val, file ); -} - -static void WriteInt16( FILE * file, uint16_t val ) -{ - fputc( val & 0xFF, file ); - fputc( val >> 8, file ); -} - -static void WriteInt32( FILE * file, uint32_t val ) -{ - fputc( val & 0xFF, file ); - fputc( ( val >> 8 ) & 0xFF, file ); - fputc( ( val >> 16 ) & 0xFF, file ); - fputc( val >> 24, file ); -} - -static void WriteBitmapInfo( FILE * file, hb_bitmap_info_t * info ) -{ - WriteInt32( file, info->FourCC ); - WriteInt32( file, info->BytesCount ); - WriteInt32( file, info->Size ); - WriteInt32( file, info->Width ); - WriteInt32( file, info->Height ); - WriteInt16( file, info->Planes ); - WriteInt16( file, info->BitCount ); - WriteInt32( file, info->Compression ); - WriteInt32( file, info->SizeImage ); - WriteInt32( file, info->XPelsPerMeter ); - WriteInt32( file, info->YPelsPerMeter ); - WriteInt32( file, info->ClrUsed ); - WriteInt32( file, info->ClrImportant ); -} - -static void WriteWaveFormatEx( FILE * file, hb_wave_formatex_t * format ) -{ - WriteInt32( file, format->FourCC ); - WriteInt32( file, format->BytesCount ); - WriteInt16( file, format->FormatTag ); - WriteInt16( file, format->Channels ); - WriteInt32( file, format->SamplesPerSec ); - WriteInt32( file, format->AvgBytesPerSec ); - WriteInt16( file, format->BlockAlign ); - WriteInt16( file, format->BitsPerSample ); - WriteInt16( file, format->Size ); -} - -static void WriteWaveMp3( FILE * file, hb_wave_mp3_t * mp3 ) -{ - WriteInt16( file, mp3->Id ); - WriteInt32( file, mp3->Flags ); - WriteInt16( file, mp3->BlockSize ); - WriteInt16( file, mp3->FramesPerBlock ); - WriteInt16( file, mp3->CodecDelay ); -} - -static void WriteMainHeader( FILE * file, hb_avi_main_header_t * header ) -{ - WriteInt32( file, header->FourCC ); - WriteInt32( file, header->BytesCount ); - WriteInt32( file, header->MicroSecPerFrame ); - WriteInt32( file, header->MaxBytesPerSec ); - WriteInt32( file, header->PaddingGranularity ); - WriteInt32( file, header->Flags ); - WriteInt32( file, header->TotalFrames ); - WriteInt32( file, header->InitialFrames ); - WriteInt32( file, header->Streams ); - WriteInt32( file, header->SuggestedBufferSize ); - WriteInt32( file, header->Width ); - WriteInt32( file, header->Height ); - WriteInt32( file, header->Reserved[0] ); - WriteInt32( file, header->Reserved[1] ); - WriteInt32( file, header->Reserved[2] ); - WriteInt32( file, header->Reserved[3] ); -} - -static void WriteStreamHeader( FILE * file, hb_avi_stream_header_t * header ) -{ - WriteInt32( file, header->FourCC ); - WriteInt32( file, header->BytesCount ); - WriteInt32( file, header->Type ); - WriteInt32( file, header->Handler ); - WriteInt32( file, header->Flags ); - WriteInt16( file, header->Priority ); - WriteInt16( file, header->Language ); - WriteInt32( file, header->InitialFrames ); - WriteInt32( file, header->Scale ); - WriteInt32( file, header->Rate ); - WriteInt32( file, header->Start ); - WriteInt32( file, header->Length ); - WriteInt32( file, header->SuggestedBufferSize ); - WriteInt32( file, header->Quality ); - WriteInt32( file, header->SampleSize ); - WriteInt16( file, header->Left ); - WriteInt16( file, header->Top ); - WriteInt16( file, header->Right ); - WriteInt16( file, header->Bottom ); -} - -static void IndexAddInt32( hb_buffer_t * b, uint32_t val ) -{ - if( b->size + 16 > b->alloc ) - { - hb_log( "muxavi: reallocing index (%d MB)", - 1 + b->alloc / 1024 / 1024 ); - hb_buffer_realloc( b, b->alloc + 1024 * 1024 ); - } - - b->data[b->size++] = val & 0xFF; - b->data[b->size++] = ( val >> 8 ) & 0xFF; - b->data[b->size++] = ( val >> 16 ) & 0xFF; - b->data[b->size++] = val >> 24; -} - -struct hb_mux_object_s -{ - HB_MUX_COMMON; - - hb_job_t * job; - - /* Data size in bytes, not including headers */ - unsigned size; - FILE * file; - hb_buffer_t * index; - hb_avi_main_header_t main_header; -}; - -struct hb_mux_data_s -{ - uint32_t fourcc; - hb_avi_stream_header_t header; - union - { - hb_bitmap_info_t v; - struct - { - hb_wave_formatex_t f; - hb_wave_mp3_t m; - } a; - } format; -}; - -static void AddIndex( hb_mux_object_t * m ) -{ - fseek( m->file, 0, SEEK_END ); - - /* Write the index at the end of the file */ - WriteInt32( m->file, FOURCC( "idx1" ) ); - WriteInt32( m->file, m->index->size ); - WriteBuffer( m->file, m->index ); - - /* Update file size */ - m->size += 8 + m->index->size; - fseek( m->file, 4, SEEK_SET ); - WriteInt32( m->file, 2040 + m->size ); - - /* Update HASINDEX flag */ - m->main_header.Flags |= AVIF_HASINDEX; - fseek( m->file, 24, SEEK_SET ); - WriteMainHeader( m->file, &m->main_header ); -} - - -/********************************************************************** - * AVIInit - ********************************************************************** - * Allocates things, create file, initialize and write headers - *********************************************************************/ -static int AVIInit( hb_mux_object_t * m ) -{ - hb_job_t * job = m->job; - hb_title_t * title = job->title; - - hb_audio_t * audio; - hb_mux_data_t * mux_data; - - int audio_count = hb_list_count( title->list_audio ); - int is_ac3 = ( job->acodec & HB_ACODEC_AC3 ); - int hdrl_bytes; - int i; - - /* Allocate index */ - m->index = hb_buffer_init( 1024 * 1024 ); - m->index->size = 0; - - /* Open destination file */ - hb_log( "muxavi: opening %s", job->file ); - m->file = fopen( job->file, "wb" ); - -#define m m->main_header - /* AVI main header */ - m.FourCC = FOURCC( "avih" ); - m.BytesCount = sizeof( hb_avi_main_header_t ) - 8; - m.MicroSecPerFrame = (uint64_t) 1000000 * job->vrate_base / job->vrate; - m.Streams = 1 + audio_count; - m.Width = job->width; - m.Height = job->height; -#undef m - - /* Video track */ - mux_data = calloc( sizeof( hb_mux_data_t ), 1 ); - job->mux_data = mux_data; - -#define h mux_data->header - /* Video stream header */ - h.FourCC = FOURCC( "strh" ); - h.BytesCount = sizeof( hb_avi_stream_header_t ) - 8; - h.Type = FOURCC( "vids" ); - - if( job->vcodec == HB_VCODEC_FFMPEG ) - h.Handler = FOURCC( "divx" ); - else if( job->vcodec == HB_VCODEC_XVID ) - h.Handler = FOURCC( "xvid" ); - else if( job->vcodec == HB_VCODEC_X264 ) - h.Handler = FOURCC( "h264" ); - - h.Scale = job->vrate_base; - h.Rate = job->vrate; -#undef h - -#define f mux_data->format.v - /* Video stream format */ - f.FourCC = FOURCC( "strf" ); - f.BytesCount = sizeof( hb_bitmap_info_t ) - 8; - f.Size = f.BytesCount; - f.Width = job->width; - f.Height = job->height; - f.Planes = 1; - f.BitCount = 24; - if( job->vcodec == HB_VCODEC_FFMPEG ) - f.Compression = FOURCC( "DX50" ); - else if( job->vcodec == HB_VCODEC_XVID ) - f.Compression = FOURCC( "XVID" ); - else if( job->vcodec == HB_VCODEC_X264 ) - f.Compression = FOURCC( "H264" ); -#undef f - - /* Audio tracks */ - for( i = 0; i < hb_list_count( title->list_audio ); i++ ) - { - audio = hb_list_item( title->list_audio, i ); - - mux_data = calloc( sizeof( hb_mux_data_t ), 1 ); - audio->mux_data = mux_data; - -#define h mux_data->header -#define f mux_data->format.a.f -#define m mux_data->format.a.m - /* Audio stream header */ - h.FourCC = FOURCC( "strh" ); - h.BytesCount = sizeof( hb_avi_stream_header_t ) - 8; - h.Type = FOURCC( "auds" ); - h.InitialFrames = 1; - h.Scale = 1; - h.Rate = is_ac3 ? ( audio->bitrate / 8 ) : - ( job->abitrate * 1000 / 8 ); - h.Quality = 0xFFFFFFFF; - h.SampleSize = 1; - - /* Audio stream format */ - f.FourCC = FOURCC( "strf" ); - if( is_ac3 ) - { - f.BytesCount = sizeof( hb_wave_formatex_t ) - 8; - f.FormatTag = 0x2000; - f.Channels = audio->channels; - f.SamplesPerSec = audio->rate; - } - else - { - f.BytesCount = sizeof( hb_wave_formatex_t ) + - sizeof( hb_wave_mp3_t ) - 8; - f.FormatTag = 0x55; - f.Channels = 2; - f.SamplesPerSec = job->arate; - } - f.AvgBytesPerSec = h.Rate; - f.BlockAlign = 1; - if( is_ac3 ) - { - f.Size = 0; - } - else - { - f.Size = sizeof( hb_wave_mp3_t ); - m.Id = 1; - m.Flags = 2; - m.BlockSize = 1152 * f.AvgBytesPerSec / job->arate; - m.FramesPerBlock = 1; - m.CodecDelay = 1393; - } -#undef h -#undef f -#undef m - } - - hdrl_bytes = - /* Main header */ - 4 + sizeof( hb_avi_main_header_t ) + - /* strh for video + audios */ - ( 1 + audio_count ) * ( 12 + sizeof( hb_avi_stream_header_t ) ) + - /* video strf */ - sizeof( hb_bitmap_info_t ) + - /* audios strf */ - audio_count * ( sizeof( hb_wave_formatex_t ) + - ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) ); - - /* Here we really start to write into the file */ - - /* Main headers */ - WriteInt32( m->file, FOURCC( "RIFF" ) ); - WriteInt32( m->file, 2040 ); - WriteInt32( m->file, FOURCC( "AVI " ) ); - WriteInt32( m->file, FOURCC( "LIST" ) ); - WriteInt32( m->file, hdrl_bytes ); - WriteInt32( m->file, FOURCC( "hdrl" ) ); - WriteMainHeader( m->file, &m->main_header ); - - /* Video track */ - mux_data = job->mux_data; - mux_data->fourcc = FOURCC( "00dc" ); - - WriteInt32( m->file, FOURCC( "LIST" ) ); - WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) + - sizeof( hb_bitmap_info_t ) ); - WriteInt32( m->file, FOURCC( "strl" ) ); - WriteStreamHeader( m->file, &mux_data->header ); - WriteBitmapInfo( m->file, &mux_data->format.v ); - - /* Audio tracks */ - for( i = 0; i < audio_count; i++ ) - { - char fourcc[4] = "00wb"; - - audio = hb_list_item( title->list_audio, i ); - mux_data = audio->mux_data; - - fourcc[1] = '1' + i; /* This is fine as we don't allow more - than 8 tracks */ - mux_data->fourcc = FOURCC( fourcc ); - - WriteInt32( m->file, FOURCC( "LIST" ) ); - WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) + - sizeof( hb_wave_formatex_t ) + - ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) ); - WriteInt32( m->file, FOURCC( "strl" ) ); - WriteStreamHeader( m->file, &mux_data->header ); - WriteWaveFormatEx( m->file, &mux_data->format.a.f ); - if( !is_ac3 ) - { - WriteWaveMp3( m->file, &mux_data->format.a.m ); - } - } - - WriteInt32( m->file, FOURCC( "JUNK" ) ); - WriteInt32( m->file, 2020 - hdrl_bytes ); - for( i = 0; i < 2020 - hdrl_bytes; i++ ) - { - WriteInt8( m->file, 0 ); - } - WriteInt32( m->file, FOURCC( "LIST" ) ); - WriteInt32( m->file, 4 ); - WriteInt32( m->file, FOURCC( "movi" ) ); - - return 0; -} - -static int AVIMux( hb_mux_object_t * m, hb_mux_data_t * mux_data, - hb_buffer_t * buf ) -{ - hb_job_t * job = m->job; - hb_title_t * title = job->title; - - hb_audio_t * audio; - int i; - - /* Update index */ - IndexAddInt32( m->index, mux_data->fourcc ); - IndexAddInt32( m->index, buf->key ? AVIIF_KEYFRAME : 0 ); - IndexAddInt32( m->index, 4 + m->size ); - IndexAddInt32( m->index, buf->size ); - - /* Write the chunk to the file */ - fseek( m->file, 0, SEEK_END ); - WriteInt32( m->file, mux_data->fourcc ); - WriteInt32( m->file, buf->size ); - WriteBuffer( m->file, buf ); - - /* Chunks must be 2-bytes aligned */ - if( buf->size & 1 ) - { - WriteInt8( m->file, 0 ); - } - - /* Update headers */ - m->size += 8 + EVEN( buf->size ); - mux_data->header.Length++; - - /* RIFF size */ - fseek( m->file, 4, SEEK_SET ); - WriteInt32( m->file, 2052 + m->size ); - - /* Mmmmh that's not nice */ - fseek( m->file, 140, SEEK_SET ); - WriteInt32( m->file, job->mux_data->header.Length ); - for( i = 0; i < hb_list_count( title->list_audio ); i++ ) - { - audio = hb_list_item( title->list_audio, i ); - fseek( m->file, 264 + i * - ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 : - sizeof( hb_wave_mp3_t ) ) ), SEEK_SET ); - WriteInt32( m->file, audio->mux_data->header.Length ); - } - - /* movi size */ - fseek( m->file, 2052, SEEK_SET ); - WriteInt32( m->file, 4 + m->size ); - return 0; -} - -static int AVIEnd( hb_mux_object_t * m ) -{ - hb_job_t * job = m->job; - - hb_log( "muxavi: writing index" ); - AddIndex( m ); - - hb_log( "muxavi: closing %s", job->file ); - fclose( m->file ); - - hb_buffer_close( &m->index ); - - return 0; -} - -hb_mux_object_t * hb_mux_avi_init( hb_job_t * job ) -{ - hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 ); - m->init = AVIInit; - m->mux = AVIMux; - m->end = AVIEnd; - m->job = job; - return m; -} - |