"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/divx.c" (9 Jan 2007, 24576 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 #define FIELDS 2
   19     unsigned char *work_buffer;
   20     char *temp_frame;
   21     long buffer_size;
   22     int decode_initialized[FIELDS];
   23     int encode_initialized[FIELDS];
   24 // For heroine 60 encoding, we want different streams for each field.
   25     int total_fields;
   26     int bitrate;
   27     long rc_period;          // the intended rate control averaging period
   28     long rc_reaction_period; // the reation period for rate control
   29     long rc_reaction_ratio;  // the ratio for down/up rate control
   30     long max_key_interval;   // the maximum interval between key frames
   31     int max_quantizer;       // the upper limit of the quantizer
   32     int min_quantizer;       // the lower limit of the quantizer
   33     int quantizer;           // For vbr
   34     int quality;             // the forward search range for motion estimation
   35     int fix_bitrate;
   36     int use_deblocking;
   37 
   38 // Last frame decoded
   39     long last_frame[FIELDS];
   40     int encode_handle[FIELDS];
   41 
   42     DEC_PARAM dec_param[FIELDS];
   43     ENC_PARAM enc_param[FIELDS];
   44 
   45     int decode_handle[FIELDS];
   46 // Must count pframes in VBR
   47     int p_count[FIELDS];
   48 } quicktime_divx_codec_t;
   49 
   50 static pthread_mutex_t encode_mutex;
   51 static pthread_mutex_t decode_mutex;
   52 static int mutex_initialized = 0;
   53 static int decode_handle = 1;
   54 static int encode_handle = 0;
   55 
   56 static int delete_codec(quicktime_video_map_t *vtrack)
   57 {
   58     quicktime_divx_codec_t *codec;
   59     int i;
   60 //printf("delete_codec 1\n");
   61 
   62 
   63     codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   64     for(i = 0; i < codec->total_fields; i++)
   65     {
   66         if(codec->encode_initialized[i])
   67         {
   68             pthread_mutex_lock(&encode_mutex);
   69             encore(codec->encode_handle[i],
   70                 ENC_OPT_RELEASE,
   71                 0,
   72                 0);
   73             pthread_mutex_unlock(&encode_mutex);
   74         }
   75 
   76         if(codec->decode_initialized[i])
   77         {
   78             pthread_mutex_lock(&decode_mutex);
   79 
   80             decore_set_global(&codec->dec_param[i]);
   81             decore(codec->decode_handle[i],
   82                 DEC_OPT_RELEASE,
   83                 0,
   84                 0);
   85 
   86             free(codec->dec_param[i].buffers.mp4_edged_ref_buffers);
   87             free(codec->dec_param[i].buffers.mp4_edged_for_buffers);
   88             free(codec->dec_param[i].buffers.mp4_display_buffers);
   89             free(codec->dec_param[i].buffers.mp4_state);
   90             free(codec->dec_param[i].buffers.mp4_tables);
   91             free(codec->dec_param[i].buffers.mp4_stream);
   92 
   93             pthread_mutex_unlock(&decode_mutex);
   94         }
   95     }
   96     pthread_mutex_unlock(&decode_mutex);
   97 
   98 
   99     if(codec->temp_frame) free(codec->temp_frame);
  100     if(codec->work_buffer) free(codec->work_buffer);
  101 
  102 
  103     free(codec);
  104 //printf("delete_codec 100\n");
  105     return 0;
  106 }
  107 
  108 static int reads_colormodel(quicktime_t *file, 
  109         int colormodel, 
  110         int track)
  111 {
  112     return (colormodel == BC_YUV420P);
  113 }
  114 
  115 static int writes_colormodel(quicktime_t *file, 
  116         int colormodel, 
  117         int track)
  118 {
  119     return (colormodel == BC_RGB888 ||
  120         colormodel == BC_RGBA8888 ||
  121         colormodel == BC_RGB161616 ||
  122         colormodel == BC_RGBA16161616 ||
  123         colormodel == BC_YUV888 ||
  124         colormodel == BC_YUVA8888 ||
  125         colormodel == BC_YUV161616 ||
  126         colormodel == BC_YUVA16161616 ||
  127         colormodel == BC_YUV420P ||
  128         colormodel == BC_YUV422 ||
  129         colormodel == BC_COMPRESSED);
  130 }
  131 
  132 
  133 
  134 
  135 
  136 
  137 
  138 
  139 static void init_mutex()
  140 {
  141     if(!mutex_initialized)
  142     {
  143         pthread_mutexattr_t attr;
  144         mutex_initialized = 1;
  145         pthread_mutexattr_init(&attr);
  146         pthread_mutex_init(&decode_mutex, &attr);
  147         pthread_mutex_init(&encode_mutex, &attr);
  148     }
  149 }
  150 
  151 
  152 
  153 
  154 // Determine of the compressed frame is a keyframe for direct copy
  155 int quicktime_divx_is_key(unsigned char *data, long size)
  156 {
  157     int result = 0;
  158     int i;
  159 
  160     for(i = 0; i < size - 5; i++)
  161     {
  162         if( data[i]     == 0x00 && 
  163             data[i + 1] == 0x00 &&
  164             data[i + 2] == 0x01 &&
  165             data[i + 3] == 0xb6)
  166         {
  167             if((data[i + 4] & 0xc0) == 0x0) 
  168                 return 1;
  169             else
  170                 return 0;
  171         }
  172     }
  173     
  174     return result;
  175 }
  176 
  177 
  178 // Test for VOL header in frame
  179 int quicktime_divx_has_vol(unsigned char *data)
  180 {
  181     if( data[0] == 0x00 &&
  182         data[1] == 0x00 &&
  183         data[2] == 0x01 &&
  184         data[3] == 0x00 &&
  185         data[4] == 0x00 &&
  186         data[5] == 0x00 &&
  187         data[6] == 0x01 &&
  188         data[7] == 0x20)
  189         return 1;
  190     else
  191         return 0;
  192 }
  193 
  194 
  195 
  196 
  197 static void putbits(unsigned char **data, 
  198     int *bit_pos, 
  199     uint64_t *bit_store, 
  200     int *total, 
  201     int count, 
  202     uint64_t value)
  203 {
  204     value &= 0xffffffffffffffff >> (64 - count);
  205 
  206     while(64 - *bit_pos < count)
  207     {
  208         *(*data)++ = (*bit_store) >> 56;
  209         (*bit_store) <<= 8;
  210         (*bit_pos) -= 8;
  211     }
  212 
  213     (*bit_store) |= value << (64 - count - *bit_pos);
  214     (*bit_pos) += count;
  215     (*total) += count;
  216 }
  217 
  218 
  219 static void flushbits(unsigned char **data, 
  220     int *bit_pos, 
  221     uint64_t *bit_store)
  222 {
  223 //printf("flushbits %llx\n", (*bit_store));
  224     while((*bit_pos) > 0)
  225     {
  226         *(*data)++ = (*bit_store) >> 56;
  227         (*bit_store) <<= 8;
  228         (*bit_pos) -= 8;
  229     }
  230 }
  231 
  232 
  233 
  234 
  235 #define VO_START_CODE       0x8      
  236 #define VO_START_CODE_LENGTH    27
  237 #define VOL_START_CODE 0x12             /* 25-MAR-97 JDL : according to WD2 */
  238 #define VOL_START_CODE_LENGTH 28
  239 
  240 
  241 
  242 int quicktime_divx_write_vol(unsigned char *data_start,
  243     int vol_width, 
  244     int vol_height, 
  245     int time_increment_resolution, 
  246     double frame_rate)
  247 {
  248     int written = 0;
  249     int bits, fixed_vop_time_increment;
  250     unsigned char *data = data_start;
  251     int bit_pos;
  252     uint64_t bit_store;
  253     int i, j;
  254 
  255     bit_store = 0;
  256     bit_pos = 0;
  257     vol_width = (int)((float)vol_width / 16 + 0.5) * 16;
  258     vol_height = (int)((float)vol_height / 16 + 0.5) * 16;
  259 
  260 
  261     putbits(&data, 
  262         &bit_pos, 
  263         &bit_store, 
  264         &written,
  265         VO_START_CODE_LENGTH, VO_START_CODE);
  266     putbits(&data, 
  267         &bit_pos, 
  268         &bit_store, 
  269         &written,
  270         5, 0);              /* vo_id = 0                                */
  271 
  272     putbits(&data, 
  273         &bit_pos, 
  274         &bit_store, 
  275         &written,
  276         VOL_START_CODE_LENGTH, VOL_START_CODE);
  277 
  278 
  279 
  280 
  281     putbits(&data, 
  282         &bit_pos, 
  283         &bit_store, 
  284         &written,
  285         4, 0);              /* vol_id = 0                               */
  286 
  287     putbits(&data, 
  288         &bit_pos, 
  289         &bit_store, 
  290         &written,
  291         1, 0);              /* random_accessible_vol = 0                */
  292     putbits(&data, 
  293         &bit_pos, 
  294         &bit_store, 
  295         &written,
  296         8, 1);              /* video_object_type_indication = 1 video   */
  297     putbits(&data, 
  298         &bit_pos, 
  299         &bit_store, 
  300         &written,
  301         1, 1);              /* is_object_layer_identifier = 1           */
  302     putbits(&data, 
  303         &bit_pos, 
  304         &bit_store, 
  305         &written,
  306         4, 2);              /* visual_object_layer_ver_id = 2           */
  307     putbits(&data, 
  308         &bit_pos, 
  309         &bit_store, 
  310         &written,
  311         3, 1);              /* visual_object_layer_priority = 1         */
  312     putbits(&data, 
  313         &bit_pos, 
  314         &bit_store, 
  315         &written,
  316         4, 1);              /* aspect_ratio_info = 1                    */
  317 
  318 
  319 
  320 
  321 
  322 
  323 
  324     putbits(&data, 
  325         &bit_pos, 
  326         &bit_store, 
  327         &written,
  328         1, 0);              /* vol_control_parameter = 0                */
  329     putbits(&data, 
  330         &bit_pos, 
  331         &bit_store, 
  332         &written,
  333         2, 0);              /* vol_shape = 0 rectangular                */
  334     putbits(&data, 
  335         &bit_pos, 
  336         &bit_store, 
  337         &written,
  338         1, 1);              /* marker                                   */
  339 
  340 
  341 
  342 
  343 
  344 
  345 
  346     putbits(&data, 
  347         &bit_pos, 
  348         &bit_store, 
  349         &written,
  350         16, time_increment_resolution);
  351     putbits(&data, 
  352         &bit_pos, 
  353         &bit_store, 
  354         &written,
  355         1, 1);              /* marker                                   */
  356     putbits(&data, 
  357         &bit_pos, 
  358         &bit_store, 
  359         &written,
  360         1, 1);              /* fixed_vop_rate = 1                       */
  361 
  362 
  363     bits = 1;
  364     while((1 << bits) < time_increment_resolution) bits++;
  365 
  366 // Log calculation fails for some reason
  367 //  bits = (int)ceil(log((double)time_increment_resolution) / log(2.0));
  368 //    if (bits < 1) bits=1;
  369 
  370     fixed_vop_time_increment = 
  371         (int)(time_increment_resolution / frame_rate + 0.1);
  372 
  373     putbits(&data, 
  374         &bit_pos, 
  375         &bit_store, 
  376         &written,
  377         bits, fixed_vop_time_increment);
  378 
  379     putbits(&data, 
  380         &bit_pos, 
  381         &bit_store, 
  382         &written,
  383         1, 1);              /* marker                                   */
  384 
  385     putbits(&data, 
  386         &bit_pos, 
  387         &bit_store, 
  388         &written,
  389         13, vol_width);
  390     putbits(&data, 
  391         &bit_pos, 
  392         &bit_store, 
  393         &written,
  394         1, 1);              /* marker                                   */
  395     putbits(&data, 
  396         &bit_pos, 
  397         &bit_store, 
  398         &written,
  399         13, vol_height);
  400     putbits(&data, 
  401         &bit_pos, 
  402         &bit_store, 
  403         &written,
  404         1, 1);              /* marker                                   */
  405 
  406     putbits(&data, 
  407         &bit_pos, 
  408         &bit_store, 
  409         &written,
  410         1, 0);              /* interlaced = 0                           */
  411     putbits(&data, 
  412         &bit_pos, 
  413         &bit_store, 
  414         &written,
  415         1, 1);              /* OBMC_disabled = 1                        */
  416     putbits(&data, 
  417         &bit_pos, 
  418         &bit_store, 
  419         &written,
  420         2, 0);              /* vol_sprite_usage = 0                     */
  421     putbits(&data, 
  422         &bit_pos, 
  423         &bit_store, 
  424         &written,
  425         1, 0);              /* not_8_bit = 0                            */
  426 
  427     putbits(&data, 
  428         &bit_pos, 
  429         &bit_store, 
  430         &written,
  431         1, 0);              /* vol_quant_type = 0                       */
  432     putbits(&data, 
  433         &bit_pos, 
  434         &bit_store, 
  435         &written,
  436         1, 0);              /* vol_quarter_pixel = 0                    */
  437     putbits(&data, 
  438         &bit_pos, 
  439         &bit_store, 
  440         &written,
  441         1, 1);              /* complexity_estimation_disabled = 1       */
  442     putbits(&data, 
  443         &bit_pos, 
  444         &bit_store, 
  445         &written,
  446         1, 1);              /* resync_marker_disabled = 1               */
  447     putbits(&data, 
  448         &bit_pos, 
  449         &bit_store, 
  450         &written,
  451         1, 0);              /* data_partitioning_enabled = 0            */
  452     putbits(&data, 
  453         &bit_pos, 
  454         &bit_store, 
  455         &written,
  456         1, 0);              /* scalability = 0                          */
  457 
  458     flushbits(&data, 
  459         &bit_pos,
  460         &bit_store);
  461 
  462 
  463 
  464 /*
  465  * for(i = 0; i < data - data_start; i++)
  466  *  for(j = 0x80; j >= 1; j /= 2)
  467  *      printf("%d", (data_start[i] & j) ? 1 : 0);
  468  * printf("\n");
  469  */
  470 
  471 
  472 
  473     return data - data_start;
  474 }
  475 
  476 
  477 
  478 
  479 
  480 #define READ_RAW(framenum) \
  481 { \
  482     quicktime_set_video_position(file, framenum, track); \
  483     bytes = quicktime_frame_size(file, framenum, track); \
  484     if(!codec->work_buffer || codec->buffer_size < bytes) \
  485     { \
  486         if(codec->work_buffer) free(codec->work_buffer); \
  487         codec->buffer_size = bytes; \
  488         codec->work_buffer = calloc(1, codec->buffer_size + 100); \
  489     } \
  490     result = !quicktime_read_data(file, codec->work_buffer, bytes); \
  491 }
  492 
  493 
  494 
  495 
  496 
  497 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
  498 {
  499     int i;
  500     longest bytes;
  501     int result = 0;
  502     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  503     quicktime_trak_t *trak = vtrack->track;
  504     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  505     int width = trak->tkhd.track_width;
  506     int height = trak->tkhd.track_height;
  507     int width_i = (int)((float)width / 16 + 0.5) * 16;
  508     int height_i = (int)((float)height / 16 + 0.5) * 16;
  509     DEC_FRAME dec_frame;
  510     int use_temp = 0;
  511     int input_cmodel;
  512     char *bmp_pointers[3];
  513     long temp_position;
  514     int current_field = vtrack->current_position % codec->total_fields;
  515 
  516 
  517 
  518     init_mutex();
  519     pthread_mutex_lock(&decode_mutex);
  520 
  521 
  522 
  523 
  524 
  525 
  526 /*
  527  * printf("decode 1 %d %d %d\n", 
  528  * vtrack->current_position, 
  529  * current_field,
  530  * codec->decode_initialized[current_field]);
  531  */
  532 
  533 
  534 
  535 
  536 
  537     if(!codec->decode_initialized[current_field])
  538     {
  539         DEC_MEM_REQS dec_mem_reqs;
  540 
  541 
  542         if(!codec->temp_frame)
  543             codec->temp_frame = malloc(width_i * height_i * 3 / 2);
  544 
  545 // decore requires handle to be > 1
  546         codec->decode_handle[current_field] = decode_handle++;
  547         codec->last_frame[current_field] = -1;
  548         codec->dec_param[current_field].x_dim = width_i;
  549         codec->dec_param[current_field].y_dim = height_i;
  550         codec->dec_param[current_field].output_format = DEC_420;
  551         codec->dec_param[current_field].time_incr = 0;
  552 
  553         decore(codec->decode_handle[current_field], 
  554             DEC_OPT_MEMORY_REQS, 
  555             &codec->dec_param[current_field], 
  556             &dec_mem_reqs);
  557         codec->dec_param[current_field].buffers.mp4_edged_ref_buffers = 
  558             calloc(1, dec_mem_reqs.mp4_edged_ref_buffers_size);
  559         codec->dec_param[current_field].buffers.mp4_edged_for_buffers = 
  560             calloc(1, dec_mem_reqs.mp4_edged_for_buffers_size);
  561         codec->dec_param[current_field].buffers.mp4_display_buffers = 
  562             calloc(1, dec_mem_reqs.mp4_display_buffers_size);
  563         codec->dec_param[current_field].buffers.mp4_state = 
  564             calloc(1, dec_mem_reqs.mp4_state_size);
  565         codec->dec_param[current_field].buffers.mp4_tables = 
  566             calloc(1, dec_mem_reqs.mp4_tables_size);
  567         codec->dec_param[current_field].buffers.mp4_stream = 
  568             calloc(1, dec_mem_reqs.mp4_stream_size);
  569 //printf("decode 2\n");
  570         decore(codec->decode_handle[current_field], 
  571             DEC_OPT_INIT, 
  572             &codec->dec_param[current_field], 
  573             NULL);
  574 
  575 //printf("decode 3\n");
  576 
  577 
  578 
  579 // Must decode frame with VOL header first but only the first frame in the
  580 // field sequence has a VOL header.
  581         temp_position = vtrack->current_position;
  582         READ_RAW(current_field);
  583         vtrack->current_position = temp_position;
  584         dec_frame.bitstream = codec->work_buffer;
  585         dec_frame.length = bytes;
  586         dec_frame.stride = width_i;
  587         dec_frame.render_flag = 0;
  588         dec_frame.bmp[0] = codec->temp_frame;
  589         dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
  590         dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
  591         decore(codec->decode_handle[current_field], 0, &dec_frame, NULL);
  592 
  593 
  594 //printf("decode 9\n");
  595 
  596         codec->decode_initialized[current_field] = 1;
  597         decore_save_global(&codec->dec_param[current_field]);
  598     }
  599 //printf("decode 10\n");
  600 
  601     decore_set_global(&codec->dec_param[current_field]);
  602 
  603 // Enable deblocking.  This doesn't make much difference at high bitrates.
  604     DEC_SET dec_set_arg;
  605     dec_set_arg.postproc_level = (codec->use_deblocking ? 100 : 0);
  606     decore(codec->decode_handle[current_field], 
  607         DEC_OPT_SETPP, 
  608         &dec_set_arg, 
  609         NULL);
  610 //printf("decode 30\n");
  611 
  612 
  613 
  614     input_cmodel = BC_YUV420P;
  615 
  616 // Decode directly into return values
  617     if(file->color_model == input_cmodel &&
  618         file->out_w == width_i &&
  619         file->out_h == height_i &&
  620         file->in_x == 0 &&
  621         file->in_y == 0 &&
  622         file->in_w == width_i &&
  623         file->in_h == height_i)
  624     {
  625 //      dec_frame.dst = row_pointers[0];
  626         dec_frame.bmp[0] = row_pointers[0];
  627         dec_frame.bmp[1] = row_pointers[1];
  628         dec_frame.bmp[2] = row_pointers[2];
  629         use_temp = 0;
  630     }
  631     else
  632 // Decode into temporaries
  633     {
  634         dec_frame.bmp[0] = codec->temp_frame;
  635         dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
  636         dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
  637         use_temp = 1;
  638     }
  639 
  640 //printf("decode 40\n");
  641     dec_frame.stride = width_i;
  642 
  643 
  644 
  645 
  646 
  647 
  648 
  649 
  650 
  651 
  652 
  653 
  654 //printf("decode 1 %d %d\n", codec->last_frame, vtrack->current_position);
  655 
  656     if(quicktime_has_keyframes(file, track) && 
  657         vtrack->current_position != 
  658             codec->last_frame[current_field] + codec->total_fields)
  659     {
  660         int frame1, frame2 = vtrack->current_position, current_frame = frame2;
  661 
  662 // Get first keyframe of same field
  663         do
  664         {
  665             frame1 = quicktime_get_keyframe_before(file, 
  666                 current_frame--, 
  667                 track);
  668         }while(frame1 > 0 && (frame1 % codec->total_fields) != current_field);
  669 
  670 
  671 // Keyframe is before last decoded frame and current frame is after last decoded
  672 // frame, so instead of rerendering from the last keyframe we can rerender from
  673 // the last decoded frame.
  674         if(frame1 < codec->last_frame[current_field] &&
  675             frame2 > codec->last_frame[current_field]) 
  676             frame1 = codec->last_frame[current_field] + codec->total_fields;
  677 
  678 // Render up to current position
  679         while(frame1 < frame2)
  680         {
  681             READ_RAW(frame1);
  682 
  683             dec_frame.bitstream = codec->work_buffer;
  684             dec_frame.length = bytes;
  685             dec_frame.render_flag = 0;
  686             decore(codec->decode_handle[current_field], 
  687                 0, 
  688                 &dec_frame, 
  689                 NULL);
  690             frame1 += codec->total_fields;
  691         }
  692         
  693         
  694         vtrack->current_position = frame2;
  695     }
  696 
  697 
  698 
  699 
  700 
  701 //printf("decode 50\n");
  702 
  703 
  704 
  705 
  706 
  707 
  708 
  709 
  710 
  711     codec->last_frame[current_field] = vtrack->current_position;
  712 //printf("decode 1\n");
  713 
  714 
  715     READ_RAW(vtrack->current_position);
  716 
  717 
  718 
  719 //printf("decode 6\n");
  720 
  721 
  722     dec_frame.bitstream = codec->work_buffer;
  723     dec_frame.length = bytes;
  724     dec_frame.render_flag = 1;
  725 
  726 //printf("decode 60\n");
  727     decore(codec->decode_handle[current_field], 0, &dec_frame, NULL);
  728 //printf("decode 100\n");
  729 
  730 
  731 
  732 // Now line average the Y buffer, doubling its height 
  733 // while keeping the UV buffers the same.
  734 /*
  735  *  if(codec->total_fields == 2)
  736  *  {
  737  *      unsigned char *bitmap = dec_frame.bmp[0];
  738  *      unsigned char *in_row1 = bitmap + width_i * height_i / 2 - width_i * 2;
  739  *      unsigned char *in_row2 = in_row1 + width_i;
  740  *      unsigned char *out_row1 = bitmap + width_i * height_i - width_i * 2;
  741  *      unsigned char *out_row2 = out_row1 + width_i;
  742  * 
  743  *      while(in_row1 >= bitmap)
  744  *      {
  745  *          unsigned char *in_ptr1 = in_row1;
  746  *          unsigned char *in_ptr2 = in_row2;
  747  *          unsigned char *out_ptr1 = out_row1;
  748  *          unsigned char *out_ptr2 = out_row2;
  749  *          if(current_field == 0)
  750  *              for(i = 0; i < width_i; i++)
  751  *              {
  752  *                  *out_ptr1++ = ((int64_t)*in_ptr1 + (int64_t)*in_ptr2) >> 1;
  753  *                  *out_ptr2++ = *in_ptr2;
  754  *                  in_ptr1++;
  755  *                  in_ptr2++;
  756  *              }
  757  *          else
  758  *              for(i = 0; i < width_i; i++)
  759  *              {
  760  *                  *out_ptr1++ = *in_ptr1;
  761  *                  *out_ptr2++ = ((int64_t)*in_ptr1 + (int64_t)*in_ptr2) >> 1;
  762  *                  in_ptr1++;
  763  *                  in_ptr2++;
  764  *              }
  765  *          in_row1 -= width_i;
  766  *          in_row2 -= width_i;
  767  *          out_row1 -= width_i * 2;
  768  *          out_row2 -= width_i * 2;
  769  *      }
  770  *  }
  771  */
  772 
  773 //printf("decode 110\n");
  774 
  775 // Convert to output colorspace
  776     if(use_temp)
  777     {
  778         unsigned char **input_rows = malloc(sizeof(unsigned char*) * height_i);
  779         for(i = 0; i < height_i; i++)
  780             input_rows[i] = codec->temp_frame + width_i * 3;
  781         
  782         
  783         cmodel_transfer(row_pointers, /* Leave NULL if non existent */
  784             input_rows,
  785             row_pointers[0], /* Leave NULL if non existent */
  786             row_pointers[1],
  787             row_pointers[2],
  788             codec->temp_frame, /* Leave NULL if non existent */
  789             codec->temp_frame + width_i * height_i,
  790             codec->temp_frame + width_i * height_i + width_i * height_i / 4,
  791             file->in_x,        /* Dimensions to capture from input frame */
  792             file->in_y, 
  793             file->in_w, 
  794             file->in_h,
  795             0,       /* Dimensions to project on output frame */
  796             0, 
  797             file->out_w, 
  798             file->out_h,
  799             input_cmodel, 
  800             file->color_model,
  801             0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
  802             width_i,       /* For planar use the luma rowspan */
  803             width);
  804         
  805         free(input_rows);
  806     }
  807 
  808 
  809     decore_save_global(&codec->dec_param[current_field]);
  810     pthread_mutex_unlock(&decode_mutex);
  811 
  812 
  813 //printf("decode 120\n");
  814 
  815     return result;
  816 }
  817 
  818 
  819 
  820 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  821 {
  822     longest offset = quicktime_position(file);
  823     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  824     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  825     quicktime_trak_t *trak = vtrack->track;
  826     int width = trak->tkhd.track_width;
  827     int height = trak->tkhd.track_height;
  828     int width_i = (int)((float)width / 16 + 0.5) * 16;
  829     int height_i = (int)((float)height / 16 + 0.5) * 16;
  830     int result = 0;
  831     int i;
  832     ENC_FRAME encore_input;
  833     ENC_RESULT encore_result;
  834     int current_field = vtrack->current_position % codec->total_fields;
  835 
  836     init_mutex();
  837     pthread_mutex_lock(&encode_mutex);
  838 
  839     if(!codec->encode_initialized[current_field])
  840     {
  841         codec->encode_initialized[current_field] = 1;
  842         codec->encode_handle[current_field] = encode_handle++;
  843         codec->enc_param[current_field].x_dim = width_i;
  844         codec->enc_param[current_field].y_dim = height_i;
  845         codec->enc_param[current_field].framerate = 
  846             quicktime_frame_rate(file, track) / codec->total_fields;
  847         codec->enc_param[current_field].bitrate = 
  848             codec->bitrate / codec->total_fields;
  849         codec->enc_param[current_field].rc_period = codec->rc_period;
  850         codec->enc_param[current_field].rc_reaction_period = codec->rc_reaction_period;
  851         codec->enc_param[current_field].rc_reaction_ratio = codec->rc_reaction_ratio;
  852         codec->enc_param[current_field].max_quantizer = codec->max_quantizer;
  853         codec->enc_param[current_field].min_quantizer = codec->min_quantizer;
  854         codec->enc_param[current_field].max_key_interval = codec->max_key_interval;
  855 
  856         codec->enc_param[current_field].search_range = codec->quality * 3;
  857         if(codec->enc_param[current_field].search_range > 15) 
  858             codec->enc_param[current_field].search_range = 15;
  859 
  860         encore(codec->encode_handle[current_field], 
  861             ENC_OPT_INIT, 
  862             &codec->enc_param[current_field], NULL);
  863     }
  864 
  865 
  866 // Assume planes are contiguous.
  867 // Encode directly from function arguments
  868     if(file->color_model == BC_YUV420P &&
  869         width == width_i &&
  870         height == height_i)
  871     {
  872         encore_input.image = row_pointers[0];
  873     }
  874 // Convert to YUV420P
  875 // Encode from temporary.
  876     else
  877     {
  878         if(!codec->temp_frame)
  879         {
  880             codec->temp_frame = malloc(width_i * height_i * 3 / 2);
  881         }
  882         
  883         cmodel_transfer(0, /* Leave NULL if non existent */
  884             row_pointers,
  885             codec->temp_frame, /* Leave NULL if non existent */
  886             codec->temp_frame + width_i * height_i,
  887             codec->temp_frame + width_i * height_i + width_i * height_i / 4,
  888             row_pointers[0], /* Leave NULL if non existent */
  889             row_pointers[1],
  890             row_pointers[2],
  891             0,        /* Dimensions to capture from input frame */
  892             0, 
  893             width, 
  894             height,
  895             0,       /* Dimensions to project on output frame */
  896             0, 
  897             width, 
  898             height,
  899             file->color_model, 
  900             BC_YUV420P,
  901             0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
  902             width,       /* For planar use the luma rowspan */
  903             width_i);
  904         
  905     
  906         encore_input.image = codec->temp_frame;
  907     }
  908 
  909 // Now shrink the Y buffer by half to contain just one field
  910 /*
  911  *  if(codec->total_fields == 2)
  912  *  {
  913  *      unsigned char *out_ptr = encore_input.image;
  914  *      unsigned char *in_ptr = encore_input.image + current_field * width_i;
  915  *      int size = width_i * height_i;
  916  *      while(in_ptr < (unsigned char*)encore_input.image + size)
  917  *      {
  918  *          for(i = 0; i < width_i; i++)
  919  *              *out_ptr++ = *in_ptr++;
  920  *          in_ptr += width_i;
  921  *      }
  922  *      bzero(out_ptr, (unsigned char*)encore_input.image + size - out_ptr);
  923  *  }
  924  * 
  925  */
  926 
  927 
  928 
  929     if(!codec->work_buffer)
  930     {
  931         codec->buffer_size = width * height;
  932         codec->work_buffer = malloc(codec->buffer_size);
  933     }
  934 
  935 
  936     bzero(codec->work_buffer, codec->buffer_size);
  937     encore_input.bitstream = codec->work_buffer;
  938     encore_input.length = 0;
  939     encore_input.quant = !codec->fix_bitrate ? codec->quantizer : 0;
  940 
  941     if(codec->p_count == 0)
  942     {
  943         codec->p_count[current_field]++;
  944     }
  945     else
  946     {
  947         codec->p_count[current_field]++;
  948         if(codec->p_count[current_field] >= codec->max_key_interval)
  949             codec->p_count[current_field] = 0;
  950     }
  951 
  952     encore(codec->encode_handle[current_field], 
  953         0,  
  954         &encore_input,
  955         &encore_result);
  956     pthread_mutex_unlock(&encode_mutex);
  957 
  958     result = !quicktime_write_data(file, 
  959         codec->work_buffer, 
  960         encore_input.length);
  961     quicktime_update_tables(file,
  962                         trak,
  963                         offset,
  964                         vtrack->current_chunk,
  965                         vtrack->current_position,
  966                         1,
  967                         encore_input.length);
  968 
  969     if(encore_result.isKeyFrame)
  970         quicktime_insert_keyframe(file, file->vtracks[track].current_position, track);
  971 
  972     file->vtracks[track].current_chunk++;
  973 
  974 
  975     return result;
  976 }
  977 
  978 static int set_parameter(quicktime_t *file, 
  979         int track, 
  980         char *key, 
  981         void *value)
  982 {
  983     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  984     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  985 
  986     if(!strcasecmp(key, "divx_bitrate"))
  987         codec->bitrate = *(int*)value;
  988     else
  989     if(!strcasecmp(key, "divx_rc_period"))
  990         codec->rc_period = *(int*)value;
  991     else
  992     if(!strcasecmp(key, "divx_rc_reaction_ratio"))
  993         codec->rc_reaction_ratio = *(int*)value;
  994     else
  995     if(!strcasecmp(key, "divx_rc_reaction_period"))
  996         codec->rc_reaction_period = *(int*)value;
  997     else
  998     if(!strcasecmp(key, "divx_max_key_interval"))
  999         codec->max_key_interval = *(int*)value;
 1000     else
 1001     if(!strcasecmp(key, "divx_max_quantizer"))
 1002         codec->max_quantizer = *(int*)value;
 1003     else
 1004     if(!strcasecmp(key, "divx_min_quantizer"))
 1005         codec->min_quantizer = *(int*)value;
 1006     else
 1007     if(!strcasecmp(key, "divx_quantizer"))
 1008         codec->quantizer = *(int*)value;
 1009     else
 1010     if(!strcasecmp(key, "divx_quality"))
 1011         codec->quality = *(int*)value;
 1012     else
 1013     if(!strcasecmp(key, "divx_fix_bitrate"))
 1014         codec->fix_bitrate = *(int*)value;
 1015     else
 1016     if(!strcasecmp(key, "divx_use_deblocking"))
 1017         codec->use_deblocking = *(int*)value;
 1018     return 0;
 1019 }
 1020 
 1021 
 1022 void quicktime_init_codec_divx(quicktime_video_map_t *vtrack)
 1023 {
 1024     quicktime_divx_codec_t *codec;
 1025 
 1026 /* Init public items */
 1027     ((quicktime_codec_t*)vtrack->codec)->priv = calloc(1, sizeof(quicktime_divx_codec_t));
 1028     ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = delete_codec;
 1029     ((quicktime_codec_t*)vtrack->codec)->decode_video = decode;
 1030     ((quicktime_codec_t*)vtrack->codec)->encode_video = encode;
 1031     ((quicktime_codec_t*)vtrack->codec)->reads_colormodel = reads_colormodel;
 1032     ((quicktime_codec_t*)vtrack->codec)->writes_colormodel = writes_colormodel;
 1033     ((quicktime_codec_t*)vtrack->codec)->set_parameter = set_parameter;
 1034     
 1035     codec = ((quicktime_codec_t*)vtrack->codec)->priv;
 1036     
 1037     codec->bitrate = 1000000;
 1038     codec->rc_period = 50;
 1039     codec->rc_reaction_ratio = 45;
 1040     codec->rc_reaction_period = 10;
 1041     codec->max_key_interval = 45;
 1042     codec->max_quantizer = 31;
 1043     codec->min_quantizer = 1;
 1044     codec->quantizer = 10;
 1045     codec->quality = 5;
 1046     codec->fix_bitrate = 1;
 1047     codec->total_fields = 1;
 1048 }
 1049 
 1050 void quicktime_init_codec_hv60(quicktime_video_map_t *vtrack)
 1051 {
 1052     quicktime_init_codec_divx(vtrack);
 1053     quicktime_divx_codec_t *codec;
 1054     
 1055     codec = ((quicktime_codec_t*)vtrack->codec)->priv;
 1056     
 1057     codec->total_fields = 2;
 1058 }
 1059