1 #include "libavcodec/avcodec.h"
2 #include "colormodels.h"
3 #include "funcprotos.h"
6 #include "workarounds.h"
11 // This generates our own header using fixed parameters
12 //#define MANUAL_HEADER
18 x264_t *encoder[FIELDS];
19 x264_picture_t *pic[FIELDS];
22 int encode_initialized[FIELDS];
24 // Temporary storage for color conversions
26 // Storage of compressed data
27 unsigned char *work_buffer;
28 // Amount of data in work_buffer
35 quicktime_ffmpeg_t *decoder;
37 } quicktime_h264_codec_t;
39 static pthread_mutex_t h264_lock = PTHREAD_MUTEX_INITIALIZER;
42 // Direct copy routines
43 int quicktime_h264_is_key(unsigned char *data, long size, char *codec_id)
49 static void delete_codec(quicktime_video_map_t *vtrack)
52 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
54 for(i = 0; i < codec->total_fields; i++) {
55 if( !codec->encode_initialized[i]) continue;
56 pthread_mutex_lock(&h264_lock);
58 x264_picture_clean(codec->pic[i]);
61 if(codec->encoder[i]) {
62 x264_encoder_close(codec->encoder[i]);
64 pthread_mutex_unlock(&h264_lock);
67 if(codec->temp_frame) free(codec->temp_frame);
68 if(codec->work_buffer) free(codec->work_buffer);
69 if(codec->decoder) quicktime_delete_ffmpeg(codec->decoder);
75 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
77 // int64_t offset = quicktime_position(file);
78 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
79 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
80 quicktime_trak_t *trak = vtrack->track;
81 int width = quicktime_video_width(file, track);
82 int height = quicktime_video_height(file, track);
83 int w_2 = quicktime_quantize2(width);
84 // ffmpeg interprets the codec height as the presentation height
85 int h_2 = quicktime_quantize2(height);
89 int frame_number = vtrack->current_position / codec->total_fields;
90 int current_field = vtrack->current_position % codec->total_fields;
91 quicktime_atom_t chunk_atom;
92 unsigned char header[1024];
96 quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc;
98 pthread_mutex_lock(&h264_lock);
100 if(!codec->encode_initialized[current_field])
102 codec->encode_initialized[current_field] = 1;
103 codec->param.i_width = w_2;
104 codec->param.i_height = h_2;
105 codec->param.i_fps_num = quicktime_frame_rate_n(file, track);
106 codec->param.i_fps_den = quicktime_frame_rate_d(file, track);
108 // Reset quantizer if fixed bitrate
109 x264_param_t default_params;
110 x264_param_default(&default_params);
111 if(codec->param.rc.i_qp_constant)
113 codec->param.rc.i_qp_constant = default_params.rc.i_qp_constant;
114 codec->param.rc.i_qp_min = default_params.rc.i_qp_min;
115 codec->param.rc.i_qp_max = default_params.rc.i_qp_max;
120 codec->param.i_threads = file->cpus;
123 codec->encoder[current_field] = x264_encoder_open(&codec->param);
124 codec->pic[current_field] = calloc(1, sizeof(x264_picture_t));
125 x264_picture_init(codec->pic[current_field]);
126 //printf("encode 1 %d %d\n", codec->param.i_width, codec->param.i_height);
127 x264_picture_alloc(codec->pic[current_field], X264_CSP_I420,
128 codec->param.i_width, codec->param.i_height);
131 x264_picture_t *pic = codec->pic[current_field];
132 pic->i_type = X264_TYPE_AUTO;
133 pic->i_qpplus1 = X264_QP_AUTO;
134 pic->i_pts = frame_number;
136 codec->buffer_size = 0;
137 int allocation = w_2 * h_2 * 3 + 100;
138 if( !codec->work_buffer ) {
139 codec->work_buffer = calloc(1, allocation);
142 x264_picture_t pic_out;
145 x264_t *h = codec->encoder[current_field];
147 if( !codec->flushing ) {
148 if( !row_pointers ) {
149 bzero(pic->img.plane[0], w_2 * h_2);
150 bzero(pic->img.plane[1], w_2 * h_2 / 4);
151 bzero(pic->img.plane[2], w_2 * h_2 / 4);
153 else if( file->color_model == BC_YUV420P ) {
154 memcpy(pic->img.plane[0], row_pointers[0], w_2 * h_2);
155 memcpy(pic->img.plane[1], row_pointers[1], w_2 * h_2 / 4);
156 memcpy(pic->img.plane[2], row_pointers[2], w_2 * h_2 / 4);
159 //printf("encode 2 %p %p %p\n", pic->img.plane[0], pic->img.plane[1], pic->img.plane[2]);
160 cmodel_transfer(0, row_pointers,
161 pic->img.plane[0], pic->img.plane[1], pic->img.plane[2],
162 row_pointers[0], row_pointers[1], row_pointers[2],
163 0, 0, width, height, 0, 0, width, height,
164 file->color_model, BC_YUV420P,
165 0, width, pic->img.i_stride[0]);
168 result = x264_encoder_encode(h, &nals, &nnal, pic, &pic_out);
170 printf("frame_num %d: nals=%d, ret=%d\n", frame_number, nnal, result);
172 else if( x264_encoder_delayed_frames(h) > 0 ) {
173 result = x264_encoder_encode(h, &nals, &nnal, 0, &pic_out);
175 printf("flushing %d: nals=%d, ret=%d\n", frame_number, nnal, result);
177 //printf("encode %d nnal=%d\n", __LINE__, nnal);
179 for( i = 0; i < nnal; ++i ) {
180 int size = nals[i].i_payload;
181 //printf("encode %d size=%d\n", __LINE__, size);
182 if(size + codec->buffer_size > allocation) {
183 printf("qth264.c %d: overflow size=%d allocation=%d\n",
184 __LINE__, size, allocation);
187 unsigned char *ptr = codec->work_buffer + codec->buffer_size;
188 memcpy(ptr, nals[i].p_payload, size);
189 codec->buffer_size += size;
190 if( avcc->data_size ) continue;
193 // Synthesize header.
194 // Hopefully all the parameter set NAL's are present in the first frame.
196 header[header_size++] = 0x01;
197 header[header_size++] = 0x4d;
198 header[header_size++] = 0x40;
199 header[header_size++] = 0x1f;
200 header[header_size++] = 0xff;
201 header[header_size++] = 0xe1;
204 int nal_type = (*ptr & 0x1f);
205 // Picture parameter or sequence parameter set
208 if( got_sps ) continue;
212 if( got_pps ) continue;
214 header[header_size++] = 0x1; // Number of sps nal's.
220 header[header_size++] = size >> 8;
221 header[header_size++] = size;
222 memcpy(&header[header_size], ptr, size);
224 if( !got_sps || !got_pps ) continue;
225 // printf("encode %d\n", __LINE__);
226 // { int j; for(j = 0; j < header_size; j++) printf("%02x ", header[j]); }
229 quicktime_set_avcc_header(avcc, header, header_size);
232 pthread_mutex_unlock(&h264_lock);
234 if( codec->buffer_size > 0 ) {
235 if(pic_out.i_type == X264_TYPE_IDR ||
236 pic_out.i_type == X264_TYPE_I) {
240 quicktime_write_chunk_header(file, trak, &chunk_atom);
241 result = !quicktime_write_data(file,
242 (char*)codec->work_buffer,
244 quicktime_write_chunk_footer(file, trak,
245 vtrack->current_chunk, &chunk_atom, 1);
248 quicktime_insert_keyframe(file,
249 vtrack->current_position,
253 vtrack->current_chunk++;
255 return result >= 0 ? 0 : -1;
261 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
263 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
264 quicktime_trak_t *trak = vtrack->track;
265 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
266 quicktime_stsd_table_t *stsd_table = &trak->mdia.minf.stbl.stsd.table[0];
267 int width = trak->tkhd.track_width;
268 int height = trak->tkhd.track_height;
271 codec->decoder = quicktime_new_ffmpeg(file->cpus,
272 codec->total_fields, CODEC_ID_H264, width, height, stsd_table);
273 return !codec->decoder ? 1 :
274 quicktime_ffmpeg_decode(codec->decoder, file, row_pointers, track);
277 static void flush(quicktime_t *file, int track)
279 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
280 quicktime_trak_t *trak = vtrack->track;
281 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
282 // trak->mdia.minf.stbl.stsd.table[0].version = 1;
283 // trak->mdia.minf.stbl.stsd.table[0].revision = 1;
284 quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc;
285 if( !avcc->data_size )
286 encode(file, 0, track);
288 while( !encode(file, 0, track) );
293 static int reads_colormodel(quicktime_t *file,
297 return (colormodel == BC_YUV420P);
300 static int writes_colormodel(quicktime_t *file,
304 return (colormodel == BC_YUV420P);
307 static int set_parameter(quicktime_t *file,
312 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
313 char *compressor = quicktime_compressor(vtrack->track);
315 if(quicktime_match_32(compressor, QUICKTIME_H264) ||
316 quicktime_match_32(compressor, QUICKTIME_HV64))
318 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
319 if(!strcasecmp(key, "h264_bitrate"))
321 if(quicktime_match_32(compressor, QUICKTIME_H264))
322 codec->param.rc.i_bitrate = *(int*)value;
324 codec->param.rc.i_bitrate = *(int*)value / 2;
327 if(!strcasecmp(key, "h264_quantizer"))
329 codec->param.rc.i_qp_constant =
330 codec->param.rc.i_qp_min =
331 codec->param.rc.i_qp_max = *(int*)value;
334 if(!strcasecmp(key, "h264_fix_bitrate"))
336 codec->param.rc.i_qp_constant = (*(int*)value) / 1000;
342 static quicktime_h264_codec_t* init_common(quicktime_video_map_t *vtrack,
347 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
348 quicktime_h264_codec_t *codec;
350 codec_base->priv = calloc(1, sizeof(quicktime_h264_codec_t));
351 codec_base->delete_vcodec = delete_codec;
352 codec_base->decode_video = decode;
353 codec_base->encode_video = encode;
354 codec_base->flush = flush;
355 codec_base->reads_colormodel = reads_colormodel;
356 codec_base->writes_colormodel = writes_colormodel;
357 codec_base->set_parameter = set_parameter;
358 codec_base->fourcc = compressor;
359 codec_base->title = title;
360 codec_base->desc = description;
363 codec = (quicktime_h264_codec_t*)codec_base->priv;
364 x264_param_default(&codec->param);
365 codec->param.rc.i_rc_method = X264_RC_CQP;
366 // codec->param.i_log_level = 99;
371 void quicktime_init_codec_h264(quicktime_video_map_t *vtrack)
373 quicktime_h264_codec_t *result = init_common(vtrack,
377 result->total_fields = 1;
382 void quicktime_init_codec_hv64(quicktime_video_map_t *vtrack)
384 quicktime_h264_codec_t *result = init_common(vtrack,
387 "H.264 with two streams alternating every other frame. (Not standardized)");
388 result->total_fields = 2;