X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fmuxavi.c;h=85839e1ee9342459d701d2c2fbffefb4ac80f55f;hb=033e32de9c380f54c7d1362a3979da205ebc3a29;hp=0370c88581c4d7fc721e5a4446d6b52326cbba88;hpb=8f57c462e0a0ba59c7c87ef2c721a8052c3e0508;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/muxavi.c b/libhb/muxavi.c index 0370c885..85839e1e 100644 --- a/libhb/muxavi.c +++ b/libhb/muxavi.c @@ -1,10 +1,11 @@ /* $Id: muxavi.c,v 1.10 2005/03/30 18:17:29 titer Exp $ This file is part of the HandBrake source code. - Homepage: . + Homepage: . It may be used under the terms of the GNU General Public License. */ #include "hb.h" +#include "hbffmpeg.h" #define AVIF_HASINDEX 0x10 #define AVIIF_KEYFRAME 0x10 @@ -57,6 +58,31 @@ typedef struct __attribute__((__packed__)) { uint32_t FourCC; uint32_t BytesCount; + uint32_t VideoFormatToken; + uint32_t VideoStandard; + uint32_t dwVerticalRefreshRate; + uint32_t dwHTotalInT; + uint32_t dwVTotalInLines; + uint16_t dwFrameAspectRatioDen; + uint16_t dwFrameAspectRatioNum; + uint32_t dwFrameWidthInPixels; + uint32_t dwFrameHeightInLines; + uint32_t nbFieldPerFrame; + uint32_t CompressedBMHeight; + uint32_t CompressedBMWidth; + uint32_t ValidBMHeight; + uint32_t ValidBMWidth; + uint32_t ValidBMXOffset; + uint32_t ValidBMYOffset; + uint32_t VideoXOffsetInT; + uint32_t VideoYValidStartLine; + +} hb_avi_vprp_info_t; + +typedef struct __attribute__((__packed__)) +{ + uint32_t FourCC; + uint32_t BytesCount; uint32_t Size; uint32_t Width; uint32_t Height; @@ -203,6 +229,30 @@ static void WriteStreamHeader( FILE * file, hb_avi_stream_header_t * header ) WriteInt16( file, header->Bottom ); } +static void WriteVprpInfo( FILE * file, hb_avi_vprp_info_t * info ) +{ + WriteInt32( file, info->FourCC ); + WriteInt32( file, info->BytesCount ); + WriteInt32( file, info->VideoFormatToken ); + WriteInt32( file, info->VideoStandard ); + WriteInt32( file, info->dwVerticalRefreshRate ); + WriteInt32( file, info->dwHTotalInT ); + WriteInt32( file, info->dwVTotalInLines ); + WriteInt16( file, info->dwFrameAspectRatioDen ); + WriteInt16( file, info->dwFrameAspectRatioNum ); + WriteInt32( file, info->dwFrameWidthInPixels ); + WriteInt32( file, info->dwFrameHeightInLines ); + WriteInt32( file, info->nbFieldPerFrame ); + WriteInt32( file, info->CompressedBMHeight ); + WriteInt32( file, info->CompressedBMWidth ); + WriteInt32( file, info->ValidBMHeight ); + WriteInt32( file, info->ValidBMWidth ); + WriteInt32( file, info->ValidBMXOffset ); + WriteInt32( file, info->ValidBMYOffset ); + WriteInt32( file, info->VideoXOffsetInT ); + WriteInt32( file, info->VideoYValidStartLine ); +} + static void IndexAddInt32( hb_buffer_t * b, uint32_t val ) { if( b->size + 16 > b->alloc ) @@ -233,8 +283,9 @@ struct hb_mux_object_s struct hb_mux_data_s { - uint32_t fourcc; - hb_avi_stream_header_t header; + uint32_t fourcc; + hb_avi_stream_header_t header; + hb_avi_vprp_info_t vprp_header; union { hb_bitmap_info_t v; @@ -281,7 +332,8 @@ static int AVIInit( hb_mux_object_t * m ) hb_mux_data_t * mux_data; int audio_count = hb_list_count( title->list_audio ); - int is_ac3 = ( job->acodec & HB_ACODEC_AC3 ); + int is_passthru = 0; + int is_ac3 = 0; int hdrl_bytes; int i; @@ -315,8 +367,6 @@ static int AVIInit( hb_mux_object_t * m ) 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" ); @@ -335,19 +385,50 @@ static int AVIInit( hb_mux_object_t * m ) 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 +#define g mux_data->vprp_header + /* Vprp video stream header */ + AVRational sample_aspect_ratio = ( AVRational ){ job->anamorphic.par_width, job->anamorphic.par_height }; + AVRational dar = av_mul_q( sample_aspect_ratio, ( AVRational ){ job->width, job->height } ); + int num, den; + av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); + + g.FourCC = FOURCC( "vprp" ); + g.BytesCount = sizeof( hb_avi_vprp_info_t ) - 8; + g.VideoFormatToken = 0; + g.VideoStandard = 0; + g.dwVerticalRefreshRate = job->vrate / job->vrate_base; + g.dwHTotalInT = job->width; + g.dwVTotalInLines = job->height; + g.dwFrameAspectRatioDen = den; + g.dwFrameAspectRatioNum = num; + g.dwFrameWidthInPixels = job->width; + g.dwFrameHeightInLines = job->height; + g.nbFieldPerFrame = 1; + g.CompressedBMHeight = job->height; + g.CompressedBMWidth = job->width; + g.ValidBMHeight = job->height; + g.ValidBMWidth = job->width; + g.ValidBMXOffset = 0; + g.ValidBMYOffset = 0; + g.VideoXOffsetInT = 0; + g.VideoYValidStartLine = 0; +#undef g + /* Audio tracks */ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i ); + is_ac3 = (audio->config.out.codec == HB_ACODEC_AC3); + is_passthru = (audio->config.out.codec == HB_ACODEC_AC3) || + (audio->config.out.codec == HB_ACODEC_DCA); + mux_data = calloc( sizeof( hb_mux_data_t ), 1 ); - audio->mux_data = mux_data; + audio->priv.mux_data = mux_data; #define h mux_data->header #define f mux_data->format.a.f @@ -358,31 +439,31 @@ static int AVIInit( hb_mux_object_t * m ) h.Type = FOURCC( "auds" ); h.InitialFrames = 1; h.Scale = 1; - h.Rate = is_ac3 ? ( audio->bitrate / 8 ) : - ( job->abitrate * 1000 / 8 ); + h.Rate = is_passthru ? ( audio->config.in.bitrate / 8 ) : + ( audio->config.out.bitrate * 1000 / 8 ); h.Quality = 0xFFFFFFFF; h.SampleSize = 1; /* Audio stream format */ f.FourCC = FOURCC( "strf" ); - if( is_ac3 ) + if( is_passthru ) { f.BytesCount = sizeof( hb_wave_formatex_t ) - 8; - f.FormatTag = 0x2000; - f.Channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout); - f.SamplesPerSec = audio->rate; + f.FormatTag = is_ac3 ? 0x2000 : 0x2001; + f.Channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->config.in.channel_layout); + f.SamplesPerSec = audio->config.in.samplerate; } else { f.BytesCount = sizeof( hb_wave_formatex_t ) + sizeof( hb_wave_mp3_t ) - 8; f.FormatTag = 0x55; - f.Channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(job->audio_mixdowns[i]); - f.SamplesPerSec = job->arate; + f.Channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); + f.SamplesPerSec = audio->config.out.samplerate; } f.AvgBytesPerSec = h.Rate; f.BlockAlign = 1; - if( is_ac3 ) + if( is_passthru ) { f.Size = 0; } @@ -391,7 +472,7 @@ static int AVIInit( hb_mux_object_t * m ) f.Size = sizeof( hb_wave_mp3_t ); m.Id = 1; m.Flags = 2; - m.BlockSize = 1152 * f.AvgBytesPerSec / job->arate; + m.BlockSize = 1152 * f.AvgBytesPerSec / audio->config.out.samplerate; m.FramesPerBlock = 1; m.CodecDelay = 1393; } @@ -406,10 +487,12 @@ static int AVIInit( hb_mux_object_t * m ) /* strh for video + audios */ ( 1 + audio_count ) * ( 12 + sizeof( hb_avi_stream_header_t ) ) + /* video strf */ - sizeof( hb_bitmap_info_t ) + + sizeof( hb_bitmap_info_t ) + + /* video vprp */ + ( job->anamorphic.mode ? sizeof( hb_avi_vprp_info_t ) : 0 ) + /* audios strf */ audio_count * ( sizeof( hb_wave_formatex_t ) + - ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) ); + ( is_passthru ? 0 : sizeof( hb_wave_mp3_t ) ) ); /* Here we really start to write into the file */ @@ -428,10 +511,15 @@ static int AVIInit( hb_mux_object_t * m ) WriteInt32( m->file, FOURCC( "LIST" ) ); WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) + - sizeof( hb_bitmap_info_t ) ); + sizeof( hb_bitmap_info_t ) + + ( job->anamorphic.mode ? sizeof( hb_avi_vprp_info_t ) : 0 ) ); WriteInt32( m->file, FOURCC( "strl" ) ); WriteStreamHeader( m->file, &mux_data->header ); WriteBitmapInfo( m->file, &mux_data->format.v ); + if( job->anamorphic.mode ) + { + WriteVprpInfo( m->file, &mux_data->vprp_header ); + } /* Audio tracks */ for( i = 0; i < audio_count; i++ ) @@ -439,7 +527,7 @@ static int AVIInit( hb_mux_object_t * m ) char fourcc[4] = "00wb"; audio = hb_list_item( title->list_audio, i ); - mux_data = audio->mux_data; + mux_data = audio->priv.mux_data; fourcc[1] = '1' + i; /* This is fine as we don't allow more than 8 tracks */ @@ -448,11 +536,11 @@ static int AVIInit( hb_mux_object_t * m ) 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 ) ) ); + ( is_passthru ? 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 ) + if( !is_passthru ) { WriteWaveMp3( m->file, &mux_data->format.a.m ); } @@ -511,11 +599,14 @@ static int AVIMux( hb_mux_object_t * m, hb_mux_data_t * mux_data, WriteInt32( m->file, job->mux_data->header.Length ); for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { + int is_passthru; audio = hb_list_item( title->list_audio, i ); + is_passthru = (audio->config.out.codec == HB_ACODEC_AC3) || + (audio->config.out.codec == HB_ACODEC_DCA); fseek( m->file, 264 + i * - ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 : + ( 102 + ( is_passthru ? 0 : sizeof( hb_wave_mp3_t ) ) ), SEEK_SET ); - WriteInt32( m->file, audio->mux_data->header.Length ); + WriteInt32( m->file, audio->priv.mux_data->header.Length ); } /* movi size */