"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/divx.c.2" (9 Jan 2007, 10480 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 #include "colormodels.h"
    2 #include "funcprotos.h"
    3 #include "quicktime.h"
    4 #include "workarounds.h"
    5 #include "divx.h"
    6 
    7 
    8 #include <stdint.h>
    9 #include <stdlib.h>
   10 
   11 
   12 static pthread_mutex_t encode_mutex;
   13 static pthread_mutex_t decode_mutex;
   14 static int mutex_initialized = 0;
   15 
   16 static int delete_codec(quicktime_video_map_t *vtrack)
   17 {
   18     quicktime_divx_codec_t *codec;
   19 
   20     codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   21     if(codec->encode_initialized)
   22     {
   23         pthread_mutex_lock(&encode_mutex);
   24         encore(codec->enc_param.handle,
   25             ENC_OPT_RELEASE,
   26             0,
   27             0);
   28         pthread_mutex_unlock(&encode_mutex);
   29     }
   30     if(codec->decode_initialized)
   31     {
   32         pthread_mutex_lock(&decode_mutex);
   33         decore(codec->dec_param.handle,
   34             DEC_OPT_DESTROY,
   35             0,
   36             0);
   37         pthread_mutex_unlock(&decode_mutex);
   38     }
   39     if(codec->temp_frame) free(codec->temp_frame);
   40     if(codec->work_buffer) free(codec->work_buffer);
   41     free(codec);
   42     return 0;
   43 }
   44 
   45 static int reads_colormodel(quicktime_t *file, 
   46         int colormodel, 
   47         int track)
   48 {
   49     return (colormodel == BC_RGB888 ||
   50         colormodel == BC_RGBA8888 ||
   51         colormodel == BC_RGB161616 ||
   52         colormodel == BC_RGBA16161616 ||
   53         colormodel == BC_YUV888 ||
   54         colormodel == BC_YUVA8888 ||
   55         colormodel == BC_YUV161616 ||
   56         colormodel == BC_YUVA16161616 ||
   57         colormodel == BC_RGB8 ||
   58         colormodel == BC_RGB565 ||
   59         colormodel == BC_BGR888 ||
   60         colormodel == BC_BGR8888 ||
   61         colormodel == BC_YUV420P ||
   62         colormodel == BC_YUV422);
   63 }
   64 
   65 static int writes_colormodel(quicktime_t *file, 
   66         int colormodel, 
   67         int track)
   68 {
   69     return (colormodel == BC_RGB888 ||
   70         colormodel == BC_RGBA8888 ||
   71         colormodel == BC_RGB161616 ||
   72         colormodel == BC_RGBA16161616 ||
   73         colormodel == BC_YUV888 ||
   74         colormodel == BC_YUVA8888 ||
   75         colormodel == BC_YUV161616 ||
   76         colormodel == BC_YUVA16161616 ||
   77         colormodel == BC_YUV420P ||
   78         colormodel == BC_YUV422);
   79 }
   80 
   81 
   82 
   83 
   84 
   85 
   86 
   87 
   88 static void init_mutex()
   89 {
   90     if(!mutex_initialized)
   91     {
   92         pthread_mutexattr_t attr;
   93         mutex_initialized = 1;
   94         pthread_mutexattr_init(&attr);
   95         pthread_mutex_init(&decode_mutex, &attr);
   96         pthread_mutex_init(&encode_mutex, &attr);
   97     }
   98 }
   99 
  100 
  101 
  102 
  103 
  104 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
  105 {
  106     int i;
  107     longest bytes;
  108     int result = 0;
  109     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  110     quicktime_trak_t *trak = vtrack->track;
  111     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  112     int width = trak->tkhd.track_width;
  113     int height = trak->tkhd.track_height;
  114     int width_i = (int)((float)width / 2 + 0.5) * 2;
  115     int height_i = (int)((float)height / 2 + 0.5) * 2;
  116     DEC_FRAME dec_frame;
  117     int use_temp = 0;
  118     int input_cmodel;
  119     char *bmp_pointers[3];
  120 
  121 //printf("decode 1\n");
  122 
  123     init_mutex();
  124     pthread_mutex_lock(&decode_mutex);
  125 
  126     quicktime_set_video_position(file, vtrack->current_position, track);
  127     bytes = quicktime_frame_size(file, vtrack->current_position, track);
  128 //printf("decode 1\n");
  129 
  130     if(!codec->work_buffer || codec->buffer_size < bytes)
  131     {
  132         if(codec->work_buffer) free(codec->work_buffer);
  133         codec->buffer_size = bytes;
  134         codec->work_buffer = calloc(1, codec->buffer_size + 100);
  135     }
  136 //printf("decode 1\n");
  137 
  138     result = !quicktime_read_data(file, codec->work_buffer, bytes);
  139 //printf("decode 1\n");
  140 
  141     if(!codec->decode_initialized)
  142     {
  143         codec->decode_initialized = 1;
  144         codec->dec_param.width = width_i;
  145         codec->dec_param.height = height_i;
  146         decore(0, DEC_OPT_CREATE, &codec->dec_param, NULL);
  147 
  148 
  149     }
  150 
  151 //printf("decode 1\n");
  152 
  153 
  154 
  155     dec_frame.bitstream = codec->work_buffer;
  156     dec_frame.length = bytes;
  157     dec_frame.stride = width_i;
  158     dec_frame.render = 1;
  159     dec_frame.colorspace = DEC_CSP_YV12;
  160 
  161     input_cmodel = BC_YUV420P;
  162     if(file->color_model == input_cmodel &&
  163         file->out_w == width_i &&
  164         file->out_h == height_i &&
  165         file->in_x == 0 &&
  166         file->in_y == 0 &&
  167         file->in_w == width_i &&
  168         file->in_h == height_i)
  169     {
  170         dec_frame.dst = row_pointers[0];
  171         use_temp = 0;
  172     }
  173     else
  174     {
  175         if(!codec->temp_frame)
  176         {
  177             codec->temp_frame = malloc(width_i * height_i * 3 / 2);
  178         }
  179         dec_frame.dst = codec->temp_frame;
  180         use_temp = 1;
  181     }
  182 
  183 
  184 //printf("decode 1\n");
  185     decore(codec->dec_param.handle, DEC_OPT_DECODE, &dec_frame, NULL);
  186 //printf("decode 2\n");
  187 
  188 
  189     pthread_mutex_unlock(&decode_mutex);
  190 //printf("decode 1 %d %d\n", use_temp, file->color_model);
  191 
  192     if(use_temp)
  193     {
  194         unsigned char **input_rows = malloc(sizeof(unsigned char*) * height_i);
  195         for(i = 0; i < height_i; i++)
  196             input_rows[i] = (char*)codec->temp_frame + width_i * 3;
  197 //printf("decode 3\n");
  198         
  199         
  200         cmodel_transfer(row_pointers, /* Leave NULL if non existent */
  201             input_rows,
  202             row_pointers[0], /* Leave NULL if non existent */
  203             row_pointers[1],
  204             row_pointers[2],
  205             codec->temp_frame, /* Leave NULL if non existent */
  206             codec->temp_frame + width_i * height_i,
  207             codec->temp_frame + width_i * height_i + width_i * height_i / 4,
  208             file->in_x,        /* Dimensions to capture from input frame */
  209             file->in_y, 
  210             file->in_w, 
  211             file->in_h,
  212             0,       /* Dimensions to project on output frame */
  213             0, 
  214             file->out_w, 
  215             file->out_h,
  216             input_cmodel, 
  217             file->color_model,
  218             0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
  219             width_i,       /* For planar use the luma rowspan */
  220             width);
  221         
  222 //printf("decode 4\n");
  223         free(input_rows);
  224     }
  225 
  226 
  227 
  228 
  229 //printf("decode 2\n");
  230 
  231     return result;
  232 }
  233 
  234 
  235 
  236 
  237 
  238 
  239 
  240 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  241 {
  242 //printf("encode 1\n");
  243     longest offset = quicktime_position(file);
  244     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  245     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  246     quicktime_trak_t *trak = vtrack->track;
  247     int width = trak->tkhd.track_width;
  248     int height = trak->tkhd.track_height;
  249     int width_i = (int)((float)width / 2 + 0.5) * 2;
  250     int height_i = (int)((float)height / 2 + 0.5) * 2;
  251     int result = 0;
  252     int i;
  253     ENC_FRAME encore_input;
  254     ENC_RESULT encore_result;
  255 //printf("encode 1\n");
  256 
  257     init_mutex();
  258     pthread_mutex_lock(&encode_mutex);
  259 
  260     if(!codec->encode_initialized)
  261     {
  262         codec->encode_initialized = 1;
  263         codec->enc_param.x_dim = width_i;
  264         codec->enc_param.y_dim = height_i;
  265         codec->enc_param.framerate = quicktime_frame_rate(file, track);
  266         codec->enc_param.bitrate = codec->bitrate;
  267         codec->enc_param.rc_period = codec->rc_period;
  268         codec->enc_param.rc_reaction_period = codec->rc_reaction_period;
  269         codec->enc_param.rc_reaction_ratio = codec->rc_reaction_ratio;
  270         codec->enc_param.max_quantizer = codec->max_quantizer;
  271         codec->enc_param.min_quantizer = codec->min_quantizer;
  272         codec->enc_param.max_key_interval = codec->max_key_interval;
  273         codec->enc_param.use_bidirect = 0;
  274         codec->enc_param.deinterlace = 0;
  275         codec->enc_param.quality = 5;
  276         codec->enc_param.obmc = 0;
  277         
  278 
  279 
  280         encore(0, ENC_OPT_INIT, &codec->enc_param, NULL);
  281     }
  282 
  283 //printf("encode 1\n");
  284 
  285 // Assume planes are contiguous
  286     if(file->color_model == BC_YUV420P &&
  287         width == width_i &&
  288         height == height_i)
  289     {
  290         encore_input.image = row_pointers[0];
  291 //printf("encode 1\n");
  292     }
  293 // Convert to YUV420P
  294     else
  295     {
  296 //printf("encode 2\n");
  297         if(!codec->temp_frame)
  298         {
  299             codec->temp_frame = malloc(width_i * height_i * 3 / 2);
  300         }
  301 //printf("encode 2 %d %d %d %d %d %d\n", file->color_model, width, height, width_i, height_i);
  302 
  303         cmodel_transfer(0, /* Leave NULL if non existent */
  304             row_pointers,
  305             codec->temp_frame, /* Leave NULL if non existent */
  306             codec->temp_frame + width_i * height_i,
  307             codec->temp_frame + width_i * height_i + width_i * height_i / 4,
  308             row_pointers[0], /* Leave NULL if non existent */
  309             row_pointers[1],
  310             row_pointers[2],
  311             0,        /* Dimensions to capture from input frame */
  312             0, 
  313             width, 
  314             height,
  315             0,       /* Dimensions to project on output frame */
  316             0, 
  317             width_i, 
  318             height_i,
  319             file->color_model, 
  320             BC_YUV420P,
  321             0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
  322             width,       /* For planar use the luma rowspan */
  323             width_i);
  324         
  325 //printf("encode 2\n");
  326     
  327         encore_input.image = codec->temp_frame;
  328     }
  329 //printf("encode 1\n");
  330 
  331     if(!codec->work_buffer)
  332     {
  333         codec->buffer_size = width * height;
  334         codec->work_buffer = malloc(codec->buffer_size);
  335     }
  336 //printf("encode 1\n");
  337 
  338     encore_input.bitstream = codec->work_buffer;
  339     encore_input.length = codec->buffer_size;
  340     encore_input.colorspace = ENC_CSP_YV12;
  341     encore_input.quant = codec->enc_param.min_quantizer;
  342 
  343 //printf("encode 1\n");
  344     encore(codec->enc_param.handle, 
  345             ENC_OPT_ENCODE, 
  346             &encore_input,
  347             &encore_result);
  348     pthread_mutex_unlock(&encode_mutex);
  349 //printf("encode 1\n");
  350 
  351     result = !quicktime_write_data(file, codec->work_buffer, encore_input.length);
  352     quicktime_update_tables(file,
  353                         file->vtracks[track].track,
  354                         offset,
  355                         file->vtracks[track].current_chunk,
  356                         file->vtracks[track].current_position,
  357                         1,
  358                         encore_input.length);
  359 //printf("encode 1\n");
  360 
  361     file->vtracks[track].current_chunk++;
  362 //printf("encode 2\n");
  363 
  364     return result;
  365 }
  366 
  367 static int set_parameter(quicktime_t *file, 
  368         int track, 
  369         char *key, 
  370         void *value)
  371 {
  372     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  373     quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  374 
  375     if(!strcasecmp(key, "v_bitrate"))
  376         codec->bitrate = *(int*)value;
  377     else
  378     if(!strcasecmp(key, "v_rc_period"))
  379         codec->rc_period = *(int*)value;
  380     else
  381     if(!strcasecmp(key, "v_rc_reaction_ratio"))
  382         codec->rc_reaction_ratio = *(int*)value;
  383     else
  384     if(!strcasecmp(key, "v_rc_reaction_period"))
  385         codec->rc_reaction_period = *(int*)value;
  386     else
  387     if(!strcasecmp(key, "v_max_key_interval"))
  388         codec->max_key_interval = *(int*)value;
  389     else
  390     if(!strcasecmp(key, "v_max_quantizer"))
  391         codec->max_quantizer = *(int*)value;
  392     else
  393     if(!strcasecmp(key, "v_min_quantizer"))
  394         codec->min_quantizer = *(int*)value;
  395     else
  396     if(!strcasecmp(key, "v_search_range"))
  397         codec->search_range = *(int*)value;
  398 }
  399 
  400 
  401 void quicktime_init_codec_divx(quicktime_video_map_t *vtrack)
  402 {
  403     int i;
  404     quicktime_divx_codec_t *codec;
  405 
  406 /* Init public items */
  407     ((quicktime_codec_t*)vtrack->codec)->priv = calloc(1, sizeof(quicktime_divx_codec_t));
  408     ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = delete_codec;
  409     ((quicktime_codec_t*)vtrack->codec)->decode_video = decode;
  410     ((quicktime_codec_t*)vtrack->codec)->encode_video = encode;
  411     ((quicktime_codec_t*)vtrack->codec)->reads_colormodel = reads_colormodel;
  412     ((quicktime_codec_t*)vtrack->codec)->writes_colormodel = writes_colormodel;
  413     ((quicktime_codec_t*)vtrack->codec)->set_parameter = set_parameter;
  414 }
  415