"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/yuv2.c" (9 Jan 2007, 9030 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 "yuv2.h"
    5 
    6 /* U V values are signed but Y R G B values are unsigned! */
    7 /*
    8  *      R = Y               + 1.40200 * V
    9  *      G = Y - 0.34414 * U - 0.71414 * V
   10  *      B = Y + 1.77200 * U
   11  */
   12 
   13 /*
   14  *      Y =  0.2990 * R + 0.5870 * G + 0.1140 * B
   15  *      U = -0.1687 * R - 0.3310 * G + 0.5000 * B
   16  *      V =  0.5000 * R - 0.4187 * G - 0.0813 * B  
   17  */
   18 
   19 
   20 typedef struct
   21 {
   22     unsigned char *work_buffer;
   23     int coded_w, coded_h;
   24 
   25 /* The YUV2 codec requires a bytes per line that is a multiple of 4 */
   26     int bytes_per_line;
   27     int initialized;
   28 
   29         int is_2vuy;
   30         uint8_t ** rows;
   31   } quicktime_yuv2_codec_t;
   32 
   33 static int quicktime_delete_codec_yuv2(quicktime_video_map_t *vtrack)
   34 {
   35     quicktime_yuv2_codec_t *codec;
   36 
   37     codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   38     if(codec->work_buffer) free(codec->work_buffer);
   39         if(codec->rows) free(codec->rows);
   40         free(codec);
   41     return 0;
   42 }
   43 #if 0
   44 static int quicktime_reads_colormodel_yuv2(quicktime_t *file, 
   45         int colormodel, 
   46         int track)
   47 {
   48     return (colormodel == BC_RGB888 ||
   49         colormodel == BC_YUV888 ||
   50         colormodel == BC_YUV422P);
   51 }
   52 #endif
   53 
   54 static void convert_encode_yuv2(quicktime_yuv2_codec_t *codec, unsigned char **row_pointers)
   55 {
   56     int y, x;
   57     for(y = 0; y < codec->coded_h; y++)
   58     {
   59         unsigned char *out_row = codec->work_buffer + y * codec->bytes_per_line;
   60         unsigned char *in_row = row_pointers[y];
   61         for(x = 0; x < codec->bytes_per_line; )
   62         {
   63             *out_row++ = *in_row++;
   64             *out_row++ = (int)(*in_row++) - 128;
   65             *out_row++ = *in_row++;
   66             *out_row++ = (int)(*in_row++) - 128;
   67             x += 4;
   68         }
   69     }
   70 }
   71 
   72 static void convert_decode_yuv2(quicktime_yuv2_codec_t *codec, unsigned char **row_pointers)
   73 {
   74     int y, x;
   75     for(y = 0; y < codec->coded_h; y++)
   76     {
   77         unsigned char *in_row = row_pointers[y];
   78         for(x = 0; x < codec->bytes_per_line; )
   79         {
   80             in_row[1] += 128;
   81             in_row[3] += 128;
   82             x += 4;
   83             in_row += 4;
   84         }
   85     }
   86 }
   87 
   88 static void convert_encode_2vuy(quicktime_yuv2_codec_t *codec, unsigned char **row_pointers)
   89 {
   90     int y, x;
   91     for(y = 0; y < codec->coded_h; y++)
   92     {
   93         unsigned char *out_row = codec->work_buffer + y * codec->bytes_per_line;
   94         unsigned char *in_row = row_pointers[y];
   95         for(x = 0; x < codec->bytes_per_line; )
   96         {
   97                         out_row[0] = in_row[1]; /* Y */
   98             out_row[1] = in_row[0]; /* U */
   99             out_row[2] = in_row[3]; /* Y */
  100             out_row[3] = in_row[2]; /* V */
  101             x += 4;
  102                         out_row += 4;
  103                         in_row += 4;
  104         }
  105     }
  106 }
  107 
  108 static void convert_decode_2vuy(quicktime_yuv2_codec_t *codec, unsigned char **row_pointers)
  109 {
  110         uint8_t swap;
  111         int y, x;
  112     for(y = 0; y < codec->coded_h; y++)
  113     {
  114         unsigned char *in_row = row_pointers[y];
  115         for(x = 0; x < codec->bytes_per_line; )
  116         {
  117                         swap = in_row[0];
  118                         in_row[0] = in_row[1];
  119                         in_row[1] = swap;
  120 
  121                         swap = in_row[2];
  122                         in_row[2] = in_row[3];
  123                         in_row[3] = swap;
  124                         
  125                         x += 4;
  126             in_row += 4;
  127         }
  128     }
  129 }
  130 
  131 
  132 static void initialize(quicktime_video_map_t *vtrack, quicktime_yuv2_codec_t *codec,
  133                        int width, int height)
  134 {
  135     if(!codec->initialized)
  136     {
  137 /* Init private items */
  138         codec->coded_w = (int)((float)width / 4 + 0.5) * 4;
  139 //      codec->coded_h = (int)((float)vtrack->track->tkhd.track_height / 4 + 0.5) * 4;
  140                 codec->coded_h = height;
  141         codec->bytes_per_line = codec->coded_w * 2;
  142         codec->work_buffer = malloc(codec->bytes_per_line *
  143                                 codec->coded_h);
  144         codec->initialized = 1;
  145     }
  146 }
  147 
  148 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
  149 {
  150     int64_t bytes, y;
  151     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  152     quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  153     int width = quicktime_video_width(file, track);
  154     int height = quicktime_video_height(file, track);
  155     int result = 0;
  156     initialize(vtrack, codec, width, height);
  157     quicktime_set_video_position(file, vtrack->current_position, track);
  158     bytes = quicktime_frame_size(file, vtrack->current_position, track);
  159     if(file->color_model == BC_YUV422 &&
  160         file->in_x == 0 && 
  161         file->in_y == 0 && 
  162         file->in_w == width &&
  163         file->in_h == height &&
  164         file->out_w == width &&
  165         file->out_h == height)
  166     {
  167         result = !quicktime_read_data(file, row_pointers[0], bytes);
  168                 if(codec->is_2vuy)
  169                   convert_decode_2vuy(codec, row_pointers);
  170                 else
  171                   convert_decode_yuv2(codec, row_pointers);
  172     }
  173     else
  174     {
  175         if(!codec->rows)
  176             codec->rows = malloc(height * sizeof(*(codec->rows)));
  177         result = !quicktime_read_data(file, codec->work_buffer, bytes);
  178         for(y = 0; y < height; y++)
  179             codec->rows[y] = &codec->work_buffer[y * codec->bytes_per_line];
  180                 if(codec->is_2vuy)
  181                   convert_decode_2vuy(codec, codec->rows);
  182                 else
  183                   convert_decode_yuv2(codec, codec->rows);
  184 
  185         cmodel_transfer(row_pointers, 
  186             codec->rows,
  187             row_pointers[0],
  188             row_pointers[1],
  189             row_pointers[2],
  190             0,
  191             0,
  192             0,
  193             file->in_x, 
  194             file->in_y, 
  195             file->in_w, 
  196             file->in_h,
  197             0, 
  198             0, 
  199             file->out_w, 
  200             file->out_h,
  201             BC_YUV422, 
  202             file->color_model,
  203             0,
  204             codec->coded_w,
  205             file->out_w);
  206     }
  207 
  208     
  209 
  210     return result;
  211 }
  212 
  213 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  214 {
  215     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  216     quicktime_trak_t *trak = vtrack->track;
  217     quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  218     int result = 1;
  219     int width = vtrack->track->tkhd.track_width;
  220     int height = vtrack->track->tkhd.track_height;
  221     int64_t bytes;
  222     unsigned char *buffer;
  223     int i;
  224     quicktime_atom_t chunk_atom;
  225 
  226     initialize(vtrack, codec, width, height);
  227 
  228     bytes = height * codec->bytes_per_line;
  229     buffer = codec->work_buffer;
  230     if(file->color_model == BC_YUV422)
  231     {
  232                 if(codec->is_2vuy)
  233                   convert_encode_2vuy(codec, row_pointers);
  234                 else
  235                   convert_encode_yuv2(codec, row_pointers);
  236         quicktime_write_chunk_header(file, trak, &chunk_atom);
  237         result = !quicktime_write_data(file, buffer, bytes);
  238     }
  239     else
  240     {
  241         if(!codec->rows)
  242             codec->rows = malloc(height * sizeof(*(codec->rows)));
  243         for(i = 0; i < height; i++)
  244             codec->rows[i] = buffer + i * codec->bytes_per_line;
  245 
  246         cmodel_transfer(codec->rows, 
  247             row_pointers,
  248             0,
  249             0,
  250             0,
  251             row_pointers[0],
  252             row_pointers[1],
  253             row_pointers[2],
  254             0, 
  255             0, 
  256             width, 
  257             height,
  258             0, 
  259             0, 
  260             width, 
  261             height,
  262             file->color_model,
  263             BC_YUV422, 
  264             0,
  265             width,
  266             codec->coded_w);
  267                 if(codec->is_2vuy)
  268                   convert_encode_2vuy(codec, codec->rows);
  269                 else
  270                   convert_encode_yuv2(codec, codec->rows);
  271 
  272         quicktime_write_chunk_header(file, trak, &chunk_atom);
  273         result = !quicktime_write_data(file, buffer, bytes);
  274     }
  275 
  276     quicktime_write_chunk_footer(file, 
  277         trak,
  278         vtrack->current_chunk,
  279         &chunk_atom, 
  280         1);
  281 printf("10\n");
  282 
  283     vtrack->current_chunk++;
  284     return result;
  285 }
  286 
  287 static int reads_colormodel(quicktime_t *file, 
  288         int colormodel, 
  289         int track)
  290 {
  291 
  292     return (colormodel == BC_RGB888 ||
  293         colormodel == BC_YUV888 ||
  294         colormodel == BC_YUV422P ||
  295         colormodel == BC_YUV422);
  296 }
  297 
  298 static int writes_colormodel(quicktime_t *file, 
  299         int colormodel, 
  300         int track)
  301 {
  302 
  303     return (colormodel == BC_RGB888 ||
  304         colormodel == BC_YUV888 ||
  305         colormodel == BC_YUV422P ||
  306         colormodel == BC_YUV422);
  307 }
  308 
  309 void quicktime_init_codec_yuv2(quicktime_video_map_t *vtrack)
  310 {
  311     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  312 
  313 /* Init public items */
  314     codec_base->priv = calloc(1, sizeof(quicktime_yuv2_codec_t));
  315     codec_base->delete_vcodec = quicktime_delete_codec_yuv2;
  316     codec_base->decode_video = decode;
  317     codec_base->encode_video = encode;
  318     codec_base->decode_audio = 0;
  319     codec_base->encode_audio = 0;
  320     codec_base->reads_colormodel = reads_colormodel;
  321     codec_base->writes_colormodel = writes_colormodel;
  322     codec_base->fourcc = QUICKTIME_YUV2;
  323     codec_base->title = "Component Y'CbCr 8-bit 4:2:2 (yuv2)";
  324     codec_base->desc = "YUV 4:2:2";
  325 }
  326 
  327 void quicktime_init_codec_2vuy(quicktime_video_map_t *vtrack)
  328 {
  329     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  330         quicktime_yuv2_codec_t * codec;
  331 /* Init public items */
  332     codec_base->priv = calloc(1, sizeof(quicktime_yuv2_codec_t));
  333     codec_base->delete_vcodec = quicktime_delete_codec_yuv2;
  334     codec_base->decode_video = decode;
  335     codec_base->encode_video = encode;
  336     codec_base->decode_audio = 0;
  337     codec_base->encode_audio = 0;
  338     codec_base->reads_colormodel = reads_colormodel;
  339     codec_base->writes_colormodel = writes_colormodel;
  340     codec_base->fourcc = "2vuy";
  341     codec_base->title = "Component Y'CbCr 8-bit 4:2:2 (2vuy)";
  342     codec_base->desc = "YUV 4:2:2";
  343         codec = (quicktime_yuv2_codec_t *)(codec_base->priv);
  344         codec->is_2vuy = 1;
  345 }
  346