r105: This commit was manufactured by cvs2svn to create tag
[cinelerra_cv/mob.git] / hvirtual / quicktime / divx.c.encore50
blob1ebf576252e989b7282407a12f664eef8cdce4cc
1 // Divx for encore50
4 #include "colormodels.h"
5 #include "funcprotos.h"
6 #include "quicktime.h"
7 #include "workarounds.h"
8 #include ENCORE_INCLUDE
9 #include DECORE_INCLUDE
11 #include <pthread.h>
12 #include <stdint.h>
13 #include <stdlib.h>
16 typedef struct
18         unsigned char *work_buffer;
19         char *temp_frame;
20         long buffer_size;
21         int decode_initialized;
22         int encode_initialized;
23         int bitrate;
24         long rc_period; // the intended rate control averaging period
25         long rc_reaction_period; // the reation period for rate control
26         long rc_reaction_ratio; // the ratio for down/up rate control
27         long max_key_interval; // the maximum interval between key frames
28         int max_quantizer; // the upper limit of the quantizer
29         int min_quantizer; // the lower limit of the quantizer
30         int quantizer;    // For vbr
31         int quality; // the forward search range for motion estimation
32         int fix_bitrate;
33 // Last frame decoded
34         long last_frame;  
35         int encode_handle;
37         DEC_PARAM dec_param;
38         ENC_PARAM enc_param;
40         int decode_handle;
41 // Must count pframes in VBR
42         int p_count;
43 } quicktime_divx_codec_t;
45 static pthread_mutex_t encode_mutex;
46 static pthread_mutex_t decode_mutex;
47 static int mutex_initialized = 0;
48 static int decode_handle = 1;
49 static int encode_handle = 0;
51 static int delete_codec(quicktime_video_map_t *vtrack)
53         quicktime_divx_codec_t *codec;
55         codec = ((quicktime_codec_t*)vtrack->codec)->priv;
56         if(codec->encode_initialized)
57         {
58                 pthread_mutex_lock(&encode_mutex);
59                 encore(codec->encode_handle,
60                         ENC_OPT_RELEASE,
61                         0,
62                         0);
63                 pthread_mutex_unlock(&encode_mutex);
64         }
65         if(codec->decode_initialized)
66         {
67                 pthread_mutex_lock(&decode_mutex);
74  *              decore(codec->handle,
75  *                      DEC_OPT_DESTROY,
76  *                      0,
77  *                      0);
78  */
82                 decore(codec->decode_handle,
83                         DEC_OPT_RELEASE,
84                         0,
85                         0);
89                 pthread_mutex_unlock(&decode_mutex);
90         }
91         if(codec->temp_frame) free(codec->temp_frame);
92         if(codec->work_buffer) free(codec->work_buffer);
93         free(codec);
94         return 0;
97 static int reads_colormodel(quicktime_t *file, 
98                 int colormodel, 
99                 int track)
101         return (colormodel == BC_YUV420P);
104 static int writes_colormodel(quicktime_t *file, 
105                 int colormodel, 
106                 int track)
108         return (colormodel == BC_RGB888 ||
109                 colormodel == BC_RGBA8888 ||
110                 colormodel == BC_RGB161616 ||
111                 colormodel == BC_RGBA16161616 ||
112                 colormodel == BC_YUV888 ||
113                 colormodel == BC_YUVA8888 ||
114                 colormodel == BC_YUV161616 ||
115                 colormodel == BC_YUVA16161616 ||
116                 colormodel == BC_YUV420P ||
117                 colormodel == BC_YUV422 ||
118                 colormodel == BC_COMPRESSED);
128 static void init_mutex()
130         if(!mutex_initialized)
131         {
132                 pthread_mutexattr_t attr;
133                 mutex_initialized = 1;
134                 pthread_mutexattr_init(&attr);
135                 pthread_mutex_init(&decode_mutex, &attr);
136                 pthread_mutex_init(&encode_mutex, &attr);
137         }
143 // Determine of the compressed frame is a keyframe for direct copy
144 int quicktime_divx_is_key(unsigned char *data, long size)
146         int result = 0;
147         int i;
149         for(i = 0; i < size - 5; i++)
150         {
151                 if( data[i]     == 0x00 && 
152                         data[i + 1] == 0x00 &&
153                         data[i + 2] == 0x01 &&
154                         data[i + 3] == 0xb6)
155                 {
156                         if((data[i + 4] & 0xc0) == 0x0) 
157                                 return 1;
158                         else
159                                 return 0;
160                 }
161         }
162         
163         return result;
167 // Test for VOL header in frame
168 int quicktime_divx_has_vol(unsigned char *data)
170         if( data[0] == 0x00 &&
171                 data[1] == 0x00 &&
172                 data[2] == 0x01 &&
173                 data[3] == 0x00 &&
174                 data[4] == 0x00 &&
175                 data[5] == 0x00 &&
176                 data[6] == 0x01 &&
177                 data[7] == 0x20)
178                 return 1;
179         else
180                 return 0;
186 static void putbits(unsigned char **data, 
187         int *bit_pos, 
188         uint64_t *bit_store, 
189         int *total, 
190         int count, 
191         uint64_t value)
193         value &= 0xffffffffffffffff >> (64 - count);
195         while(64 - *bit_pos < count)
196         {
197                 *(*data)++ = (*bit_store) >> 56;
198                 (*bit_store) <<= 8;
199                 (*bit_pos) -= 8;
200         }
202         (*bit_store) |= value << (64 - count - *bit_pos);
203         (*bit_pos) += count;
204         (*total) += count;
208 static void flushbits(unsigned char **data, 
209         int *bit_pos, 
210         uint64_t *bit_store)
212 //printf("flushbits %llx\n", (*bit_store));
213         while((*bit_pos) > 0)
214         {
215                 *(*data)++ = (*bit_store) >> 56;
216                 (*bit_store) <<= 8;
217                 (*bit_pos) -= 8;
218         }
224 #define VO_START_CODE           0x8      
225 #define VO_START_CODE_LENGTH    27
226 #define VOL_START_CODE 0x12             /* 25-MAR-97 JDL : according to WD2 */
227 #define VOL_START_CODE_LENGTH 28
231 int quicktime_divx_write_vol(unsigned char *data_start,
232         int vol_width, 
233         int vol_height, 
234         int time_increment_resolution, 
235         float frame_rate)
237         int written = 0;
238         int bits, fixed_vop_time_increment;
239         unsigned char *data = data_start;
240         int bit_pos;
241         uint64_t bit_store;
242         int i, j;
244         bit_store = 0;
245         bit_pos = 0;
246         vol_width = (int)((float)vol_width / 16 + 0.5) * 16;
247         vol_height = (int)((float)vol_height / 16 + 0.5) * 16;
250         putbits(&data, 
251                 &bit_pos, 
252                 &bit_store, 
253                 &written,
254                 VO_START_CODE_LENGTH, VO_START_CODE);
255         putbits(&data, 
256                 &bit_pos, 
257                 &bit_store, 
258                 &written,
259                 5, 0);                          /* vo_id = 0                                                            */
261         putbits(&data, 
262                 &bit_pos, 
263                 &bit_store, 
264                 &written,
265                 VOL_START_CODE_LENGTH, VOL_START_CODE);
270         putbits(&data, 
271                 &bit_pos, 
272                 &bit_store, 
273                 &written,
274                 4, 0);                          /* vol_id = 0                                                           */
276         putbits(&data, 
277                 &bit_pos, 
278                 &bit_store, 
279                 &written,
280                 1, 0);                          /* random_accessible_vol = 0                            */
281         putbits(&data, 
282                 &bit_pos, 
283                 &bit_store, 
284                 &written,
285                 8, 1);                          /* video_object_type_indication = 1 video       */
286         putbits(&data, 
287                 &bit_pos, 
288                 &bit_store, 
289                 &written,
290                 1, 1);                          /* is_object_layer_identifier = 1                       */
291         putbits(&data, 
292                 &bit_pos, 
293                 &bit_store, 
294                 &written,
295                 4, 2);                          /* visual_object_layer_ver_id = 2                       */
296         putbits(&data, 
297                 &bit_pos, 
298                 &bit_store, 
299                 &written,
300                 3, 1);                          /* visual_object_layer_priority = 1                     */
301         putbits(&data, 
302                 &bit_pos, 
303                 &bit_store, 
304                 &written,
305                 4, 1);                          /* aspect_ratio_info = 1                                        */
313         putbits(&data, 
314                 &bit_pos, 
315                 &bit_store, 
316                 &written,
317                 1, 0);                          /* vol_control_parameter = 0                            */
318         putbits(&data, 
319                 &bit_pos, 
320                 &bit_store, 
321                 &written,
322                 2, 0);                          /* vol_shape = 0 rectangular                            */
323         putbits(&data, 
324                 &bit_pos, 
325                 &bit_store, 
326                 &written,
327                 1, 1);                          /* marker                                                                       */
335         putbits(&data, 
336                 &bit_pos, 
337                 &bit_store, 
338                 &written,
339                 16, time_increment_resolution);
340         putbits(&data, 
341                 &bit_pos, 
342                 &bit_store, 
343                 &written,
344                 1, 1);                          /* marker                                                                       */
345         putbits(&data, 
346                 &bit_pos, 
347                 &bit_store, 
348                 &written,
349                 1, 1);                          /* fixed_vop_rate = 1                                           */
352         bits = 1;
353         while((1 << bits) < time_increment_resolution) bits++;
355 // Log calculation fails for some reason
356 //      bits = (int)ceil(log((double)time_increment_resolution) / log(2.0));
357 //    if (bits < 1) bits=1;
359         fixed_vop_time_increment = 
360                 (int)(time_increment_resolution / frame_rate + 0.1);
362         putbits(&data, 
363                 &bit_pos, 
364                 &bit_store, 
365                 &written,
366                 bits, fixed_vop_time_increment);
368         putbits(&data, 
369                 &bit_pos, 
370                 &bit_store, 
371                 &written,
372                 1, 1);                          /* marker                                                                       */
374         putbits(&data, 
375                 &bit_pos, 
376                 &bit_store, 
377                 &written,
378                 13, vol_width);
379         putbits(&data, 
380                 &bit_pos, 
381                 &bit_store, 
382                 &written,
383                 1, 1);                          /* marker                                                                       */
384         putbits(&data, 
385                 &bit_pos, 
386                 &bit_store, 
387                 &written,
388                 13, vol_height);
389         putbits(&data, 
390                 &bit_pos, 
391                 &bit_store, 
392                 &written,
393                 1, 1);                          /* marker                                                                       */
395         putbits(&data, 
396                 &bit_pos, 
397                 &bit_store, 
398                 &written,
399                 1, 0);                          /* interlaced = 0                                                       */
400         putbits(&data, 
401                 &bit_pos, 
402                 &bit_store, 
403                 &written,
404                 1, 1);                          /* OBMC_disabled = 1                                            */
405         putbits(&data, 
406                 &bit_pos, 
407                 &bit_store, 
408                 &written,
409                 2, 0);                          /* vol_sprite_usage = 0                                         */
410         putbits(&data, 
411                 &bit_pos, 
412                 &bit_store, 
413                 &written,
414                 1, 0);                          /* not_8_bit = 0                                                        */
416         putbits(&data, 
417                 &bit_pos, 
418                 &bit_store, 
419                 &written,
420                 1, 0);                          /* vol_quant_type = 0                                           */
421         putbits(&data, 
422                 &bit_pos, 
423                 &bit_store, 
424                 &written,
425                 1, 0);                          /* vol_quarter_pixel = 0                                        */
426         putbits(&data, 
427                 &bit_pos, 
428                 &bit_store, 
429                 &written,
430                 1, 1);                          /* complexity_estimation_disabled = 1           */
431         putbits(&data, 
432                 &bit_pos, 
433                 &bit_store, 
434                 &written,
435                 1, 1);                          /* resync_marker_disabled = 1                           */
436         putbits(&data, 
437                 &bit_pos, 
438                 &bit_store, 
439                 &written,
440                 1, 0);                          /* data_partitioning_enabled = 0                        */
441         putbits(&data, 
442                 &bit_pos, 
443                 &bit_store, 
444                 &written,
445                 1, 0);                          /* scalability = 0                                                      */
447         flushbits(&data, 
448                 &bit_pos,
449                 &bit_store);
454  * for(i = 0; i < data - data_start; i++)
455  *      for(j = 0x80; j >= 1; j /= 2)
456  *              printf("%d", (data_start[i] & j) ? 1 : 0);
457  * printf("\n");
458  */
462         return data - data_start;
469 #define READ_RAW(framenum) \
470 { \
471         quicktime_set_video_position(file, framenum, track); \
472         bytes = quicktime_frame_size(file, framenum, track); \
473         if(!codec->work_buffer || codec->buffer_size < bytes) \
474         { \
475                 if(codec->work_buffer) free(codec->work_buffer); \
476                 codec->buffer_size = bytes; \
477                 codec->work_buffer = calloc(1, codec->buffer_size + 100); \
478         } \
479         result = !quicktime_read_data(file, codec->work_buffer, bytes); \
486 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
488         int i;
489         longest bytes;
490         int result = 0;
491         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
492         quicktime_trak_t *trak = vtrack->track;
493         quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
494         int width = trak->tkhd.track_width;
495         int height = trak->tkhd.track_height;
496         int width_i = (int)((float)width / 16 + 0.5) * 16;
497         int height_i = (int)((float)height / 16 + 0.5) * 16;
498         DEC_FRAME dec_frame;
499         int use_temp = 0;
500         int input_cmodel;
501         char *bmp_pointers[3];
502         long temp_position;
507 //printf("decode 1 %d\n", file->color_model);
509         init_mutex();
510         pthread_mutex_lock(&decode_mutex);
523         if(!codec->decode_initialized)
524         {
525                 DEC_MEM_REQS dec_mem_reqs;
527 // decore requires handle to be > 1
528                 codec->decode_handle = decode_handle++;
529                 codec->last_frame = -1;
530                 codec->dec_param.x_dim = width_i;
531                 codec->dec_param.y_dim = height_i;
532                 codec->dec_param.output_format = DEC_420;
533                 codec->dec_param.time_incr = 0;
535                 decore(codec->decode_handle, DEC_OPT_MEMORY_REQS, &codec->dec_param, &dec_mem_reqs);
536                 codec->dec_param.buffers.mp4_edged_ref_buffers = calloc(1, dec_mem_reqs.mp4_edged_ref_buffers_size);
537                 codec->dec_param.buffers.mp4_edged_for_buffers = calloc(1, dec_mem_reqs.mp4_edged_for_buffers_size);
538                 codec->dec_param.buffers.mp4_display_buffers = calloc(1, dec_mem_reqs.mp4_display_buffers_size);
539                 codec->dec_param.buffers.mp4_state = calloc(1, dec_mem_reqs.mp4_state_size);
540                 codec->dec_param.buffers.mp4_tables = calloc(1, dec_mem_reqs.mp4_tables_size);
541                 codec->dec_param.buffers.mp4_stream = calloc(1, dec_mem_reqs.mp4_stream_size);
542                 decore(codec->decode_handle, DEC_OPT_INIT, &codec->dec_param, NULL);
544                 codec->temp_frame = malloc(width_i * height_i * 3 / 2);
548  *              codec->dec_param.width = width_i;
549  *              codec->dec_param.height = height_i;
550  *              decore(0, DEC_OPT_CREATE, &codec->dec_param, NULL);
551  */
556 // Must decode frame with VOL header first but only the first frame in the
557 // sequence has a VOL header.
558                 temp_position = vtrack->current_position;
559                 READ_RAW(0);
560                 vtrack->current_position = temp_position;
561                 dec_frame.bitstream = codec->work_buffer;
562                 dec_frame.length = bytes;
563                 dec_frame.stride = width_i;
564                 dec_frame.render_flag = 0;
565                 dec_frame.bmp[0] = codec->temp_frame;
566                 dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
567                 dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
568                 decore(codec->decode_handle, 0, &dec_frame, NULL);
572                 codec->decode_initialized = 1;
573         }
575 //printf("decode 1\n");
580         input_cmodel = BC_YUV420P;
581         if(file->color_model == input_cmodel &&
582                 file->out_w == width_i &&
583                 file->out_h == height_i &&
584                 file->in_x == 0 &&
585                 file->in_y == 0 &&
586                 file->in_w == width_i &&
587                 file->in_h == height_i)
588         {
589 //              dec_frame.dst = row_pointers[0];
590                 dec_frame.bmp[0] = row_pointers[0];
591                 dec_frame.bmp[1] = row_pointers[1];
592                 dec_frame.bmp[2] = row_pointers[2];
593                 use_temp = 0;
594         }
595         else
596         {
597 //              dec_frame.dst = codec->temp_frame;
598                 dec_frame.bmp[0] = codec->temp_frame;
599                 dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
600                 dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
601                 use_temp = 1;
602         }
611         dec_frame.stride = width_i;
613 //      dec_frame.render = 1;
614 //      dec_frame.colorspace = DEC_CSP_YV12;
627 //printf("decode 1 %d %d\n", codec->last_frame, vtrack->current_position);
629         if(quicktime_has_keyframes(file, track) && 
630                 vtrack->current_position != codec->last_frame + 1)
631         {
632                 int frame1, frame2 = vtrack->current_position;
634                 frame1 = quicktime_get_keyframe_before(file, vtrack->current_position, track);
636                 if(frame1 < codec->last_frame &&
637                         frame2 > codec->last_frame) frame1 = codec->last_frame + 1;
640                 while(frame1 < frame2)
641                 {
642                         quicktime_set_video_position(file, frame1, track);
643                         bytes = quicktime_frame_size(file, frame1, track);
646                         if(!codec->work_buffer || codec->buffer_size < bytes)
647                         {
648                                 if(codec->work_buffer) free(codec->work_buffer);
649                                 codec->buffer_size = bytes;
650                                 codec->work_buffer = calloc(1, codec->buffer_size + 100);
651                         }
653                         quicktime_read_data(file, codec->work_buffer, bytes);
655 //printf("decode 2 %d %d\n", frame1, frame2);
656                         dec_frame.bitstream = codec->work_buffer;
657                         dec_frame.length = bytes;
658                         dec_frame.render_flag = 0;
659                         decore(codec->decode_handle, 0, &dec_frame, NULL);
660                         frame1++;
661                 }
662                 
663                 
664                 vtrack->current_position = frame2;
665         }
680         codec->last_frame = vtrack->current_position;
681 //printf("decode 1\n");
684         READ_RAW(vtrack->current_position);
688 //printf("decode 1\n");
690 //printf("decode 1\n");
693         dec_frame.bitstream = codec->work_buffer;
694         dec_frame.length = bytes;
695         dec_frame.render_flag = 1;
697 //printf("decode 1\n");
698 //      decore(codec->dec_param.handle, DEC_OPT_DECODE, &dec_frame, NULL);
699         decore(codec->decode_handle, 0, &dec_frame, NULL);
700 //printf("decode 2\n");
703         pthread_mutex_unlock(&decode_mutex);
704 //printf("decode 1 %d %d\n", use_temp, file->color_model);
706         if(use_temp)
707         {
708                 unsigned char **input_rows = malloc(sizeof(unsigned char*) * height_i);
709                 for(i = 0; i < height_i; i++)
710                         input_rows[i] = codec->temp_frame + width_i * 3;
711                 
712                 
713                 cmodel_transfer(row_pointers, /* Leave NULL if non existent */
714                         input_rows,
715                         row_pointers[0], /* Leave NULL if non existent */
716                         row_pointers[1],
717                         row_pointers[2],
718                         codec->temp_frame, /* Leave NULL if non existent */
719                         codec->temp_frame + width_i * height_i,
720                         codec->temp_frame + width_i * height_i + width_i * height_i / 4,
721                         file->in_x,        /* Dimensions to capture from input frame */
722                         file->in_y, 
723                         file->in_w, 
724                         file->in_h,
725                         0,       /* Dimensions to project on output frame */
726                         0, 
727                         file->out_w, 
728                         file->out_h,
729                         input_cmodel, 
730                         file->color_model,
731                         0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
732                         width_i,       /* For planar use the luma rowspan */
733                         width);
734                 
735                 free(input_rows);
736         }
741 //printf("decode 2\n");
743         return result;
748 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
750 //printf("encode 1\n");
751         longest offset = quicktime_position(file);
752         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
753         quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
754         quicktime_trak_t *trak = vtrack->track;
755         int width = trak->tkhd.track_width;
756         int height = trak->tkhd.track_height;
757         int width_i = (int)((float)width / 16 + 0.5) * 16;
758         int height_i = (int)((float)height / 16 + 0.5) * 16;
759         int result = 0;
760         int i;
761         ENC_FRAME encore_input;
762         ENC_RESULT encore_result;
763 //printf("encode 1 %d %d\n", width_i, height_i);
765         init_mutex();
766         pthread_mutex_lock(&encode_mutex);
768         if(!codec->encode_initialized)
769         {
770                 codec->encode_initialized = 1;
771                 codec->encode_handle = encode_handle++;
772                 codec->enc_param.x_dim = width_i;
773                 codec->enc_param.y_dim = height_i;
774                 codec->enc_param.framerate = quicktime_frame_rate(file, track);
775                 codec->enc_param.bitrate = codec->bitrate;
776                 codec->enc_param.rc_period = codec->rc_period;
777                 codec->enc_param.rc_reaction_period = codec->rc_reaction_period;
778                 codec->enc_param.rc_reaction_ratio = codec->rc_reaction_ratio;
779                 codec->enc_param.max_quantizer = codec->max_quantizer;
780                 codec->enc_param.min_quantizer = codec->min_quantizer;
781                 codec->enc_param.max_key_interval = codec->max_key_interval;
783                 codec->enc_param.search_range = codec->quality * 3;
784                 if(codec->enc_param.search_range > 15) codec->enc_param.search_range = 15;
786                 encore(codec->encode_handle, ENC_OPT_INIT, &codec->enc_param, NULL);
787         }
789 //printf("encode 1\n");
791 // Assume planes are contiguous
792         if(file->color_model == BC_YUV420P &&
793                 width == width_i &&
794                 height == height_i)
795         {
796 //printf("encode 1.1\n");
797                 encore_input.image = row_pointers[0];
798         }
799 // Convert to YUV420P
800         else
801         {
802                 if(!codec->temp_frame)
803                 {
804                         codec->temp_frame = malloc(width_i * height_i * 3 / 2);
805                 }
806 //printf("encode 2 %d %d %d %d %d %d\n", file->color_model, width, height, width_i, height_i);
807                 
808 //printf("encode 1.5\n");
809                 cmodel_transfer(0, /* Leave NULL if non existent */
810                         row_pointers,
811                         codec->temp_frame, /* Leave NULL if non existent */
812                         codec->temp_frame + width_i * height_i,
813                         codec->temp_frame + width_i * height_i + width_i * height_i / 4,
814                         row_pointers[0], /* Leave NULL if non existent */
815                         row_pointers[1],
816                         row_pointers[2],
817                         0,        /* Dimensions to capture from input frame */
818                         0, 
819                         width, 
820                         height,
821                         0,       /* Dimensions to project on output frame */
822                         0, 
823                         width, 
824                         height,
825                         file->color_model, 
826                         BC_YUV420P,
827                         0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
828                         width,       /* For planar use the luma rowspan */
829                         width_i);
830                 
831 //printf("encode 2\n");
832         
833                 encore_input.image = codec->temp_frame;
834         }
835 //printf("encode 3\n");
837         if(!codec->work_buffer)
838         {
839                 codec->buffer_size = width * height;
840 //              codec->buffer_size = 0x1000000;
841                 codec->work_buffer = malloc(codec->buffer_size);
842         }
844 //printf("encode 4\n");
846         bzero(codec->work_buffer, codec->buffer_size);
847         encore_input.bitstream = codec->work_buffer;
848         encore_input.length = 0;
849         encore_input.quant = !codec->fix_bitrate ? codec->quantizer : 0;
851         if(codec->p_count == 0)
852         {
853                 codec->p_count++;
854         }
855         else
856         {
857                 codec->p_count++;
858                 if(codec->p_count >= codec->max_key_interval)
859                         codec->p_count = 0;
860         }
862 //printf("encode 5 %d\n", encore_input.quant);
863         encore(codec->encode_handle,    
864                 0,      
865                 &encore_input,
866                 &encore_result);
867         pthread_mutex_unlock(&encode_mutex);
868 //printf("encode 6\n");
870         result = !quicktime_write_data(file, codec->work_buffer, encore_input.length);
871         quicktime_update_tables(file,
872                                                 file->vtracks[track].track,
873                                                 offset,
874                                                 file->vtracks[track].current_chunk,
875                                                 file->vtracks[track].current_position,
876                                                 1,
877                                                 encore_input.length);
879         file->vtracks[track].current_chunk++;
881         if(encore_result.isKeyFrame)
882                 quicktime_insert_keyframe(file, file->vtracks[track].current_position, track);
884 //printf("encode 7\n");
886 //printf("encode 8\n");
888         return result;
891 static int set_parameter(quicktime_t *file, 
892                 int track, 
893                 char *key, 
894                 void *value)
896         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
897         quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
899         if(!strcasecmp(key, "divx_bitrate"))
900                 codec->bitrate = *(int*)value;
901         else
902         if(!strcasecmp(key, "divx_rc_period"))
903                 codec->rc_period = *(int*)value;
904         else
905         if(!strcasecmp(key, "divx_rc_reaction_ratio"))
906                 codec->rc_reaction_ratio = *(int*)value;
907         else
908         if(!strcasecmp(key, "divx_rc_reaction_period"))
909                 codec->rc_reaction_period = *(int*)value;
910         else
911         if(!strcasecmp(key, "divx_max_key_interval"))
912                 codec->max_key_interval = *(int*)value;
913         else
914         if(!strcasecmp(key, "divx_max_quantizer"))
915                 codec->max_quantizer = *(int*)value;
916         else
917         if(!strcasecmp(key, "divx_min_quantizer"))
918                 codec->min_quantizer = *(int*)value;
919         else
920         if(!strcasecmp(key, "divx_quantizer"))
921                 codec->quantizer = *(int*)value;
922         else
923         if(!strcasecmp(key, "divx_quality"))
924                 codec->quality = *(int*)value;
925         else
926         if(!strcasecmp(key, "divx_fix_bitrate"))
927                 codec->fix_bitrate = *(int*)value;
928         return 0;
932 void quicktime_init_codec_divx(quicktime_video_map_t *vtrack)
934         int i;
935         quicktime_divx_codec_t *codec;
937 /* Init public items */
938         ((quicktime_codec_t*)vtrack->codec)->priv = calloc(1, sizeof(quicktime_divx_codec_t));
939         ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = delete_codec;
940         ((quicktime_codec_t*)vtrack->codec)->decode_video = decode;
941         ((quicktime_codec_t*)vtrack->codec)->encode_video = encode;
942         ((quicktime_codec_t*)vtrack->codec)->reads_colormodel = reads_colormodel;
943         ((quicktime_codec_t*)vtrack->codec)->writes_colormodel = writes_colormodel;
944         ((quicktime_codec_t*)vtrack->codec)->set_parameter = set_parameter;
945         
946         codec = ((quicktime_codec_t*)vtrack->codec)->priv;
947         
948         codec->bitrate = 1000000;
949         codec->rc_period = 50;
950         codec->rc_reaction_ratio = 45;
951         codec->rc_reaction_period = 10;
952         codec->max_key_interval = 45;
953         codec->max_quantizer = 31;
954         codec->min_quantizer = 1;
955         codec->quantizer = 10;
956         codec->quality = 5;
957         codec->fix_bitrate = 1;