OSDN Git Service

Don't drop subtitles when crossing PTS discontinuities by using buffer sequence numbe...
[handbrake-jp/handbrake-jp-git.git] / libhb / muxavi.c
1 /* $Id: muxavi.c,v 1.10 2005/03/30 18:17:29 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 #define AVIF_HASINDEX  0x10
10 #define AVIIF_KEYFRAME 0x10
11 #define FOURCC(a)      ((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0])
12
13 /* Structures definitions */
14 typedef struct __attribute__((__packed__))
15 {
16     uint32_t FourCC;
17     uint32_t BytesCount;
18     uint32_t MicroSecPerFrame;
19     uint32_t MaxBytesPerSec;
20     uint32_t PaddingGranularity;
21     uint32_t Flags;
22     uint32_t TotalFrames;
23     uint32_t InitialFrames;
24     uint32_t Streams;
25     uint32_t SuggestedBufferSize;
26     uint32_t Width;
27     uint32_t Height;
28     uint32_t Reserved[4];
29
30 } hb_avi_main_header_t;
31
32 typedef struct __attribute__((__packed__))
33 {
34     uint32_t FourCC;
35     uint32_t BytesCount;
36     uint32_t Type;
37     uint32_t Handler;
38     uint32_t Flags;
39     uint16_t Priority;
40     uint16_t Language;
41     uint32_t InitialFrames;
42     uint32_t Scale;
43     uint32_t Rate;
44     uint32_t Start;
45     uint32_t Length;
46     uint32_t SuggestedBufferSize;
47     uint32_t Quality;
48     uint32_t SampleSize;
49     int16_t  Left;
50     int16_t  Top;
51     int16_t  Right;
52     int16_t  Bottom;
53
54 } hb_avi_stream_header_t;
55
56 typedef struct __attribute__((__packed__))
57 {
58     uint32_t FourCC;
59     uint32_t BytesCount;
60     uint32_t Size;
61     uint32_t Width;
62     uint32_t Height;
63     uint16_t Planes;
64     uint16_t BitCount;
65     uint32_t Compression;
66     uint32_t SizeImage;
67     uint32_t XPelsPerMeter;
68     uint32_t YPelsPerMeter;
69     uint32_t ClrUsed;
70     uint32_t ClrImportant;
71
72 } hb_bitmap_info_t;
73
74 typedef struct __attribute__((__packed__))
75 {
76     uint32_t FourCC;
77     uint32_t BytesCount;
78     uint16_t FormatTag;
79     uint16_t Channels;
80     uint32_t SamplesPerSec;
81     uint32_t AvgBytesPerSec;
82     uint16_t BlockAlign;
83     uint16_t BitsPerSample;
84     uint16_t Size;
85
86 } hb_wave_formatex_t;
87
88 typedef struct __attribute__((__packed__))
89 {
90     uint16_t Id;
91     uint32_t Flags;
92     uint16_t BlockSize;
93     uint16_t FramesPerBlock;
94     uint16_t CodecDelay;
95
96 } hb_wave_mp3_t;
97
98 static void WriteBuffer( FILE * file, hb_buffer_t * buf )
99 {
100     fwrite( buf->data, buf->size, 1, file );
101 }
102
103 /* Little-endian write routines */
104
105 static void WriteInt8( FILE * file, uint8_t val )
106 {
107     fputc( val, file );
108 }   
109
110 static void WriteInt16( FILE * file, uint16_t val )
111 {
112     fputc( val & 0xFF, file );
113     fputc( val >> 8, file );
114 }
115
116 static void WriteInt32( FILE * file, uint32_t val )
117 {
118     fputc( val & 0xFF, file );
119     fputc( ( val >> 8 ) & 0xFF, file );
120     fputc( ( val >> 16 ) & 0xFF, file );
121     fputc( val >> 24, file );
122 }
123
124 static void WriteBitmapInfo( FILE * file, hb_bitmap_info_t * info )
125 {
126     WriteInt32( file, info->FourCC );
127     WriteInt32( file, info->BytesCount );
128     WriteInt32( file, info->Size );
129     WriteInt32( file, info->Width );
130     WriteInt32( file, info->Height );
131     WriteInt16( file, info->Planes );
132     WriteInt16( file, info->BitCount );
133     WriteInt32( file, info->Compression );
134     WriteInt32( file, info->SizeImage );
135     WriteInt32( file, info->XPelsPerMeter );
136     WriteInt32( file, info->YPelsPerMeter );
137     WriteInt32( file, info->ClrUsed );
138     WriteInt32( file, info->ClrImportant );
139 }
140
141 static void WriteWaveFormatEx( FILE * file, hb_wave_formatex_t * format )
142 {
143     WriteInt32( file, format->FourCC );
144     WriteInt32( file, format->BytesCount );
145     WriteInt16( file, format->FormatTag );
146     WriteInt16( file, format->Channels );
147     WriteInt32( file, format->SamplesPerSec );
148     WriteInt32( file, format->AvgBytesPerSec );
149     WriteInt16( file, format->BlockAlign );
150     WriteInt16( file, format->BitsPerSample );
151     WriteInt16( file, format->Size );
152 }
153
154 static void WriteWaveMp3( FILE * file, hb_wave_mp3_t * mp3 )
155 {
156     WriteInt16( file, mp3->Id );
157     WriteInt32( file, mp3->Flags );
158     WriteInt16( file, mp3->BlockSize );
159     WriteInt16( file, mp3->FramesPerBlock );
160     WriteInt16( file, mp3->CodecDelay );
161 }
162
163 static void WriteMainHeader( FILE * file, hb_avi_main_header_t * header )
164 {
165     WriteInt32( file, header->FourCC );
166     WriteInt32( file, header->BytesCount );
167     WriteInt32( file, header->MicroSecPerFrame );
168     WriteInt32( file, header->MaxBytesPerSec );
169     WriteInt32( file, header->PaddingGranularity );
170     WriteInt32( file, header->Flags );
171     WriteInt32( file, header->TotalFrames );
172     WriteInt32( file, header->InitialFrames );
173     WriteInt32( file, header->Streams );
174     WriteInt32( file, header->SuggestedBufferSize );
175     WriteInt32( file, header->Width );
176     WriteInt32( file, header->Height );
177     WriteInt32( file, header->Reserved[0] );
178     WriteInt32( file, header->Reserved[1] );
179     WriteInt32( file, header->Reserved[2] );
180     WriteInt32( file, header->Reserved[3] );
181 }
182
183 static void WriteStreamHeader( FILE * file, hb_avi_stream_header_t * header )
184 {
185     WriteInt32( file, header->FourCC );
186     WriteInt32( file, header->BytesCount );
187     WriteInt32( file, header->Type );
188     WriteInt32( file, header->Handler );
189     WriteInt32( file, header->Flags );
190     WriteInt16( file, header->Priority );
191     WriteInt16( file, header->Language );
192     WriteInt32( file, header->InitialFrames );
193     WriteInt32( file, header->Scale );
194     WriteInt32( file, header->Rate );
195     WriteInt32( file, header->Start );
196     WriteInt32( file, header->Length );
197     WriteInt32( file, header->SuggestedBufferSize );
198     WriteInt32( file, header->Quality );
199     WriteInt32( file, header->SampleSize );
200     WriteInt16( file, header->Left );
201     WriteInt16( file, header->Top );
202     WriteInt16( file, header->Right );
203     WriteInt16( file, header->Bottom );
204 }
205
206 static void IndexAddInt32( hb_buffer_t * b, uint32_t val )
207 {
208     if( b->size + 16 > b->alloc )
209     {
210         hb_log( "muxavi: reallocing index (%d MB)",
211                 1 + b->alloc / 1024 / 1024 );
212         hb_buffer_realloc( b, b->alloc + 1024 * 1024 );
213     }
214
215     b->data[b->size++] = val & 0xFF;
216     b->data[b->size++] = ( val >> 8 ) & 0xFF;
217     b->data[b->size++] = ( val >> 16 ) & 0xFF;
218     b->data[b->size++] = val >> 24;
219 }
220
221 struct hb_mux_object_s
222 {
223     HB_MUX_COMMON;
224
225     hb_job_t * job;
226
227     /* Data size in bytes, not including headers */
228     unsigned               size;
229     FILE                 * file;
230     hb_buffer_t          * index;
231     hb_avi_main_header_t   main_header;
232 };
233
234 struct hb_mux_data_s
235 {
236     uint32_t               fourcc;
237     hb_avi_stream_header_t header;
238     union
239     {
240         hb_bitmap_info_t   v;
241         struct
242         {
243             hb_wave_formatex_t f;
244             hb_wave_mp3_t      m;
245         } a;
246     } format;
247 };
248
249 static void AddIndex( hb_mux_object_t * m )
250 {
251     fseek( m->file, 0, SEEK_END );
252
253     /* Write the index at the end of the file */
254     WriteInt32( m->file, FOURCC( "idx1" ) );
255     WriteInt32( m->file, m->index->size );
256     WriteBuffer( m->file, m->index );
257
258     /* Update file size */
259     m->size += 8 + m->index->size;
260     fseek( m->file, 4, SEEK_SET );
261     WriteInt32( m->file, 2040 + m->size );
262
263     /* Update HASINDEX flag */
264     m->main_header.Flags |= AVIF_HASINDEX;
265     fseek( m->file, 24, SEEK_SET );
266     WriteMainHeader( m->file, &m->main_header );
267 }
268
269
270 /**********************************************************************
271  * AVIInit
272  **********************************************************************
273  * Allocates things, create file, initialize and write headers
274  *********************************************************************/
275 static int AVIInit( hb_mux_object_t * m )
276 {
277     hb_job_t   * job   = m->job;
278     hb_title_t * title = job->title;
279
280     hb_audio_t    * audio;
281     hb_mux_data_t * mux_data;
282
283     int audio_count = hb_list_count( title->list_audio );
284     int is_ac3      = ( job->acodec & HB_ACODEC_AC3 );
285     int hdrl_bytes;
286     int i;
287
288     /* Allocate index */
289     m->index       = hb_buffer_init( 1024 * 1024 );
290     m->index->size = 0;
291
292     /* Open destination file */
293     hb_log( "muxavi: opening %s", job->file );
294     m->file = fopen( job->file, "wb" );
295
296 #define m m->main_header
297     /* AVI main header */
298     m.FourCC           = FOURCC( "avih" );
299     m.BytesCount       = sizeof( hb_avi_main_header_t ) - 8;
300     m.MicroSecPerFrame = (uint64_t) 1000000 * job->vrate_base / job->vrate;
301     m.Streams          = 1 + audio_count;
302     m.Width            = job->width;
303     m.Height           = job->height;
304 #undef m
305
306     /* Video track */
307     mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
308     job->mux_data = mux_data;
309     
310 #define h mux_data->header
311     /* Video stream header */
312     h.FourCC     = FOURCC( "strh" );
313     h.BytesCount = sizeof( hb_avi_stream_header_t ) - 8;
314     h.Type       = FOURCC( "vids" );
315
316     if( job->vcodec == HB_VCODEC_FFMPEG )
317         h.Handler = FOURCC( "divx" );
318     else if( job->vcodec == HB_VCODEC_XVID )
319         h.Handler = FOURCC( "xvid" );
320     else if( job->vcodec == HB_VCODEC_X264 )
321         h.Handler = FOURCC( "h264" );
322
323     h.Scale      = job->vrate_base;
324     h.Rate       = job->vrate;
325 #undef h
326
327 #define f mux_data->format.v
328     /* Video stream format */
329     f.FourCC      = FOURCC( "strf" );
330     f.BytesCount  = sizeof( hb_bitmap_info_t ) - 8;
331     f.Size        = f.BytesCount;
332     f.Width       = job->width;
333     f.Height      = job->height;
334     f.Planes      = 1;
335     f.BitCount    = 24;
336     if( job->vcodec == HB_VCODEC_FFMPEG )
337         f.Compression = FOURCC( "DX50" );
338     else if( job->vcodec == HB_VCODEC_XVID )
339         f.Compression = FOURCC( "XVID" );
340     else if( job->vcodec == HB_VCODEC_X264 )
341         f.Compression = FOURCC( "H264" );
342 #undef f
343
344     /* Audio tracks */
345     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
346     {
347         audio = hb_list_item( title->list_audio, i );
348
349         mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
350         audio->mux_data = mux_data;
351
352 #define h mux_data->header
353 #define f mux_data->format.a.f
354 #define m mux_data->format.a.m
355         /* Audio stream header */
356         h.FourCC        = FOURCC( "strh" );
357         h.BytesCount    = sizeof( hb_avi_stream_header_t ) - 8;
358         h.Type          = FOURCC( "auds" );
359         h.InitialFrames = 1;
360         h.Scale         = 1;
361         h.Rate          = is_ac3 ? ( audio->bitrate / 8 ) :
362                                    ( job->abitrate * 1000 / 8 );
363         h.Quality       = 0xFFFFFFFF;
364         h.SampleSize    = 1;
365
366         /* Audio stream format */
367         f.FourCC         = FOURCC( "strf" );
368         if( is_ac3 )
369         {
370             f.BytesCount     = sizeof( hb_wave_formatex_t ) - 8;
371             f.FormatTag      = 0x2000;
372             f.Channels       = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout);
373             f.SamplesPerSec  = audio->rate;
374         }
375         else
376         {
377             f.BytesCount     = sizeof( hb_wave_formatex_t ) +
378                                sizeof( hb_wave_mp3_t ) - 8;
379             f.FormatTag      = 0x55;
380             f.Channels       = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(job->audio_mixdowns[i]);
381             f.SamplesPerSec  = job->arate;
382         }
383         f.AvgBytesPerSec = h.Rate;
384         f.BlockAlign     = 1;
385         if( is_ac3 )
386         {
387             f.Size       = 0;
388         }
389         else
390         {
391             f.Size           = sizeof( hb_wave_mp3_t );
392             m.Id             = 1;
393             m.Flags          = 2;
394             m.BlockSize      = 1152 * f.AvgBytesPerSec / job->arate;
395             m.FramesPerBlock = 1;
396             m.CodecDelay     = 1393;
397         }
398 #undef h
399 #undef f
400 #undef m
401     }
402
403     hdrl_bytes =
404         /* Main header */
405         4 + sizeof( hb_avi_main_header_t ) +
406         /* strh for video + audios */
407         ( 1 + audio_count ) * ( 12 + sizeof( hb_avi_stream_header_t ) ) +
408         /* video strf */
409         sizeof( hb_bitmap_info_t ) +
410         /* audios strf */
411         audio_count * ( sizeof( hb_wave_formatex_t ) +
412                         ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) );
413
414     /* Here we really start to write into the file */
415
416     /* Main headers */
417     WriteInt32( m->file, FOURCC( "RIFF" ) );
418     WriteInt32( m->file, 2040 );
419     WriteInt32( m->file, FOURCC( "AVI " ) );
420     WriteInt32( m->file, FOURCC( "LIST" ) );
421     WriteInt32( m->file, hdrl_bytes );
422     WriteInt32( m->file, FOURCC( "hdrl" ) );
423     WriteMainHeader( m->file, &m->main_header );
424
425     /* Video track */
426     mux_data          = job->mux_data;
427     mux_data->fourcc = FOURCC( "00dc" );
428
429     WriteInt32( m->file, FOURCC( "LIST" ) );
430     WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) +
431                 sizeof( hb_bitmap_info_t ) );
432     WriteInt32( m->file, FOURCC( "strl" ) );
433     WriteStreamHeader( m->file, &mux_data->header );
434     WriteBitmapInfo( m->file, &mux_data->format.v );
435
436     /* Audio tracks */
437     for( i = 0; i < audio_count; i++ )
438     {
439         char fourcc[4] = "00wb";
440         
441         audio    = hb_list_item( title->list_audio, i );
442         mux_data = audio->mux_data;
443
444         fourcc[1] = '1' + i; /* This is fine as we don't allow more
445                                 than 8 tracks */
446         mux_data->fourcc = FOURCC( fourcc );
447
448         WriteInt32( m->file, FOURCC( "LIST" ) );
449         WriteInt32( m->file, 4 + sizeof( hb_avi_stream_header_t ) +
450                              sizeof( hb_wave_formatex_t ) +
451                              ( is_ac3 ? 0 : sizeof( hb_wave_mp3_t ) ) );
452         WriteInt32( m->file, FOURCC( "strl" ) );
453         WriteStreamHeader( m->file, &mux_data->header );
454         WriteWaveFormatEx( m->file, &mux_data->format.a.f );
455         if( !is_ac3 )
456         {
457             WriteWaveMp3( m->file, &mux_data->format.a.m );
458         }
459     }
460
461     WriteInt32( m->file, FOURCC( "JUNK" ) );
462     WriteInt32( m->file, 2020 - hdrl_bytes );
463     for( i = 0; i < 2020 - hdrl_bytes; i++ )
464     {
465         WriteInt8( m->file, 0 );
466     }
467     WriteInt32( m->file, FOURCC( "LIST" ) );
468     WriteInt32( m->file, 4 );
469     WriteInt32( m->file, FOURCC( "movi" ) );
470
471     return 0;
472 }
473
474 static int AVIMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
475                    hb_buffer_t * buf )
476 {
477     hb_job_t   * job   = m->job;
478     hb_title_t * title = job->title;
479
480     hb_audio_t * audio;
481     int i;
482
483     /* Update index */
484     IndexAddInt32( m->index, mux_data->fourcc );
485     IndexAddInt32( m->index, (buf->frametype & HB_FRAME_KEY) ? AVIIF_KEYFRAME : 0 );
486     IndexAddInt32( m->index, 4 + m->size );
487     IndexAddInt32( m->index, buf->size );
488
489     /* Write the chunk to the file */
490     fseek( m->file, 0, SEEK_END );
491     WriteInt32( m->file, mux_data->fourcc );
492     WriteInt32( m->file, buf->size );
493     WriteBuffer( m->file, buf );
494
495     /* Chunks must be 2-bytes aligned */
496     if( buf->size & 1 )
497     {
498         WriteInt8( m->file, 0 );
499     }
500
501     /* Update headers */ 
502     m->size += 8 + EVEN( buf->size );
503     mux_data->header.Length++;
504
505     /* RIFF size */ 
506     fseek( m->file, 4, SEEK_SET );
507     WriteInt32( m->file, 2052 + m->size );
508
509     /* Mmmmh that's not nice */
510     fseek( m->file, 140, SEEK_SET );
511     WriteInt32( m->file, job->mux_data->header.Length );
512     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
513     {
514         audio = hb_list_item( title->list_audio, i );
515         fseek( m->file, 264 + i *
516                ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 :
517                  sizeof( hb_wave_mp3_t ) ) ), SEEK_SET );
518         WriteInt32( m->file, audio->mux_data->header.Length );
519     }
520
521     /* movi size */
522     fseek( m->file, 2052, SEEK_SET );
523     WriteInt32( m->file, 4 + m->size );
524     return 0;
525 }
526
527 static int AVIEnd( hb_mux_object_t * m )
528 {
529     hb_job_t * job = m->job;
530
531     hb_log( "muxavi: writing index" );
532     AddIndex( m );
533
534     hb_log( "muxavi: closing %s", job->file );
535     fclose( m->file );
536
537     hb_buffer_close( &m->index );
538
539     return 0;
540 }
541
542 hb_mux_object_t * hb_mux_avi_init( hb_job_t * job )
543 {
544     hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
545     m->init      = AVIInit;
546     m->mux       = AVIMux;
547     m->end       = AVIEnd;
548     m->job       = job;
549     return m;
550 }
551