OSDN Git Service

Set MinCache to 1 if we're using x264 and b-frames.
[handbrake-jp/handbrake-jp-git.git] / libhb / muxmkv.c
1 /* $Id:  $
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 /* libmkv header */
8 #include "libmkv.h"
9
10 #include <ogg/ogg.h>
11
12 #include "hb.h"
13
14 struct hb_mux_object_s
15 {
16     HB_MUX_COMMON;
17
18     hb_job_t * job;
19
20     mk_Writer * file;
21 };
22
23 struct hb_mux_data_s
24 {
25     mk_Track  * track;
26     uint64_t  prev_chapter_tc;
27     uint64_t  max_tc;
28     uint16_t  current_chapter;
29 };
30
31 /**********************************************************************
32  * MKVInit
33  **********************************************************************
34  * Allocates hb_mux_data_t structures, create file and write headers
35  *********************************************************************/
36 static int MKVInit( hb_mux_object_t * m )
37 {
38     hb_job_t   * job   = m->job;
39     hb_title_t * title = job->title;
40     hb_audio_t    * audio;
41     hb_mux_data_t * mux_data;
42
43     uint8_t         *avcC = NULL;
44     uint8_t         default_track_flag = 1;
45     int             avcC_len, i;
46     ogg_packet      *ogg_headers[3];
47     mk_TrackConfig *track;
48
49     track = calloc(1, sizeof(mk_TrackConfig));
50
51     m->file = mk_createWriter(job->file, 1000000, 1);
52
53     /* Video track */
54     mux_data      = calloc(1, sizeof( hb_mux_data_t ) );
55     job->mux_data = mux_data;
56
57     track->trackType = MK_TRACK_VIDEO;
58     track->flagDefault = 1;
59     switch (job->vcodec)
60     {
61         case HB_VCODEC_X264:
62             track->codecID = MK_VCODEC_MP4AVC;
63             /* Taken from x264 muxers.c */
64             avcC_len = 5 + 1 + 2 + job->config.h264.sps_length + 1 + 2 + job->config.h264.pps_length;
65             avcC = malloc(avcC_len);
66             if (avcC == NULL)
67                 return -1;
68
69             avcC[0] = 1;
70             avcC[1] = job->config.h264.sps[1];      /* AVCProfileIndication */
71             avcC[2] = job->config.h264.sps[2];      /* profile_compat */
72             avcC[3] = job->config.h264.sps[3];      /* AVCLevelIndication */
73             avcC[4] = 0xff; // nalu size length is four bytes
74             avcC[5] = 0xe1; // one sps
75
76             avcC[6] = job->config.h264.sps_length >> 8;
77             avcC[7] = job->config.h264.sps_length;
78
79             memcpy(avcC+8, job->config.h264.sps, job->config.h264.sps_length);
80
81             avcC[8+job->config.h264.sps_length] = 1; // one pps
82             avcC[9+job->config.h264.sps_length] = job->config.h264.pps_length >> 8;
83             avcC[10+job->config.h264.sps_length] = job->config.h264.pps_length;
84
85             memcpy( avcC+11+job->config.h264.sps_length, job->config.h264.pps, job->config.h264.pps_length );
86             track->codecPrivate = avcC;
87             track->codecPrivateSize = avcC_len;
88             if (job->areBframes)
89                 track->minCache = 1;
90             break;
91         case HB_VCODEC_XVID:
92         case HB_VCODEC_FFMPEG:
93             track->codecID = MK_VCODEC_MP4ASP;
94             track->codecPrivate = job->config.mpeg4.bytes;
95             track->codecPrivateSize = job->config.mpeg4.length;
96             break;
97         default:
98             *job->die = 1;
99             hb_log("muxmkv: Unknown video codec: %x", job->vcodec);
100             return 0;
101     }
102
103     track->video.pixelWidth = job->width;
104     track->video.pixelHeight = job->height;
105     track->video.displayHeight = job->height;
106     if(job->pixel_ratio)
107     {
108         track->video.displayWidth = job->width * ((double)job->pixel_aspect_width / (double)job->pixel_aspect_height);
109     }
110     else
111     {
112         track->video.displayWidth = job->width;
113     }
114
115
116     track->defaultDuration = (int64_t)(((float)job->vrate_base / (float)job->vrate) * 1000000000);
117
118     mux_data->track = mk_createTrack(m->file, track);
119
120     memset(track, 0, sizeof(mk_TrackConfig));
121
122     /* add the audio tracks */
123     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
124     {
125         audio = hb_list_item( title->list_audio, i );
126         mux_data = malloc( sizeof( hb_mux_data_t ) );
127         audio->mux_data = mux_data;
128
129         switch (job->acodec)
130         {
131             case HB_ACODEC_AC3:
132                 track->codecPrivate = NULL;
133                 track->codecPrivateSize = 0;
134                 track->codecID = MK_ACODEC_AC3;
135                 break;
136             case HB_ACODEC_LAME:
137                 track->codecPrivate = NULL;
138                 track->codecPrivateSize = 0;
139                 track->codecID = MK_ACODEC_MP3;
140                 break;
141             case HB_ACODEC_VORBIS:
142                 {
143                     int i, j;
144                     int64_t offset = 0;
145                     int64_t cp_size = 0;
146                     char    *cp;
147                     track->codecID = MK_ACODEC_VORBIS;
148                     cp_size = sizeof( char );
149                     for (i = 0; i < 3; ++i)
150                     {
151                         ogg_headers[i] = (ogg_packet *)audio->config.vorbis.headers[i];
152                         ogg_headers[i]->packet = (unsigned char *)&audio->config.vorbis.headers[i] + sizeof( ogg_packet );
153                         cp_size += (sizeof( char ) * ((ogg_headers[i]->bytes / 255) + 1)) + ogg_headers[i]->bytes;
154                             /* This will be too big, but it doesn't matter, as we only need it to be big enough. */
155                     }
156                     cp = track->codecPrivate = calloc(1, cp_size);
157                     cp[offset++] = 0x02;
158                     for (i = 0; i < 2; ++i)
159                     {
160                         for (j = ogg_headers[i]->bytes; j >= 255; j -= 255)
161                         {
162                             cp[offset++] = 255;
163                         }
164                         cp[offset++] = j;
165                     }
166                     for(i = 0; i < 3; ++i)
167                     {
168                         memcpy(cp + offset, ogg_headers[i]->packet, ogg_headers[i]->bytes);
169                         offset += ogg_headers[i]->bytes;
170                     }
171                     track->codecPrivateSize = offset;
172                 }
173                 break;
174             case HB_ACODEC_FAAC:
175                 track->codecPrivate = audio->config.aac.bytes;
176                 track->codecPrivateSize = audio->config.aac.length;
177                 track->codecID = MK_ACODEC_AAC;
178                 break;
179             default:
180                 *job->die = 1;
181                 hb_log("muxmkv: Unknown audio codec: %x", job->acodec);
182                 return 0;
183         }
184         
185         if (default_track_flag)
186         {
187             track->flagDefault = 1;
188             default_track_flag = 0;
189         }
190         
191         track->trackType = MK_TRACK_AUDIO;
192         track->language = audio->iso639_2;
193         track->audio.samplingFreq = (float)job->arate;
194         track->audio.channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);
195 //        track->defaultDuration = job->arate * 1000;
196         mux_data->track = mk_createTrack(m->file, track);
197         if (job->acodec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
198           free(track->codecPrivate);
199     }
200
201     mk_writeHeader( m->file, "HandBrake " HB_VERSION);
202     if (track != NULL)
203         free(track);
204     if (avcC != NULL)
205         free(avcC);
206
207     return 0;
208 }
209
210 static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
211                    hb_buffer_t * buf )
212 {
213     hb_job_t * job = m->job;
214     hb_title_t * title = job->title;
215     uint64_t   timecode = 0;
216     hb_chapter_t *chapter_data;
217     char tmp_buffer[1024];
218     char *string = tmp_buffer;
219     if (mux_data == job->mux_data)
220     {
221         /* Video */
222         /* Where does the 11130 come from? I had to calculate it from the actual
223           * and the observed duration of the file. Otherwise the timecodes come
224           * out way too small, and you get a 2hr movie that plays in .64 sec.  */
225         if ((job->vcodec == HB_VCODEC_X264) && (buf->frametype & HB_FRAME_REF))
226         {
227             timecode = (buf->start + (buf->renderOffset - 1000000)) * 11130;
228         }
229         else
230         {
231             timecode = buf->start * 11130;
232         }
233
234         if (job->chapter_markers && (buf->new_chap || timecode == 0))
235         {
236             /* Make sure we're not writing a chapter that has 0 length */
237             if (mux_data->prev_chapter_tc != timecode)
238             {
239                 chapter_data = hb_list_item( title->list_chapter, mux_data->current_chapter );
240                 tmp_buffer[0] = '\0';
241
242                 if( chapter_data != NULL )
243                 {
244                     string = chapter_data->title;
245                 }
246
247                 if( strlen(string) == 0 || strlen(string) >= 1024 )
248                 {
249                     snprintf( tmp_buffer, 1023, "Chapter %02i", mux_data->current_chapter++ );
250                     string = tmp_buffer;
251                 }
252                 mk_createChapterSimple(m->file, mux_data->prev_chapter_tc, timecode, string);
253             }
254             mux_data->prev_chapter_tc = timecode;
255         }
256
257         if (buf->stop * 11130 > mux_data->max_tc)
258             mux_data->max_tc = buf->stop * 11130;
259     }
260     else
261     {
262         /* Audio */
263         timecode = buf->start * 11130;
264         if (job->acodec == HB_ACODEC_VORBIS)
265         {
266             /* ughhh, vorbis is a pain :( */
267             ogg_packet  *op;
268
269             op = (ogg_packet *)buf->data;
270             op->packet = buf->data + sizeof( ogg_packet );
271             mk_startFrame(m->file, mux_data->track);
272             mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
273             mk_setFrameFlags(m->file, mux_data->track, timecode, 1);
274             return 0;
275         }
276     }
277
278     mk_startFrame(m->file, mux_data->track);
279     mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
280     mk_setFrameFlags(m->file, mux_data->track, timecode,
281         ((job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data) ? (buf->frametype == HB_FRAME_IDR) : ((buf->frametype & HB_FRAME_KEY) != 0)) );
282     return 0;
283 }
284
285 static int MKVEnd( hb_mux_object_t * m )
286 {
287     hb_job_t  *job = m->job;
288     hb_mux_data_t *mux_data = job->mux_data;
289     hb_title_t  *title = job->title;
290     hb_chapter_t *chapter_data = hb_list_item( title->list_chapter, mux_data->current_chapter );
291     char tmp_buffer[1024];
292     char *string = tmp_buffer;
293
294     if(job->chapter_markers)
295     {
296         tmp_buffer[0] = '\0';
297
298         if( chapter_data != NULL )
299         {
300             string = chapter_data->title;
301         }
302
303         if( strlen(string) == 0 || strlen(string) >= 1024 )
304         {
305             snprintf( tmp_buffer, 1023, "Chapter %02i", mux_data->current_chapter );
306             string = tmp_buffer;
307         }
308         mk_createChapterSimple(m->file, mux_data->prev_chapter_tc, mux_data->max_tc, string);
309     }
310
311     mk_close(m->file);
312
313     // TODO: Free what we alloc'd
314
315     return 0;
316 }
317
318 hb_mux_object_t * hb_mux_mkv_init( hb_job_t * job )
319 {
320     hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
321     m->init      = MKVInit;
322     m->mux       = MKVMux;
323     m->end       = MKVEnd;
324     m->job       = job;
325     return m;
326 }