"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/divx.c.encore50" (9 Jan 2007, 20826 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Divx for encore50
    2 
    3 
    4 #include "colormodels.h"
    5 #include "funcprotos.h"
    6 #include "quicktime.h"
    7 #include "workarounds.h"
    8 #include ENCORE_INCLUDE
    9 #include DECORE_INCLUDE
   10 
   11 #include <pthread.h>
   12 #include <stdint.h>
   13 #include <stdlib.h>
   14 
   15 
   16 typedef struct
   17 {
   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;
   36 
   37     DEC_PARAM dec_param;
   38     ENC_PARAM enc_param;
   39 
   40     int decode_handle;
   41 // Must count pframes in VBR
   42     int p_count;
   43 } quicktime_divx_codec_t;
   44 
   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;
   50 
   51 static int delete_codec(quicktime_video_map_t *vtrack)
   52 {
   53     quicktime_divx_codec_t *codec;
   54 
   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);
   68 
   69 
   70 
   71 
   72 
   73 /*
   74  *      decore(codec->handle,
   75  *          DEC_OPT_DESTROY,
   76  *          0,
   77  *          0);
   78  */
   79 
   80 
   81 
   82         decore(codec->decode_handle,
   83             DEC_OPT_RELEASE,
   84             0,
   85             0);
   86 
   87 
   88 
   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;
   95 }
   96 
   97 static int reads_colormodel(quicktime_t *file, 
   98         int colormodel, 
   99         int track)
  100 {
  101     return (colormodel == BC_YUV420P);
  102 }
  103 
  104 static int writes_colormodel(quicktime_t *file, 
  105         int colormodel, 
  106         int track)
  107 {
  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);
  119 }
  120 
  121 
  122 
  123 
  124 
  125 
  126 
  127 
  128 static void init_mutex()
  129 {
  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     }
  138 }
  139 
  140 
  141 
  142 
  143 // Determine of the compressed frame is a keyframe for direct copy
  144 int quicktime_divx_is_key(unsigned char *data, long size)
  145 {
  146     int result = 0;
  147     int i;
  148 
  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;
  164 }
  165 
  166 
  167 // Test for VOL header in frame
  168 int quicktime_divx_has_vol(unsigned char *data)
  169 {
  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;
  181 }
  182 
  183 
  184 
  185 
  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)
  192 {
  193     value &= 0xffffffffffffffff >> (64 - count);
  194 
  195     while(64 - *bit_pos < count)
  196     {
  197         *(*data)++ = (*bit_store) >> 56;
  198         (*bit_store) <<= 8;
  199         (*bit_pos) -= 8;
  200     }
  201 
  202     (*bit_store) |= value << (64 - count - *bit_pos);
  203     (*bit_pos) += count;
  204     (*total) += count;
  205 }
  206 
  207 
  208 static void flushbits(unsigned char **data, 
  209     int *bit_pos, 
  210     uint64_t *bit_store)
  211 {
  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     }
  219 }
  220 
  221 
  222 
  223 
  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
  228 
  229 
  230 
  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)
  236 {
  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;
  243 
  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;
  248 
  249 
  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                                */
  260 
  261     putbits(&data, 
  262         &bit_pos, 
  263         &bit_store, 
  264         &written,
  265         VOL_START_CODE_LENGTH, VOL_START_CODE);
  266 
  267 
  268 
  269 
  270     putbits(&data, 
  271         &bit_pos, 
  272         &bit_store, 
  273         &written,
  274         4, 0);              /* vol_id = 0                               */
  275 
  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                    */
  306 
  307 
  308 
  309 
  310 
  311 
  312 
  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                                   */
  328 
  329 
  330 
  331 
  332 
  333 
  334 
  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                       */
  350 
  351 
  352     bits = 1;
  353     while((1 << bits) < time_increment_resolution) bits++;
  354 
  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;
  358 
  359     fixed_vop_time_increment = 
  360         (int)(time_increment_resolution / frame_rate + 0.1);
  361 
  362     putbits(&data, 
  363         &bit_pos, 
  364         &bit_store, 
  365         &written,
  366         bits, fixed_vop_time_increment);
  367 
  368     putbits(&data, 
  369         &bit_pos, 
  370         &bit_store, 
  371         &written,
  372         1, 1);              /* marker                                   */
  373 
  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                                   */
  394 
  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                            */
  415 
  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                          */
  446 
  447     flushbits(&data, 
  448         &bit_pos,
  449         &bit_store);
  450 
  451 
  452 
  453 /*
  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  */
  459 
  460 
  461 
  462     return data - data_start;
  463 }
  464 
  465 
  466 
  467 
  468 
  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); \
  480 }
  481 
  482 
  483 
  484 
  485 
  486 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
  487 {
  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;
  503 
  504 
  505 
  506 
  507 //printf("decode 1 %d\n", file->color_model);
  508 
  509     init_mutex();
  510     pthread_mutex_lock(&decode_mutex);
  511 
  512 
  513 
  514 
  515 
  516 
  517 
  518 
  519 
  520 
  521 
  522 
  523     if(!codec->decode_initialized)
  524     {
  525         DEC_MEM_REQS dec_mem_reqs;
  526 
  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;
  534 
  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);
  543 
  544         codec->temp_frame = malloc(width_i * height_i * 3 / 2);
  545 
  546 
  547 /*
  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  */
  552 
  553 
  554 
  555 
  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);
  569 
  570 
  571 
  572         codec->decode_initialized = 1;
  573     }
  574 
  575 //printf("decode 1\n");
  576 
  577 
  578 
  579 
  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     }
  603 
  604 
  605 
  606 
  607 
  608 
  609 
  610 
  611     dec_frame.stride = width_i;
  612 
  613 //  dec_frame.render = 1;
  614 //  dec_frame.colorspace = DEC_CSP_YV12;
  615 
  616 
  617 
  618 
  619 
  620 
  621 
  622 
  623 
  624 
  625 
  626 
  627 //printf("decode 1 %d %d\n", codec->last_frame, vtrack->current_position);
  628 
  629     if(quicktime_has_keyframes(file, track) && 
  630         vtrack->current_position != codec->last_frame + 1)
  631     {
  632         int frame1, frame2 = vtrack->current_position;
  633 
  634         frame1 = quicktime_get_keyframe_before(file, vtrack->current_position, track);
  635 
  636         if(frame1 < codec->last_frame &&
  637             frame2 > codec->last_frame) frame1 = codec->last_frame + 1;
  638 
  639 
  640         while(frame1 < frame2)
  641         {
  642             quicktime_set_video_position(file, frame1, track);
  643             bytes = quicktime_frame_size(file, frame1, track);
  644 
  645 
  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             }
  652 
  653             quicktime_read_data(file, codec->work_buffer, bytes);
  654 
  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     }
  666 
  667 
  668 
  669 
  670 
  671 
  672 
  673 
  674 
  675 
  676 
  677 
  678 
  679 
  680     codec->last_frame = vtrack->current_position;
  681 //printf("decode 1\n");
  682 
  683 
  684     READ_RAW(vtrack->current_position);
  685 
  686 
  687 
  688 //printf("decode 1\n");
  689 
  690 //printf("decode 1\n");
  691 
  692 
  693     dec_frame.bitstream = codec->work_buffer;
  694     dec_frame.length = bytes;
  695     dec_frame.render_flag = 1;
  696 
  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");
  701 
  702 
  703     pthread_mutex_unlock(&decode_mutex);
  704 //printf("decode 1 %d %d\n", use_temp, file->color_model);
  705 
  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     }
  737 
  738 
  739 
  740 
  741 //printf("decode 2\n");
  742 
  743     return result;
  744 }
  745 
  746 
  747 
  748 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  749 {
  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);
  764 
  765     init_mutex();
  766     pthread_mutex_lock(&encode_mutex);
  767 
  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;
  782 
  783         codec->enc_param.search_range = codec->quality * 3;
  784         if(codec->enc_param.search_range > 15) codec->enc_param.search_range = 15;
  785 
  786         encore(codec->encode_handle, ENC_OPT_INIT, &codec->enc_param, NULL);
  787     }
  788 
  789 //printf("encode 1\n");
  790 
  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");
  836 
  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     }
  843 
  844 //printf("encode 4\n");
  845 
  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;
  850 
  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     }
  861 
  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");
  869 
  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);
  878 
  879     file->vtracks[track].current_chunk++;
  880 
  881     if(encore_result.isKeyFrame)
  882         quicktime_insert_keyframe(file, file->vtracks[track].current_position, track);
  883 
  884 //printf("encode 7\n");
  885 
  886 //printf("encode 8\n");
  887 
  888     return result;
  889 }
  890 
  891 static int set_parameter(quicktime_t *file, 
  892         int track, 
  893         char *key, 
  894         void *value)
  895 {
  896     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  897     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  898 
  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;
  929 }
  930 
  931 
  932 void quicktime_init_codec_divx(quicktime_video_map_t *vtrack)
  933 {
  934     int i;
  935     quicktime_divx_codec_t *codec;
  936 
  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;
  958 }
  959