1 #include "colormodels.h"
2 #include "funcprotos.h"
6 /* U V values are signed but Y R G B values are unsigned! */
9 * G = Y - 0.34414 * U - 0.71414 * V
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
22 unsigned char *work_buffer;
25 /* The YUV2 codec requires a bytes per line that is a multiple of 4 */
31 } quicktime_yuv2_codec_t;
33 static void quicktime_delete_codec_yuv2(quicktime_video_map_t *vtrack)
35 quicktime_yuv2_codec_t *codec;
37 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
38 if(codec->work_buffer) free(codec->work_buffer);
39 if(codec->rows) free(codec->rows);
43 static int quicktime_reads_colormodel_yuv2(quicktime_t *file,
47 return (colormodel == BC_RGB888 ||
48 colormodel == BC_YUV888 ||
49 colormodel == BC_YUV422P);
53 static void convert_encode_yuv2(quicktime_yuv2_codec_t *codec)
56 for(y = 0; y < codec->coded_h; y++) {
57 unsigned char *row = codec->work_buffer + y * codec->bytes_per_line;
58 for(x = 0; x < codec->bytes_per_line; ) {
67 static void convert_decode_yuv2(quicktime_yuv2_codec_t *codec)
70 for(y = 0; y < codec->coded_h; y++) {
71 unsigned char *row = codec->work_buffer + y * codec->bytes_per_line;
72 for(x = 0; x < codec->bytes_per_line; ) {
81 static void convert_encode_2vuy(quicktime_yuv2_codec_t *codec)
84 for(y = 0; y < codec->coded_h; y++) {
85 unsigned char *row = codec->work_buffer + y * codec->bytes_per_line;
86 for(x = 0; x < codec->bytes_per_line; ) {
87 int y0 = row[0], u = row[1];
88 int y1 = row[2], v = row[3];
89 row[0] = u; row[1] = y0;
90 row[2] = v; row[3] = y1;
97 static void convert_decode_2vuy(quicktime_yuv2_codec_t *codec)
100 for(y = 0; y < codec->coded_h; y++) {
101 unsigned char *row = codec->work_buffer + y * codec->bytes_per_line;
102 for(x = 0; x < codec->bytes_per_line; ) {
103 int u = row[0], y0 = row[1];
104 int v = row[2], y1 = row[3];
105 row[0] = y0; row[1] = u;
106 row[2] = y1; row[3] = v;
114 static void initialize(quicktime_video_map_t *vtrack, quicktime_yuv2_codec_t *codec,
115 int width, int height)
117 if(!codec->initialized)
120 /* Init private items */
121 codec->coded_w = (int)((float)width / 4 + 0.5) * 4;
122 // codec->coded_h = (int)((float)vtrack->track->tkhd.track_height / 4 + 0.5) * 4;
123 codec->coded_h = height;
124 codec->bytes_per_line = codec->coded_w * 2;
125 codec->work_buffer = malloc(codec->bytes_per_line * codec->coded_h);
126 codec->rows = malloc(height * sizeof(*(codec->rows)));
127 for(y = 0; y < height; y++)
128 codec->rows[y] = &codec->work_buffer[y * codec->bytes_per_line];
129 codec->initialized = 1;
133 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
136 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
137 quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
138 int width = quicktime_video_width(file, track);
139 int height = quicktime_video_height(file, track);
142 initialize(vtrack, codec, width, height);
143 quicktime_set_video_position(file, vtrack->current_position, track);
144 bytes = quicktime_frame_size(file, vtrack->current_position, track);
146 result = !quicktime_read_data(file, (char*)codec->work_buffer, bytes);
148 convert_decode_2vuy(codec);
150 convert_decode_yuv2(codec);
152 cmodel_transfer(row_pointers, codec->rows,
153 row_pointers[0], row_pointers[1], row_pointers[2],
155 file->in_x, file->in_y, file->in_w, file->in_h,
156 0, 0, file->out_w, file->out_h,
157 BC_YUV422, file->color_model,
158 0, codec->coded_w, file->out_w);
163 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
166 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
167 quicktime_trak_t *trak = vtrack->track;
168 quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
170 int width = vtrack->track->tkhd.track_width;
171 int height = vtrack->track->tkhd.track_height;
172 quicktime_atom_t chunk_atom;
173 initialize(vtrack, codec, width, height);
174 bytes = height * codec->bytes_per_line;
176 cmodel_transfer(codec->rows, row_pointers,
178 row_pointers[0], row_pointers[1], row_pointers[2],
181 file->color_model, BC_YUV422,
182 0, width, codec->coded_w);
185 convert_encode_2vuy(codec);
187 convert_encode_yuv2(codec);
189 quicktime_write_chunk_header(file, trak, &chunk_atom);
190 result = !quicktime_write_data(file, (char*)codec->work_buffer, bytes);
191 quicktime_write_chunk_footer(file, trak,
192 vtrack->current_chunk, &chunk_atom, 1);
194 vtrack->current_chunk++;
198 static int reads_colormodel(quicktime_t *file,
203 return (colormodel == BC_RGB888 ||
204 colormodel == BC_YUV888 ||
205 colormodel == BC_YUV422P ||
206 colormodel == BC_YUV422);
209 static int writes_colormodel(quicktime_t *file,
214 return (colormodel == BC_RGB888 ||
215 colormodel == BC_YUV888 ||
216 colormodel == BC_YUV422P ||
217 colormodel == BC_YUV422);
220 void quicktime_init_codec_yuv2(quicktime_video_map_t *vtrack)
222 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
224 /* Init public items */
225 codec_base->priv = calloc(1, sizeof(quicktime_yuv2_codec_t));
226 codec_base->delete_vcodec = quicktime_delete_codec_yuv2;
227 codec_base->decode_video = decode;
228 codec_base->encode_video = encode;
229 codec_base->decode_audio = 0;
230 codec_base->encode_audio = 0;
231 codec_base->reads_colormodel = reads_colormodel;
232 codec_base->writes_colormodel = writes_colormodel;
233 codec_base->fourcc = QUICKTIME_YUV2;
234 codec_base->title = "Component Y'CbCr 8-bit 4:2:2 (yuv2)";
235 codec_base->desc = "YUV 4:2:2";
238 void quicktime_init_codec_2vuy(quicktime_video_map_t *vtrack)
240 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
241 quicktime_yuv2_codec_t * codec;
242 /* Init public items */
243 codec_base->priv = calloc(1, sizeof(quicktime_yuv2_codec_t));
244 codec_base->delete_vcodec = quicktime_delete_codec_yuv2;
245 codec_base->decode_video = decode;
246 codec_base->encode_video = encode;
247 codec_base->decode_audio = 0;
248 codec_base->encode_audio = 0;
249 codec_base->reads_colormodel = reads_colormodel;
250 codec_base->writes_colormodel = writes_colormodel;
251 codec_base->fourcc = QUICKTIME_2VUY;
252 codec_base->title = "Component Y'CbCr 8-bit 4:2:2 (2vuy)";
253 codec_base->desc = "YUV 4:2:2";
254 codec = (quicktime_yuv2_codec_t *)(codec_base->priv);