applied AkhIL's cinelerra-cv surround patch
[cinelerra_cv/ct.git] / quicktime / yv12.c
blob8c1e07f44e8500e01e22dd1c229b4aa0dd624dd9
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
4 #include "workarounds.h"
5 #include "yv12.h"
7 #include <stdlib.h>
9 #ifndef CLAMP
10 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
11 #endif
13 typedef struct
15 cmodel_yuv_t yuv_table;
16 int coded_w, coded_h;
17 unsigned char *work_buffer;
18 int initialized;
19 } quicktime_yv12_codec_t;
21 static int 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);
27 free(codec);
28 return 0;
31 static int reads_colormodel(quicktime_t *file,
32 int colormodel,
33 int track)
35 return (colormodel == BC_RGB888 ||
36 colormodel == BC_YUV888 ||
37 colormodel == BC_YUV420P);
40 static int writes_colormodel(quicktime_t *file,
41 int colormodel,
42 int track)
44 return (colormodel == BC_YUV420P);
47 static void initialize(quicktime_video_map_t *vtrack)
49 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
50 quicktime_yv12_codec_t *codec = codec_base->priv;
51 if(!codec->initialized)
53 /* Init private items */
54 codec->coded_w = (int)(vtrack->track->tkhd.track_width / 2);
55 codec->coded_w *= 2;
56 codec->coded_h = (int)(vtrack->track->tkhd.track_height / 2);
57 codec->coded_h *= 2;
58 cmodel_init_yuv(&codec->yuv_table);
59 codec->work_buffer = malloc(codec->coded_w * codec->coded_h +
60 codec->coded_w * codec->coded_h / 2);
61 codec->initialized = 1;
65 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
67 int64_t bytes, x, y;
68 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
69 quicktime_yv12_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
70 int width = vtrack->track->tkhd.track_width;
71 int height = vtrack->track->tkhd.track_height;
72 unsigned char *buffer;
73 unsigned char *output_row0, *output_row1, *y_plane0, *y_plane1, *u_plane, *v_plane;
74 int64_t y_size, u_size, v_size;
75 int result = 0;
76 int y1, u, v, y2, r, g, b, y3, y4;
77 int i;
78 int bytes_per_row = width * cmodel_calculate_pixelsize(file->color_model);
79 initialize(vtrack);
81 y_size = codec->coded_h * codec->coded_w;
82 u_size = codec->coded_h * codec->coded_w / 4;
83 v_size = codec->coded_h * codec->coded_w / 4;
85 vtrack->track->tkhd.track_width;
86 quicktime_set_video_position(file, vtrack->current_position, track);
87 bytes = quicktime_frame_size(file, vtrack->current_position, track);
90 if(file->color_model == BC_YUV420P &&
91 file->in_x == 0 &&
92 file->in_y == 0 &&
93 file->in_w == width &&
94 file->in_h == height &&
95 file->out_w == width &&
96 file->out_h == height)
98 result = !quicktime_read_data(file, row_pointers[0], y_size);
99 result = !quicktime_read_data(file, row_pointers[1], u_size);
100 result = !quicktime_read_data(file, row_pointers[2], v_size);
102 else
104 result = !quicktime_read_data(file, codec->work_buffer, bytes);
105 cmodel_transfer(row_pointers,
107 row_pointers[0],
108 row_pointers[1],
109 row_pointers[2],
110 codec->work_buffer,
111 codec->work_buffer + y_size,
112 codec->work_buffer + y_size + u_size,
113 file->in_x,
114 file->in_y,
115 file->in_w,
116 file->in_h,
119 file->out_w,
120 file->out_h,
121 BC_YUV420P,
122 file->color_model,
124 codec->coded_w,
125 file->out_w);
128 return result;
131 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
133 int64_t offset = quicktime_position(file);
134 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
135 quicktime_yv12_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
136 quicktime_trak_t *trak = vtrack->track;
137 int result = 0;
138 int width = vtrack->track->tkhd.track_width;
139 int height = vtrack->track->tkhd.track_height;
140 unsigned char *y_plane0, *y_plane1, *u_plane, *v_plane;
141 int64_t y_size, u_size, v_size;
142 unsigned char *input_row0, *input_row1;
143 int x, y;
144 int y1, u, y2, v, y3, y4, subscript;
145 int r, g, b;
146 int64_t bytes = (int64_t)0;
147 quicktime_atom_t chunk_atom;
148 initialize(vtrack);
150 y_size = codec->coded_h * codec->coded_w;
151 u_size = codec->coded_h * codec->coded_w / 4;
152 v_size = codec->coded_h * codec->coded_w / 4;
153 bytes = quicktime_add3(y_size, u_size, v_size);
155 quicktime_write_chunk_header(file, trak, &chunk_atom);
156 if(file->color_model == BC_YUV420P)
158 result = !quicktime_write_data(file, row_pointers[0], y_size);
159 if(!result) result = !quicktime_write_data(file, row_pointers[1], u_size);
160 if(!result) result = !quicktime_write_data(file, row_pointers[2], v_size);
162 else
164 cmodel_transfer(0,
165 row_pointers,
166 codec->work_buffer,
167 codec->work_buffer + y_size,
168 codec->work_buffer + y_size + u_size,
169 row_pointers[0],
170 row_pointers[1],
171 row_pointers[2],
174 width,
175 height,
178 width,
179 height,
180 file->color_model,
181 BC_YUV420P,
183 width,
184 codec->coded_w);
185 result = !quicktime_write_data(file, codec->work_buffer, bytes);
188 quicktime_write_chunk_footer(file,
189 trak,
190 vtrack->current_chunk,
191 &chunk_atom,
194 vtrack->current_chunk++;
195 return result;
198 void quicktime_init_codec_yv12(quicktime_video_map_t *vtrack)
200 int i;
201 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
203 /* Init public items */
204 codec_base->priv = calloc(1, sizeof(quicktime_yv12_codec_t));
205 codec_base->delete_vcodec = delete_codec;
206 codec_base->decode_video = decode;
207 codec_base->encode_video = encode;
208 codec_base->decode_audio = 0;
209 codec_base->encode_audio = 0;
210 codec_base->reads_colormodel = reads_colormodel;
211 codec_base->fourcc = QUICKTIME_YUV420;
212 codec_base->title = "YUV 4:2:0 Planar";
213 codec_base->desc = "YUV 4:2:0 Planar";