1 #include "colormodels.h"
2 #include "funcprotos.h"
8 unsigned char *work_buffer;
15 } quicktime_yuv4_codec_t;
17 static void quicktime_delete_codec_yuv4(quicktime_video_map_t *vtrack)
19 quicktime_yuv4_codec_t *codec;
21 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
22 if(codec->work_buffer) free(codec->work_buffer);
23 if(codec->rows) free(codec->rows);
27 static void convert_encode_yuv4(quicktime_yuv4_codec_t *codec)
30 unsigned char *outp = codec->work_buffer;
31 for(y = 0; y < codec->coded_h; y+=2) {
32 int y1 = y+1 >= codec->coded_h ? y : y+1;
33 unsigned char *row0 = codec->work_buffer + y * codec->bytes_per_line;
34 unsigned char *row1 = codec->work_buffer + y1 * codec->bytes_per_line;
35 for(x = 0; x < codec->bytes_per_line; x+=2) {
36 int y00 = *row0++, u = *row0++, v = *row0++;
37 int y01 = *row0++; u += *row0++, v += *row0++;
38 int y10 = *row1++; u += *row1++, v += *row1++;
39 int y11 = *row1++; u += *row1++, v += *row1++;
40 *outp++ = u/4; *outp++ = v/4;
41 *outp++ = y00; *outp++ = y01;
42 *outp++ = y10; *outp++ = y11;
47 static void convert_decode_yuv4(quicktime_yuv4_codec_t *codec)
50 unsigned char *inp = codec->work_buffer;
51 for(y = 0; y < codec->coded_h; y+=2) {
52 int y1 = y+1 >= codec->coded_h ? y : y+1;
53 unsigned char *row0 = codec->work_buffer + y * codec->bytes_per_line;
54 unsigned char *row1 = codec->work_buffer + y1 * codec->bytes_per_line;
55 for(x = 0; x < codec->bytes_per_line; ) {
56 int u = *inp++, v = *inp++;
57 int y00 = *inp++, y01 = *inp++;
58 int y10 = *inp++, y11 = *inp++;
59 *row0++ = y00; *row0++ = u; *row0++ = v;
60 *row0++ = y01; *row0++ = u; *row0++ = v;
61 *row1++ = y10; *row1++ = u; *row1++ = v;
62 *row1++ = y11; *row1++ = u; *row1++ = v;
68 static void initialize(quicktime_video_map_t *vtrack, quicktime_yuv4_codec_t *codec,
69 int width, int height)
71 if(!codec->initialized)
74 /* Init private items */
75 codec->coded_w = (int)((float)width / 4 + 0.5) * 4;
76 // codec->coded_h = (int)((float)vtrack->track->tkhd.track_height / 4 + 0.5) * 4;
77 codec->coded_h = height;
78 codec->bytes_per_line = codec->coded_w * 2;
79 codec->work_buffer = malloc(codec->bytes_per_line * codec->coded_h);
80 codec->rows = malloc(height * sizeof(*(codec->rows)));
81 for(y = 0; y < height; y++)
82 codec->rows[y] = &codec->work_buffer[y * codec->bytes_per_line];
83 codec->initialized = 1;
87 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
90 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
91 quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
92 int width = quicktime_video_width(file, track);
93 int height = quicktime_video_height(file, track);
96 initialize(vtrack, codec, width, height);
97 quicktime_set_video_position(file, vtrack->current_position, track);
98 bytes = quicktime_frame_size(file, vtrack->current_position, track);
100 result = !quicktime_read_data(file, (char*)codec->work_buffer, bytes);
101 convert_decode_yuv4(codec);
103 cmodel_transfer(row_pointers, codec->rows,
104 row_pointers[0], row_pointers[1], row_pointers[2],
106 file->in_x, file->in_y, file->in_w, file->in_h,
107 0, 0, file->out_w, file->out_h,
108 BC_YUV888, file->color_model,
109 0, codec->coded_w, file->out_w);
114 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
117 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
118 quicktime_trak_t *trak = vtrack->track;
119 quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
121 int width = vtrack->track->tkhd.track_width;
122 int height = vtrack->track->tkhd.track_height;
123 quicktime_atom_t chunk_atom;
124 initialize(vtrack, codec, width, height);
125 bytes = height * codec->bytes_per_line;
127 cmodel_transfer(codec->rows, row_pointers,
129 row_pointers[0], row_pointers[1], row_pointers[2],
132 file->color_model, BC_YUV888,
133 0, width, codec->coded_w);
135 convert_encode_yuv4(codec);
137 quicktime_write_chunk_header(file, trak, &chunk_atom);
138 result = !quicktime_write_data(file, (char*)codec->work_buffer, bytes);
139 quicktime_write_chunk_footer(file, trak,
140 vtrack->current_chunk, &chunk_atom, 1);
142 vtrack->current_chunk++;
146 static int reads_colormodel(quicktime_t *file,
151 return (colormodel == BC_RGB888 ||
152 colormodel == BC_YUV888 ||
153 colormodel == BC_YUV422P ||
154 colormodel == BC_YUV422);
157 static int writes_colormodel(quicktime_t *file,
162 return (colormodel == BC_RGB888 ||
163 colormodel == BC_YUV888 ||
164 colormodel == BC_YUV422P ||
165 colormodel == BC_YUV422);
169 void quicktime_init_codec_yuv4(quicktime_video_map_t *vtrack)
171 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
173 /* Init public items */
174 codec_base->priv = calloc(1, sizeof(quicktime_yuv4_codec_t));
175 codec_base->delete_vcodec = quicktime_delete_codec_yuv4;
176 codec_base->decode_video = decode;
177 codec_base->encode_video = encode;
178 codec_base->decode_audio = 0;
179 codec_base->encode_audio = 0;
180 codec_base->reads_colormodel = reads_colormodel;
181 codec_base->writes_colormodel = writes_colormodel;
182 codec_base->fourcc = QUICKTIME_YUV4;
183 codec_base->title = "YUV 4:2:0 packed";
184 codec_base->desc = "YUV 4:2:0 packed (Not standardized)";