00001 #include "avcodec.h"
00002 #include "colormodels.h"
00003 #include "funcprotos.h"
00004 #include <pthread.h>
00005 #include "qtffmpeg.h"
00006 #include "quicktime.h"
00007 #include <string.h>
00008 #include "workarounds.h"
00009 #include "x264.h"
00010
00011
00012
00013 typedef struct
00014 {
00015
00016 x264_t *encoder[FIELDS];
00017 x264_picture_t *pic[FIELDS];
00018 x264_param_t param;
00019
00020 int encode_initialized[FIELDS];
00021
00022
00023 char *temp_frame;
00024
00025 unsigned char *work_buffer;
00026
00027 int buffer_size;
00028 int total_fields;
00029
00030 int header_only;
00031
00032
00033 quicktime_ffmpeg_t *decoder;
00034
00035 } quicktime_h264_codec_t;
00036
00037 static pthread_mutex_t h264_lock = PTHREAD_MUTEX_INITIALIZER;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 int quicktime_h264_is_key(unsigned char *data, long size, char *codec_id)
00052 {
00053
00054 }
00055
00056
00057
00058
00059 static int delete_codec(quicktime_video_map_t *vtrack)
00060 {
00061 quicktime_h264_codec_t *codec;
00062 int i;
00063
00064
00065 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00066 for(i = 0; i < codec->total_fields; i++)
00067 {
00068 if(codec->encode_initialized[i])
00069 {
00070 pthread_mutex_lock(&h264_lock);
00071
00072
00073 if(codec->pic[i])
00074 {
00075 x264_picture_clean(codec->pic[i]);
00076 free(codec->pic[i]);
00077 }
00078
00079 if(codec->encoder[i])
00080 {
00081 x264_encoder_close(codec->encoder[i]);
00082 }
00083
00084 pthread_mutex_unlock(&h264_lock);
00085 }
00086 }
00087
00088
00089
00090 if(codec->temp_frame) free(codec->temp_frame);
00091 if(codec->work_buffer) free(codec->work_buffer);
00092 if(codec->decoder) quicktime_delete_ffmpeg(codec->decoder);
00093
00094
00095 free(codec);
00096 return 0;
00097 }
00098
00099
00100
00101 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
00102 {
00103 int64_t offset = quicktime_position(file);
00104 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00105 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00106 quicktime_trak_t *trak = vtrack->track;
00107 int width = quicktime_video_width(file, track);
00108 int height = quicktime_video_height(file, track);
00109 int w_16 = quicktime_quantize16(width);
00110 int h_16 = quicktime_quantize16(height);
00111 int i;
00112 int result = 0;
00113 int bytes = 0;
00114 int is_keyframe = 0;
00115 int current_field = vtrack->current_position % codec->total_fields;
00116 quicktime_atom_t chunk_atom;
00117 unsigned char header[1024];
00118 int header_size = 0;
00119 int got_pps = 0;
00120 int got_sps = 0;
00121 quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc;
00122
00123
00124
00125
00126
00127
00128 pthread_mutex_lock(&h264_lock);
00129
00130 if(!codec->encode_initialized[current_field])
00131 {
00132 codec->encode_initialized[current_field] = 1;
00133 codec->param.i_width = w_16;
00134 codec->param.i_height = w_16;
00135 codec->param.i_fps_num = quicktime_frame_rate_n(file, track);
00136 codec->param.i_fps_den = quicktime_frame_rate_d(file, track);
00137
00138 x264_param_t default_params;
00139 x264_param_default(&default_params);
00140
00141 #if X264_BUILD < 48
00142 if(codec->param.rc.b_cbr)
00143 #else
00144 if(codec->param.rc.i_rc_method == X264_RC_ABR)
00145 #endif
00146 {
00147 codec->param.rc.i_qp_constant = default_params.rc.i_qp_constant;
00148 codec->param.rc.i_qp_min = default_params.rc.i_qp_min;
00149 codec->param.rc.i_qp_max = default_params.rc.i_qp_max;
00150 }
00151
00152
00153 if(file->cpus > 1)
00154 {
00155 codec->param.i_threads = file->cpus;
00156 }
00157
00158 codec->encoder[current_field] = x264_encoder_open(&codec->param);
00159 codec->pic[current_field] = calloc(1, sizeof(x264_picture_t));
00160 x264_picture_alloc(codec->pic[current_field],
00161 X264_CSP_I420,
00162 codec->param.i_width,
00163 codec->param.i_height);
00164 }
00165
00166
00167
00168
00169
00170
00171 codec->pic[current_field]->i_type = X264_TYPE_AUTO;
00172 codec->pic[current_field]->i_qpplus1 = 0;
00173
00174
00175 if(codec->header_only)
00176 {
00177 bzero(codec->pic[current_field]->img.plane[0], w_16 * h_16);
00178 bzero(codec->pic[current_field]->img.plane[1], w_16 * h_16 / 4);
00179 bzero(codec->pic[current_field]->img.plane[2], w_16 * h_16 / 4);
00180 }
00181 else
00182 if(file->color_model == BC_YUV420P)
00183 {
00184 memcpy(codec->pic[current_field]->img.plane[0], row_pointers[0], w_16 * h_16);
00185 memcpy(codec->pic[current_field]->img.plane[1], row_pointers[1], w_16 * h_16 / 4);
00186 memcpy(codec->pic[current_field]->img.plane[2], row_pointers[2], w_16 * h_16 / 4);
00187 }
00188 else
00189 {
00190 cmodel_transfer(0,
00191 row_pointers,
00192 codec->pic[current_field]->img.plane[0],
00193 codec->pic[current_field]->img.plane[1],
00194 codec->pic[current_field]->img.plane[2],
00195 row_pointers[0],
00196 row_pointers[1],
00197 row_pointers[2],
00198 0,
00199 0,
00200 width,
00201 height,
00202 0,
00203 0,
00204 width,
00205 height,
00206 file->color_model,
00207 BC_YUV420P,
00208 0,
00209 width,
00210 codec->pic[current_field]->img.i_stride[0]);
00211
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 x264_picture_t pic_out;
00226 x264_nal_t *nals;
00227 int nnal;
00228 x264_encoder_encode(codec->encoder[current_field],
00229 &nals,
00230 &nnal,
00231 codec->pic[current_field],
00232 &pic_out);
00233 int allocation = w_16 * h_16 * 3;
00234 if(!codec->work_buffer)
00235 {
00236 codec->work_buffer = calloc(1, allocation);
00237 }
00238
00239 codec->buffer_size = 0;
00240 for(i = 0; i < nnal; i++)
00241 {
00242 int size = x264_nal_encode(codec->work_buffer + codec->buffer_size,
00243 &allocation,
00244 1,
00245 nals + i);
00246 unsigned char *ptr = codec->work_buffer + codec->buffer_size;
00247
00248 if(size > 0)
00249 {
00250
00251 uint64_t avc_size = size - 4;
00252
00253
00254
00255 if(!avcc->data_size)
00256 {
00257 if(header_size < 6)
00258 {
00259 header[header_size++] = 0x01;
00260 header[header_size++] = 0x4d;
00261 header[header_size++] = 0x40;
00262 header[header_size++] = 0x1f;
00263 header[header_size++] = 0xff;
00264 header[header_size++] = 0xe1;
00265 }
00266
00267 int nal_type = (ptr[4] & 0x1f);
00268
00269 if(nal_type == 0x7 && !got_sps)
00270 {
00271 got_sps = 1;
00272 header[header_size++] = (avc_size & 0xff00) >> 8;
00273 header[header_size++] = (avc_size & 0xff);
00274 memcpy(&header[header_size],
00275 ptr + 4,
00276 avc_size);
00277 header_size += avc_size;
00278 }
00279 else
00280 if(nal_type == 0x8 && !got_pps)
00281 {
00282 got_pps = 1;
00283
00284 header[header_size++] = 0x1;
00285 header[header_size++] = (avc_size & 0xff00) >> 8;
00286 header[header_size++] = (avc_size & 0xff);
00287 memcpy(&header[header_size],
00288 ptr + 4,
00289 avc_size);
00290 header_size += avc_size;
00291 }
00292
00293
00294 if(got_sps && got_pps)
00295 {
00296 quicktime_set_avcc_header(avcc,
00297 header,
00298 header_size);
00299 }
00300 }
00301
00302
00303
00304 *ptr++ = (avc_size & 0xff000000) >> 24;
00305 *ptr++ = (avc_size & 0xff0000) >> 16;
00306 *ptr++ = (avc_size & 0xff00) >> 8;
00307 *ptr++ = (avc_size & 0xff);
00308 codec->buffer_size += size;
00309 }
00310 else
00311 break;
00312 }
00313
00314 pthread_mutex_unlock(&h264_lock);
00315
00316
00317
00318 if(!codec->header_only)
00319 {
00320 if(pic_out.i_type == X264_TYPE_IDR ||
00321 pic_out.i_type == X264_TYPE_I)
00322 {
00323 is_keyframe = 1;
00324 }
00325
00326 if(codec->buffer_size)
00327 {
00328 quicktime_write_chunk_header(file, trak, &chunk_atom);
00329 result = !quicktime_write_data(file,
00330 codec->work_buffer,
00331 codec->buffer_size);
00332 quicktime_write_chunk_footer(file,
00333 trak,
00334 vtrack->current_chunk,
00335 &chunk_atom,
00336 1);
00337 }
00338
00339 if(is_keyframe)
00340 {
00341 quicktime_insert_keyframe(file,
00342 vtrack->current_position,
00343 track);
00344 }
00345 vtrack->current_chunk++;
00346 }
00347 return result;
00348 }
00349
00350
00351
00352
00353 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
00354 {
00355 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00356 quicktime_trak_t *trak = vtrack->track;
00357 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00358 quicktime_stsd_table_t *stsd_table = &trak->mdia.minf.stbl.stsd.table[0];
00359 int width = trak->tkhd.track_width;
00360 int height = trak->tkhd.track_height;
00361 int w_16 = quicktime_quantize16(width);
00362 int h_16 = quicktime_quantize16(height);
00363
00364
00365 if(!codec->decoder) codec->decoder = quicktime_new_ffmpeg(
00366 file->cpus,
00367 codec->total_fields,
00368 CODEC_ID_H264,
00369 width,
00370 height,
00371 stsd_table);
00372
00373
00374 if(codec->decoder) return quicktime_ffmpeg_decode(codec->decoder,
00375 file,
00376 row_pointers,
00377 track);
00378
00379 return 1;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 static void flush(quicktime_t *file, int track)
00407 {
00408 quicktime_video_map_t *track_map = &(file->vtracks[track]);
00409 quicktime_trak_t *trak = track_map->track;
00410 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00411 quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc;
00412
00413 if(!avcc->data_size)
00414 {
00415 codec->header_only = 1;
00416 encode(file, 0, track);
00417
00418
00419
00420
00421
00422
00423
00424
00425 }
00426
00427
00428
00429
00430 }
00431
00432
00433
00434 static int reads_colormodel(quicktime_t *file,
00435 int colormodel,
00436 int track)
00437 {
00438 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00439 quicktime_codec_t *codec = (quicktime_codec_t*)vtrack->codec;
00440 return (colormodel == BC_YUV420P);
00441 }
00442
00443 static int writes_colormodel(quicktime_t *file,
00444 int colormodel,
00445 int track)
00446 {
00447 return (colormodel == BC_YUV420P);
00448 }
00449
00450 static int set_parameter(quicktime_t *file,
00451 int track,
00452 char *key,
00453 void *value)
00454 {
00455 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00456 char *compressor = quicktime_compressor(vtrack->track);
00457
00458 if(quicktime_match_32(compressor, QUICKTIME_H264) ||
00459 quicktime_match_32(compressor, QUICKTIME_HV64))
00460 {
00461 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00462 if(!strcasecmp(key, "h264_bitrate"))
00463 {
00464 if(quicktime_match_32(compressor, QUICKTIME_H264))
00465 codec->param.rc.i_bitrate = *(int*)value;
00466 else
00467 codec->param.rc.i_bitrate = *(int*)value / 2;
00468 }
00469 else
00470 if(!strcasecmp(key, "h264_quantizer"))
00471 {
00472 codec->param.rc.i_qp_constant =
00473 codec->param.rc.i_qp_min =
00474 codec->param.rc.i_qp_max = *(int*)value;
00475 }
00476 else
00477 if(!strcasecmp(key, "h264_fix_bitrate"))
00478 #if X264_BUILD < 48
00479 codec->param.rc.b_cbr = (*(int*)value) / 1000;
00480 #else
00481 codec->param.rc.i_bitrate = (*(int*)value) / 1000;
00482 #endif
00483 }
00484 }
00485
00486 static quicktime_h264_codec_t* init_common(quicktime_video_map_t *vtrack,
00487 char *compressor,
00488 char *title,
00489 char *description)
00490 {
00491 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
00492 quicktime_h264_codec_t *codec;
00493
00494 codec_base->priv = calloc(1, sizeof(quicktime_h264_codec_t));
00495 codec_base->delete_vcodec = delete_codec;
00496 codec_base->decode_video = decode;
00497 codec_base->encode_video = encode;
00498 codec_base->flush = flush;
00499 codec_base->reads_colormodel = reads_colormodel;
00500 codec_base->writes_colormodel = writes_colormodel;
00501 codec_base->set_parameter = set_parameter;
00502 codec_base->fourcc = compressor;
00503 codec_base->title = title;
00504 codec_base->desc = description;
00505
00506
00507 codec = (quicktime_h264_codec_t*)codec_base->priv;
00508 x264_param_default(&codec->param);
00509
00510
00511 return codec;
00512 }
00513
00514
00515 void quicktime_init_codec_h264(quicktime_video_map_t *vtrack)
00516 {
00517 quicktime_h264_codec_t *result = init_common(vtrack,
00518 QUICKTIME_H264,
00519 "H.264",
00520 "H.264");
00521 result->total_fields = 1;
00522 }
00523
00524
00525
00526 void quicktime_init_codec_hv64(quicktime_video_map_t *vtrack)
00527 {
00528 quicktime_h264_codec_t *result = init_common(vtrack,
00529 QUICKTIME_HV64,
00530 "Dual H.264",
00531 "H.264 with two streams alternating every other frame. (Not standardized)");
00532 result->total_fields = 2;
00533 }
00534