00001
00002
00003
00004 #include "colormodels.h"
00005 #include "funcprotos.h"
00006 #include "quicktime.h"
00007 #include "workarounds.h"
00008 #include "encore50/encore.h"
00009 #include "decore50/decore.h"
00010
00011 #include <pthread.h>
00012 #include <stdint.h>
00013 #include <stdlib.h>
00014
00015
00016 typedef struct
00017 {
00018 #define FIELDS 2
00019 unsigned char *work_buffer;
00020 char *temp_frame;
00021 long buffer_size;
00022 int decode_initialized[FIELDS];
00023 int encode_initialized[FIELDS];
00024
00025 int total_fields;
00026 int bitrate;
00027 long rc_period;
00028 long rc_reaction_period;
00029 long rc_reaction_ratio;
00030 long max_key_interval;
00031 int max_quantizer;
00032 int min_quantizer;
00033 int quantizer;
00034 int quality;
00035 int fix_bitrate;
00036 int use_deblocking;
00037
00038
00039 long last_frame[FIELDS];
00040 int encode_handle[FIELDS];
00041
00042 DEC_PARAM dec_param[FIELDS];
00043 ENC_PARAM enc_param[FIELDS];
00044
00045 int decode_handle[FIELDS];
00046
00047 int p_count[FIELDS];
00048 } quicktime_divx_codec_t;
00049
00050 static pthread_mutex_t encode_mutex;
00051 static pthread_mutex_t decode_mutex;
00052 static int mutex_initialized = 0;
00053 static int decode_handle = 1;
00054 static int encode_handle = 0;
00055
00056 static int delete_codec(quicktime_video_map_t *vtrack)
00057 {
00058 quicktime_divx_codec_t *codec;
00059 int i;
00060
00061
00062
00063 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00064 for(i = 0; i < codec->total_fields; i++)
00065 {
00066 if(codec->encode_initialized[i])
00067 {
00068 pthread_mutex_lock(&encode_mutex);
00069 encore(codec->encode_handle[i],
00070 ENC_OPT_RELEASE,
00071 0,
00072 0);
00073 pthread_mutex_unlock(&encode_mutex);
00074 }
00075
00076 if(codec->decode_initialized[i])
00077 {
00078 pthread_mutex_lock(&decode_mutex);
00079
00080 decore_set_global(&codec->dec_param[i]);
00081 decore(codec->decode_handle[i],
00082 DEC_OPT_RELEASE,
00083 0,
00084 0);
00085
00086 free(codec->dec_param[i].buffers.mp4_edged_ref_buffers);
00087 free(codec->dec_param[i].buffers.mp4_edged_for_buffers);
00088 free(codec->dec_param[i].buffers.mp4_display_buffers);
00089 free(codec->dec_param[i].buffers.mp4_state);
00090 free(codec->dec_param[i].buffers.mp4_tables);
00091 free(codec->dec_param[i].buffers.mp4_stream);
00092
00093 pthread_mutex_unlock(&decode_mutex);
00094 }
00095 }
00096 pthread_mutex_unlock(&decode_mutex);
00097
00098
00099 if(codec->temp_frame) free(codec->temp_frame);
00100 if(codec->work_buffer) free(codec->work_buffer);
00101
00102
00103 free(codec);
00104
00105 return 0;
00106 }
00107
00108 static int reads_colormodel(quicktime_t *file,
00109 int colormodel,
00110 int track)
00111 {
00112 return (colormodel == BC_YUV420P);
00113 }
00114
00115 static int writes_colormodel(quicktime_t *file,
00116 int colormodel,
00117 int track)
00118 {
00119 return (colormodel == BC_RGB888 ||
00120 colormodel == BC_RGBA8888 ||
00121 colormodel == BC_RGB161616 ||
00122 colormodel == BC_RGBA16161616 ||
00123 colormodel == BC_YUV888 ||
00124 colormodel == BC_YUVA8888 ||
00125 colormodel == BC_YUV161616 ||
00126 colormodel == BC_YUVA16161616 ||
00127 colormodel == BC_YUV420P ||
00128 colormodel == BC_YUV422 ||
00129 colormodel == BC_COMPRESSED);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 static void init_mutex()
00140 {
00141 if(!mutex_initialized)
00142 {
00143 pthread_mutexattr_t attr;
00144 mutex_initialized = 1;
00145 pthread_mutexattr_init(&attr);
00146 pthread_mutex_init(&decode_mutex, &attr);
00147 pthread_mutex_init(&encode_mutex, &attr);
00148 }
00149 }
00150
00151
00152
00153
00154
00155 int quicktime_divx_is_key(unsigned char *data, long size)
00156 {
00157 int result = 0;
00158 int i;
00159
00160 for(i = 0; i < size - 5; i++)
00161 {
00162 if( data[i] == 0x00 &&
00163 data[i + 1] == 0x00 &&
00164 data[i + 2] == 0x01 &&
00165 data[i + 3] == 0xb6)
00166 {
00167 if((data[i + 4] & 0xc0) == 0x0)
00168 return 1;
00169 else
00170 return 0;
00171 }
00172 }
00173
00174 return result;
00175 }
00176
00177
00178
00179 int quicktime_divx_has_vol(unsigned char *data)
00180 {
00181 if( data[0] == 0x00 &&
00182 data[1] == 0x00 &&
00183 data[2] == 0x01 &&
00184 data[3] == 0x00 &&
00185 data[4] == 0x00 &&
00186 data[5] == 0x00 &&
00187 data[6] == 0x01 &&
00188 data[7] == 0x20)
00189 return 1;
00190 else
00191 return 0;
00192 }
00193
00194
00195
00196
00197 static void putbits(unsigned char **data,
00198 int *bit_pos,
00199 uint64_t *bit_store,
00200 int *total,
00201 int count,
00202 uint64_t value)
00203 {
00204 value &= 0xffffffffffffffff >> (64 - count);
00205
00206 while(64 - *bit_pos < count)
00207 {
00208 *(*data)++ = (*bit_store) >> 56;
00209 (*bit_store) <<= 8;
00210 (*bit_pos) -= 8;
00211 }
00212
00213 (*bit_store) |= value << (64 - count - *bit_pos);
00214 (*bit_pos) += count;
00215 (*total) += count;
00216 }
00217
00218
00219 static void flushbits(unsigned char **data,
00220 int *bit_pos,
00221 uint64_t *bit_store)
00222 {
00223
00224 while((*bit_pos) > 0)
00225 {
00226 *(*data)++ = (*bit_store) >> 56;
00227 (*bit_store) <<= 8;
00228 (*bit_pos) -= 8;
00229 }
00230 }
00231
00232
00233
00234
00235 #define VO_START_CODE 0x8
00236 #define VO_START_CODE_LENGTH 27
00237 #define VOL_START_CODE 0x12
00238 #define VOL_START_CODE_LENGTH 28
00239
00240
00241
00242 int quicktime_divx_write_vol(unsigned char *data_start,
00243 int vol_width,
00244 int vol_height,
00245 int time_increment_resolution,
00246 double frame_rate)
00247 {
00248 int written = 0;
00249 int bits, fixed_vop_time_increment;
00250 unsigned char *data = data_start;
00251 int bit_pos;
00252 uint64_t bit_store;
00253 int i, j;
00254
00255 bit_store = 0;
00256 bit_pos = 0;
00257 vol_width = (int)((float)vol_width / 16 + 0.5) * 16;
00258 vol_height = (int)((float)vol_height / 16 + 0.5) * 16;
00259
00260
00261 putbits(&data,
00262 &bit_pos,
00263 &bit_store,
00264 &written,
00265 VO_START_CODE_LENGTH, VO_START_CODE);
00266 putbits(&data,
00267 &bit_pos,
00268 &bit_store,
00269 &written,
00270 5, 0);
00271
00272 putbits(&data,
00273 &bit_pos,
00274 &bit_store,
00275 &written,
00276 VOL_START_CODE_LENGTH, VOL_START_CODE);
00277
00278
00279
00280
00281 putbits(&data,
00282 &bit_pos,
00283 &bit_store,
00284 &written,
00285 4, 0);
00286
00287 putbits(&data,
00288 &bit_pos,
00289 &bit_store,
00290 &written,
00291 1, 0);
00292 putbits(&data,
00293 &bit_pos,
00294 &bit_store,
00295 &written,
00296 8, 1);
00297 putbits(&data,
00298 &bit_pos,
00299 &bit_store,
00300 &written,
00301 1, 1);
00302 putbits(&data,
00303 &bit_pos,
00304 &bit_store,
00305 &written,
00306 4, 2);
00307 putbits(&data,
00308 &bit_pos,
00309 &bit_store,
00310 &written,
00311 3, 1);
00312 putbits(&data,
00313 &bit_pos,
00314 &bit_store,
00315 &written,
00316 4, 1);
00317
00318
00319
00320
00321
00322
00323
00324 putbits(&data,
00325 &bit_pos,
00326 &bit_store,
00327 &written,
00328 1, 0);
00329 putbits(&data,
00330 &bit_pos,
00331 &bit_store,
00332 &written,
00333 2, 0);
00334 putbits(&data,
00335 &bit_pos,
00336 &bit_store,
00337 &written,
00338 1, 1);
00339
00340
00341
00342
00343
00344
00345
00346 putbits(&data,
00347 &bit_pos,
00348 &bit_store,
00349 &written,
00350 16, time_increment_resolution);
00351 putbits(&data,
00352 &bit_pos,
00353 &bit_store,
00354 &written,
00355 1, 1);
00356 putbits(&data,
00357 &bit_pos,
00358 &bit_store,
00359 &written,
00360 1, 1);
00361
00362
00363 bits = 1;
00364 while((1 << bits) < time_increment_resolution) bits++;
00365
00366
00367
00368
00369
00370 fixed_vop_time_increment =
00371 (int)(time_increment_resolution / frame_rate + 0.1);
00372
00373 putbits(&data,
00374 &bit_pos,
00375 &bit_store,
00376 &written,
00377 bits, fixed_vop_time_increment);
00378
00379 putbits(&data,
00380 &bit_pos,
00381 &bit_store,
00382 &written,
00383 1, 1);
00384
00385 putbits(&data,
00386 &bit_pos,
00387 &bit_store,
00388 &written,
00389 13, vol_width);
00390 putbits(&data,
00391 &bit_pos,
00392 &bit_store,
00393 &written,
00394 1, 1);
00395 putbits(&data,
00396 &bit_pos,
00397 &bit_store,
00398 &written,
00399 13, vol_height);
00400 putbits(&data,
00401 &bit_pos,
00402 &bit_store,
00403 &written,
00404 1, 1);
00405
00406 putbits(&data,
00407 &bit_pos,
00408 &bit_store,
00409 &written,
00410 1, 0);
00411 putbits(&data,
00412 &bit_pos,
00413 &bit_store,
00414 &written,
00415 1, 1);
00416 putbits(&data,
00417 &bit_pos,
00418 &bit_store,
00419 &written,
00420 2, 0);
00421 putbits(&data,
00422 &bit_pos,
00423 &bit_store,
00424 &written,
00425 1, 0);
00426
00427 putbits(&data,
00428 &bit_pos,
00429 &bit_store,
00430 &written,
00431 1, 0);
00432 putbits(&data,
00433 &bit_pos,
00434 &bit_store,
00435 &written,
00436 1, 0);
00437 putbits(&data,
00438 &bit_pos,
00439 &bit_store,
00440 &written,
00441 1, 1);
00442 putbits(&data,
00443 &bit_pos,
00444 &bit_store,
00445 &written,
00446 1, 1);
00447 putbits(&data,
00448 &bit_pos,
00449 &bit_store,
00450 &written,
00451 1, 0);
00452 putbits(&data,
00453 &bit_pos,
00454 &bit_store,
00455 &written,
00456 1, 0);
00457
00458 flushbits(&data,
00459 &bit_pos,
00460 &bit_store);
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 return data - data_start;
00474 }
00475
00476
00477
00478
00479
00480 #define READ_RAW(framenum) \
00481 { \
00482 quicktime_set_video_position(file, framenum, track); \
00483 bytes = quicktime_frame_size(file, framenum, track); \
00484 if(!codec->work_buffer || codec->buffer_size < bytes) \
00485 { \
00486 if(codec->work_buffer) free(codec->work_buffer); \
00487 codec->buffer_size = bytes; \
00488 codec->work_buffer = calloc(1, codec->buffer_size + 100); \
00489 } \
00490 result = !quicktime_read_data(file, codec->work_buffer, bytes); \
00491 }
00492
00493
00494
00495
00496
00497 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
00498 {
00499 int i;
00500 longest bytes;
00501 int result = 0;
00502 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00503 quicktime_trak_t *trak = vtrack->track;
00504 quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00505 int width = trak->tkhd.track_width;
00506 int height = trak->tkhd.track_height;
00507 int width_i = (int)((float)width / 16 + 0.5) * 16;
00508 int height_i = (int)((float)height / 16 + 0.5) * 16;
00509 DEC_FRAME dec_frame;
00510 int use_temp = 0;
00511 int input_cmodel;
00512 char *bmp_pointers[3];
00513 long temp_position;
00514 int current_field = vtrack->current_position % codec->total_fields;
00515
00516
00517
00518 init_mutex();
00519 pthread_mutex_lock(&decode_mutex);
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 if(!codec->decode_initialized[current_field])
00538 {
00539 DEC_MEM_REQS dec_mem_reqs;
00540
00541
00542 if(!codec->temp_frame)
00543 codec->temp_frame = malloc(width_i * height_i * 3 / 2);
00544
00545
00546 codec->decode_handle[current_field] = decode_handle++;
00547 codec->last_frame[current_field] = -1;
00548 codec->dec_param[current_field].x_dim = width_i;
00549 codec->dec_param[current_field].y_dim = height_i;
00550 codec->dec_param[current_field].output_format = DEC_420;
00551 codec->dec_param[current_field].time_incr = 0;
00552
00553 decore(codec->decode_handle[current_field],
00554 DEC_OPT_MEMORY_REQS,
00555 &codec->dec_param[current_field],
00556 &dec_mem_reqs);
00557 codec->dec_param[current_field].buffers.mp4_edged_ref_buffers =
00558 calloc(1, dec_mem_reqs.mp4_edged_ref_buffers_size);
00559 codec->dec_param[current_field].buffers.mp4_edged_for_buffers =
00560 calloc(1, dec_mem_reqs.mp4_edged_for_buffers_size);
00561 codec->dec_param[current_field].buffers.mp4_display_buffers =
00562 calloc(1, dec_mem_reqs.mp4_display_buffers_size);
00563 codec->dec_param[current_field].buffers.mp4_state =
00564 calloc(1, dec_mem_reqs.mp4_state_size);
00565 codec->dec_param[current_field].buffers.mp4_tables =
00566 calloc(1, dec_mem_reqs.mp4_tables_size);
00567 codec->dec_param[current_field].buffers.mp4_stream =
00568 calloc(1, dec_mem_reqs.mp4_stream_size);
00569
00570 decore(codec->decode_handle[current_field],
00571 DEC_OPT_INIT,
00572 &codec->dec_param[current_field],
00573 NULL);
00574
00575
00576
00577
00578
00579
00580
00581 temp_position = vtrack->current_position;
00582 READ_RAW(current_field);
00583 vtrack->current_position = temp_position;
00584 dec_frame.bitstream = codec->work_buffer;
00585 dec_frame.length = bytes;
00586 dec_frame.stride = width_i;
00587 dec_frame.render_flag = 0;
00588 dec_frame.bmp[0] = codec->temp_frame;
00589 dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
00590 dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
00591 decore(codec->decode_handle[current_field], 0, &dec_frame, NULL);
00592
00593
00594
00595
00596 codec->decode_initialized[current_field] = 1;
00597 decore_save_global(&codec->dec_param[current_field]);
00598 }
00599
00600
00601 decore_set_global(&codec->dec_param[current_field]);
00602
00603
00604 DEC_SET dec_set_arg;
00605 dec_set_arg.postproc_level = (codec->use_deblocking ? 100 : 0);
00606 decore(codec->decode_handle[current_field],
00607 DEC_OPT_SETPP,
00608 &dec_set_arg,
00609 NULL);
00610
00611
00612
00613
00614 input_cmodel = BC_YUV420P;
00615
00616
00617 if(file->color_model == input_cmodel &&
00618 file->out_w == width_i &&
00619 file->out_h == height_i &&
00620 file->in_x == 0 &&
00621 file->in_y == 0 &&
00622 file->in_w == width_i &&
00623 file->in_h == height_i)
00624 {
00625
00626 dec_frame.bmp[0] = row_pointers[0];
00627 dec_frame.bmp[1] = row_pointers[1];
00628 dec_frame.bmp[2] = row_pointers[2];
00629 use_temp = 0;
00630 }
00631 else
00632
00633 {
00634 dec_frame.bmp[0] = codec->temp_frame;
00635 dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
00636 dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
00637 use_temp = 1;
00638 }
00639
00640
00641 dec_frame.stride = width_i;
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 if(quicktime_has_keyframes(file, track) &&
00657 vtrack->current_position !=
00658 codec->last_frame[current_field] + codec->total_fields)
00659 {
00660 int frame1, frame2 = vtrack->current_position, current_frame = frame2;
00661
00662
00663 do
00664 {
00665 frame1 = quicktime_get_keyframe_before(file,
00666 current_frame--,
00667 track);
00668 }while(frame1 > 0 && (frame1 % codec->total_fields) != current_field);
00669
00670
00671
00672
00673
00674 if(frame1 < codec->last_frame[current_field] &&
00675 frame2 > codec->last_frame[current_field])
00676 frame1 = codec->last_frame[current_field] + codec->total_fields;
00677
00678
00679 while(frame1 < frame2)
00680 {
00681 READ_RAW(frame1);
00682
00683 dec_frame.bitstream = codec->work_buffer;
00684 dec_frame.length = bytes;
00685 dec_frame.render_flag = 0;
00686 decore(codec->decode_handle[current_field],
00687 0,
00688 &dec_frame,
00689 NULL);
00690 frame1 += codec->total_fields;
00691 }
00692
00693
00694 vtrack->current_position = frame2;
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 codec->last_frame[current_field] = vtrack->current_position;
00712
00713
00714
00715 READ_RAW(vtrack->current_position);
00716
00717
00718
00719
00720
00721
00722 dec_frame.bitstream = codec->work_buffer;
00723 dec_frame.length = bytes;
00724 dec_frame.render_flag = 1;
00725
00726
00727 decore(codec->decode_handle[current_field], 0, &dec_frame, NULL);
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 if(use_temp)
00777 {
00778 unsigned char **input_rows = malloc(sizeof(unsigned char*) * height_i);
00779 for(i = 0; i < height_i; i++)
00780 input_rows[i] = codec->temp_frame + width_i * 3;
00781
00782
00783 cmodel_transfer(row_pointers,
00784 input_rows,
00785 row_pointers[0],
00786 row_pointers[1],
00787 row_pointers[2],
00788 codec->temp_frame,
00789 codec->temp_frame + width_i * height_i,
00790 codec->temp_frame + width_i * height_i + width_i * height_i / 4,
00791 file->in_x,
00792 file->in_y,
00793 file->in_w,
00794 file->in_h,
00795 0,
00796 0,
00797 file->out_w,
00798 file->out_h,
00799 input_cmodel,
00800 file->color_model,
00801 0,
00802 width_i,
00803 width);
00804
00805 free(input_rows);
00806 }
00807
00808
00809 decore_save_global(&codec->dec_param[current_field]);
00810 pthread_mutex_unlock(&decode_mutex);
00811
00812
00813
00814
00815 return result;
00816 }
00817
00818
00819
00820 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
00821 {
00822 longest offset = quicktime_position(file);
00823 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00824 quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00825 quicktime_trak_t *trak = vtrack->track;
00826 int width = trak->tkhd.track_width;
00827 int height = trak->tkhd.track_height;
00828 int width_i = (int)((float)width / 16 + 0.5) * 16;
00829 int height_i = (int)((float)height / 16 + 0.5) * 16;
00830 int result = 0;
00831 int i;
00832 ENC_FRAME encore_input;
00833 ENC_RESULT encore_result;
00834 int current_field = vtrack->current_position % codec->total_fields;
00835
00836 init_mutex();
00837 pthread_mutex_lock(&encode_mutex);
00838
00839 if(!codec->encode_initialized[current_field])
00840 {
00841 codec->encode_initialized[current_field] = 1;
00842 codec->encode_handle[current_field] = encode_handle++;
00843 codec->enc_param[current_field].x_dim = width_i;
00844 codec->enc_param[current_field].y_dim = height_i;
00845 codec->enc_param[current_field].framerate =
00846 quicktime_frame_rate(file, track) / codec->total_fields;
00847 codec->enc_param[current_field].bitrate =
00848 codec->bitrate / codec->total_fields;
00849 codec->enc_param[current_field].rc_period = codec->rc_period;
00850 codec->enc_param[current_field].rc_reaction_period = codec->rc_reaction_period;
00851 codec->enc_param[current_field].rc_reaction_ratio = codec->rc_reaction_ratio;
00852 codec->enc_param[current_field].max_quantizer = codec->max_quantizer;
00853 codec->enc_param[current_field].min_quantizer = codec->min_quantizer;
00854 codec->enc_param[current_field].max_key_interval = codec->max_key_interval;
00855
00856 codec->enc_param[current_field].search_range = codec->quality * 3;
00857 if(codec->enc_param[current_field].search_range > 15)
00858 codec->enc_param[current_field].search_range = 15;
00859
00860 encore(codec->encode_handle[current_field],
00861 ENC_OPT_INIT,
00862 &codec->enc_param[current_field], NULL);
00863 }
00864
00865
00866
00867
00868 if(file->color_model == BC_YUV420P &&
00869 width == width_i &&
00870 height == height_i)
00871 {
00872 encore_input.image = row_pointers[0];
00873 }
00874
00875
00876 else
00877 {
00878 if(!codec->temp_frame)
00879 {
00880 codec->temp_frame = malloc(width_i * height_i * 3 / 2);
00881 }
00882
00883 cmodel_transfer(0,
00884 row_pointers,
00885 codec->temp_frame,
00886 codec->temp_frame + width_i * height_i,
00887 codec->temp_frame + width_i * height_i + width_i * height_i / 4,
00888 row_pointers[0],
00889 row_pointers[1],
00890 row_pointers[2],
00891 0,
00892 0,
00893 width,
00894 height,
00895 0,
00896 0,
00897 width,
00898 height,
00899 file->color_model,
00900 BC_YUV420P,
00901 0,
00902 width,
00903 width_i);
00904
00905
00906 encore_input.image = codec->temp_frame;
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 if(!codec->work_buffer)
00930 {
00931 codec->buffer_size = width * height;
00932 codec->work_buffer = malloc(codec->buffer_size);
00933 }
00934
00935
00936 bzero(codec->work_buffer, codec->buffer_size);
00937 encore_input.bitstream = codec->work_buffer;
00938 encore_input.length = 0;
00939 encore_input.quant = !codec->fix_bitrate ? codec->quantizer : 0;
00940
00941 if(codec->p_count == 0)
00942 {
00943 codec->p_count[current_field]++;
00944 }
00945 else
00946 {
00947 codec->p_count[current_field]++;
00948 if(codec->p_count[current_field] >= codec->max_key_interval)
00949 codec->p_count[current_field] = 0;
00950 }
00951
00952 encore(codec->encode_handle[current_field],
00953 0,
00954 &encore_input,
00955 &encore_result);
00956 pthread_mutex_unlock(&encode_mutex);
00957
00958 result = !quicktime_write_data(file,
00959 codec->work_buffer,
00960 encore_input.length);
00961 quicktime_update_tables(file,
00962 trak,
00963 offset,
00964 vtrack->current_chunk,
00965 vtrack->current_position,
00966 1,
00967 encore_input.length);
00968
00969 if(encore_result.isKeyFrame)
00970 quicktime_insert_keyframe(file, file->vtracks[track].current_position, track);
00971
00972 file->vtracks[track].current_chunk++;
00973
00974
00975 return result;
00976 }
00977
00978 static int set_parameter(quicktime_t *file,
00979 int track,
00980 char *key,
00981 void *value)
00982 {
00983 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
00984 quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
00985
00986 if(!strcasecmp(key, "divx_bitrate"))
00987 codec->bitrate = *(int*)value;
00988 else
00989 if(!strcasecmp(key, "divx_rc_period"))
00990 codec->rc_period = *(int*)value;
00991 else
00992 if(!strcasecmp(key, "divx_rc_reaction_ratio"))
00993 codec->rc_reaction_ratio = *(int*)value;
00994 else
00995 if(!strcasecmp(key, "divx_rc_reaction_period"))
00996 codec->rc_reaction_period = *(int*)value;
00997 else
00998 if(!strcasecmp(key, "divx_max_key_interval"))
00999 codec->max_key_interval = *(int*)value;
01000 else
01001 if(!strcasecmp(key, "divx_max_quantizer"))
01002 codec->max_quantizer = *(int*)value;
01003 else
01004 if(!strcasecmp(key, "divx_min_quantizer"))
01005 codec->min_quantizer = *(int*)value;
01006 else
01007 if(!strcasecmp(key, "divx_quantizer"))
01008 codec->quantizer = *(int*)value;
01009 else
01010 if(!strcasecmp(key, "divx_quality"))
01011 codec->quality = *(int*)value;
01012 else
01013 if(!strcasecmp(key, "divx_fix_bitrate"))
01014 codec->fix_bitrate = *(int*)value;
01015 else
01016 if(!strcasecmp(key, "divx_use_deblocking"))
01017 codec->use_deblocking = *(int*)value;
01018 return 0;
01019 }
01020
01021
01022 void quicktime_init_codec_divx(quicktime_video_map_t *vtrack)
01023 {
01024 quicktime_divx_codec_t *codec;
01025
01026
01027 ((quicktime_codec_t*)vtrack->codec)->priv = calloc(1, sizeof(quicktime_divx_codec_t));
01028 ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = delete_codec;
01029 ((quicktime_codec_t*)vtrack->codec)->decode_video = decode;
01030 ((quicktime_codec_t*)vtrack->codec)->encode_video = encode;
01031 ((quicktime_codec_t*)vtrack->codec)->reads_colormodel = reads_colormodel;
01032 ((quicktime_codec_t*)vtrack->codec)->writes_colormodel = writes_colormodel;
01033 ((quicktime_codec_t*)vtrack->codec)->set_parameter = set_parameter;
01034
01035 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
01036
01037 codec->bitrate = 1000000;
01038 codec->rc_period = 50;
01039 codec->rc_reaction_ratio = 45;
01040 codec->rc_reaction_period = 10;
01041 codec->max_key_interval = 45;
01042 codec->max_quantizer = 31;
01043 codec->min_quantizer = 1;
01044 codec->quantizer = 10;
01045 codec->quality = 5;
01046 codec->fix_bitrate = 1;
01047 codec->total_fields = 1;
01048 }
01049
01050 void quicktime_init_codec_hv60(quicktime_video_map_t *vtrack)
01051 {
01052 quicktime_init_codec_divx(vtrack);
01053 quicktime_divx_codec_t *codec;
01054
01055 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
01056
01057 codec->total_fields = 2;
01058 }
01059