"Fossies" - the Fresh Open Source Software Archive

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