1 #include "colormodels.h"
2 #include "funcprotos.h"
4 #include "workarounds.h"
10 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
15 cmodel_yuv_t yuv_table;
17 unsigned char *work_buffer;
19 } quicktime_yv12_codec_t;
21 static void delete_codec(quicktime_video_map_t *vtrack)
23 quicktime_yv12_codec_t *codec;
25 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
26 free(codec->work_buffer);
30 static int reads_colormodel(quicktime_t *file,
34 return (colormodel == BC_RGB888 ||
35 colormodel == BC_YUV888 ||
36 colormodel == BC_YUV420P);
39 static int writes_colormodel(quicktime_t *file,
43 return (colormodel == BC_YUV420P);
46 static void initialize(quicktime_video_map_t *vtrack)
48 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
49 quicktime_yv12_codec_t *codec = codec_base->priv;
50 if(!codec->initialized)
52 /* Init private items */
53 codec->coded_w = (int)(vtrack->track->tkhd.track_width / 2);
55 codec->coded_h = (int)(vtrack->track->tkhd.track_height / 2);
57 cmodel_init_yuv(&codec->yuv_table);
58 codec->work_buffer = malloc(codec->coded_w * codec->coded_h +
59 codec->coded_w * codec->coded_h / 2);
60 codec->initialized = 1;
64 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
66 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
67 quicktime_yv12_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
68 int width = vtrack->track->tkhd.track_width;
69 int height = vtrack->track->tkhd.track_height;
70 int64_t y_size, u_size, v_size, bytes;
74 y_size = codec->coded_h * codec->coded_w;
75 u_size = codec->coded_h * codec->coded_w / 4;
76 v_size = codec->coded_h * codec->coded_w / 4;
78 quicktime_set_video_position(file, vtrack->current_position, track);
79 bytes = quicktime_frame_size(file, vtrack->current_position, track);
82 if(file->color_model == BC_YUV420P &&
85 file->in_w == width &&
86 file->in_h == height &&
87 file->out_w == width &&
88 file->out_h == height)
90 result = !quicktime_read_data(file, (char*)row_pointers[0], y_size);
91 result = !quicktime_read_data(file, (char*)row_pointers[1], u_size);
92 result = !quicktime_read_data(file, (char*)row_pointers[2], v_size);
96 result = !quicktime_read_data(file, (char*)codec->work_buffer, bytes);
97 cmodel_transfer(row_pointers,
103 codec->work_buffer + y_size,
104 codec->work_buffer + y_size + u_size,
123 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
125 // int64_t offset = quicktime_position(file);
126 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
127 quicktime_yv12_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
128 quicktime_trak_t *trak = vtrack->track;
130 int width = vtrack->track->tkhd.track_width;
131 int height = vtrack->track->tkhd.track_height;
132 int64_t y_size, u_size, v_size, bytes;
133 quicktime_atom_t chunk_atom;
136 y_size = codec->coded_h * codec->coded_w;
137 u_size = codec->coded_h * codec->coded_w / 4;
138 v_size = codec->coded_h * codec->coded_w / 4;
139 bytes = quicktime_add3(y_size, u_size, v_size);
141 quicktime_write_chunk_header(file, trak, &chunk_atom);
142 if(file->color_model == BC_YUV420P)
144 result = !quicktime_write_data(file, (char*)row_pointers[0], y_size);
145 if(!result) result = !quicktime_write_data(file, (char*)row_pointers[1], u_size);
146 if(!result) result = !quicktime_write_data(file, (char*)row_pointers[2], v_size);
153 codec->work_buffer + y_size,
154 codec->work_buffer + y_size + u_size,
171 result = !quicktime_write_data(file, (char*)codec->work_buffer, bytes);
174 quicktime_write_chunk_footer(file,
176 vtrack->current_chunk,
180 vtrack->current_chunk++;
184 void quicktime_init_codec_yv12(quicktime_video_map_t *vtrack)
186 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
188 /* Init public items */
189 codec_base->priv = calloc(1, sizeof(quicktime_yv12_codec_t));
190 codec_base->delete_vcodec = delete_codec;
191 codec_base->decode_video = decode;
192 codec_base->encode_video = encode;
193 codec_base->decode_audio = 0;
194 codec_base->encode_audio = 0;
195 codec_base->reads_colormodel = reads_colormodel;
196 codec_base->writes_colormodel = writes_colormodel;
197 codec_base->fourcc = QUICKTIME_YUV420;
198 codec_base->title = "YUV 4:2:0 Planar";
199 codec_base->desc = "YUV 4:2:0 Planar";