Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / libmpeg3 / video / output.c
blob1c37d079e99524d61662f748c3bbbc6cab05dd26
1 #include "../libmpeg3.h"
2 #include "mpeg3video.h"
3 #include <string.h>
5 #define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
8 static unsigned char mpeg3_601_to_rgb[256];
10 /* Algorithm */
11 /* r = (int)(*y + 1.371 * (*cr - 128)); */
12 /* g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */
13 /* b = (int)(*y + 1.732 * (*cb - 128)); */
16 #define DITHER_ROW_HEAD \
17 for(h = 0; h < video->out_h; h++) \
18 { \
19 y_in = &src[0][(video->y_table[h] + video->in_y) * \
20 video->coded_picture_width] + \
21 video->in_x; \
22 if(video->chroma_format == CHROMA420) \
23 { \
24 cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * \
25 video->chrom_width] + \
26 (video->in_x >> 1); \
27 cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * \
28 video->chrom_width] + \
29 (video->in_x >> 1); \
30 } \
31 else \
32 { \
33 cb_in = &src[1][(video->y_table[h] + video->in_y) * \
34 video->chrom_width] + \
35 (video->in_x >> 1); \
36 cr_in = &src[2][(video->y_table[h] + video->in_y) * \
37 video->chrom_width] + \
38 (video->in_x >> 1); \
39 } \
40 data = output_rows[h];
42 #define DITHER_ROW_TAIL \
45 #define DITHER_SCALE_HEAD \
46 for(w = 0; w < video->out_w; w++) \
47 { \
48 uv_subscript = video->x_table[w] / 2; \
49 y_l = y_in[video->x_table[w]]; \
50 y_l <<= 16; \
51 r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
52 g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
53 b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
55 #define DITHER_SCALE_601_HEAD \
56 for(w = 0; w < video->out_w; w++) \
57 { \
58 uv_subscript = video->x_table[w] / 2; \
59 y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \
60 y_l <<= 16; \
61 r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
62 g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
63 b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
65 #define DITHER_SCALE_TAIL \
68 #define DITHER_HEAD \
69 for(w = 0; w < video->horizontal_size; w++) \
70 { \
71 y_l = *y_in++; \
72 y_l <<= 16; \
73 r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
74 g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
75 b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
77 #define DITHER_601_HEAD \
78 for(w = 0; w < video->horizontal_size; w++) \
79 { \
80 y_l = mpeg3_601_to_rgb[*y_in++]; \
81 y_l <<= 16; \
82 r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
83 g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
84 b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
86 #define DITHER_TAIL \
87 if(w & 1) \
88 { \
89 cr_in++; \
90 cb_in++; \
91 } \
95 #define STORE_PIXEL_BGR888 \
96 *data++ = CLIP(b_l); \
97 *data++ = CLIP(g_l); \
98 *data++ = CLIP(r_l);
100 #define STORE_PIXEL_BGRA8888 \
101 *data++ = CLIP(b_l); \
102 *data++ = CLIP(g_l); \
103 *data++ = CLIP(r_l); \
104 *data++ = 0;
106 #define STORE_PIXEL_RGB565 \
107 *(*(unsigned short**)(&data))++ = \
108 ((CLIP(r_l) & 0xf8) << 8) | \
109 ((CLIP(g_l) & 0xfc) << 3) | \
110 ((CLIP(b_l) & 0xf8) >> 3); \
111 data += 2;
113 #define STORE_PIXEL_RGB888 \
114 *data++ = CLIP(r_l); \
115 *data++ = CLIP(g_l); \
116 *data++ = CLIP(b_l);
118 #define STORE_PIXEL_RGBA8888 \
119 *data++ = CLIP(r_l); \
120 *data++ = CLIP(g_l); \
121 *data++ = CLIP(b_l); \
122 *data++ = 0;
124 #define STORE_PIXEL_RGBA16161616 \
125 *data_s++ = CLIP(r_l); \
126 *data_s++ = CLIP(g_l); \
127 *data_s++ = CLIP(b_l); \
128 *data_s++ = 0;
132 /* Only good for YUV 4:2:0 */
133 int mpeg3video_ditherframe(mpeg3video_t *video,
134 unsigned char **src,
135 unsigned char **output_rows)
137 int h = 0;
138 unsigned char *y_in, *cb_in, *cr_in;
139 int y_l, r_l, b_l, g_l;
140 unsigned char *data;
141 int uv_subscript, step, w = -1;
145 DITHER_ROW_HEAD
146 /* Transfer row with scaling */
147 if(video->out_w != video->horizontal_size)
149 switch(video->color_model)
151 case MPEG3_BGR888:
152 DITHER_SCALE_HEAD
153 STORE_PIXEL_BGR888
154 DITHER_SCALE_TAIL
155 break;
156 case MPEG3_BGRA8888:
157 DITHER_SCALE_HEAD
158 STORE_PIXEL_BGRA8888
159 DITHER_SCALE_TAIL
160 break;
161 case MPEG3_RGB565:
162 DITHER_SCALE_HEAD
163 STORE_PIXEL_RGB565
164 DITHER_SCALE_TAIL
165 break;
166 case MPEG3_RGB888:
167 DITHER_SCALE_HEAD
168 STORE_PIXEL_RGB888
169 DITHER_SCALE_TAIL
170 break;
171 case MPEG3_RGBA8888:
172 DITHER_SCALE_HEAD
173 STORE_PIXEL_RGBA8888
174 DITHER_SCALE_TAIL
175 break;
176 case MPEG3_601_BGR888:
177 DITHER_SCALE_601_HEAD
178 STORE_PIXEL_BGR888
179 DITHER_SCALE_TAIL
180 break;
181 case MPEG3_601_BGRA8888:
182 DITHER_SCALE_601_HEAD
183 STORE_PIXEL_BGRA8888
184 DITHER_SCALE_TAIL
185 break;
186 case MPEG3_601_RGB565:
187 DITHER_SCALE_601_HEAD
188 STORE_PIXEL_RGB565
189 DITHER_SCALE_TAIL
190 break;
191 case MPEG3_601_RGB888:
192 DITHER_SCALE_601_HEAD
193 STORE_PIXEL_RGB888
194 DITHER_SCALE_TAIL
195 break;
196 case MPEG3_601_RGBA8888:
197 DITHER_SCALE_601_HEAD
198 STORE_PIXEL_RGBA8888
199 DITHER_SCALE_TAIL
200 break;
201 case MPEG3_RGBA16161616:
203 register unsigned short *data_s = (unsigned short*)data;
204 DITHER_SCALE_HEAD
205 STORE_PIXEL_RGBA16161616
206 DITHER_SCALE_TAIL
208 break;
211 else
213 /* Transfer row unscaled */
214 switch(video->color_model)
216 case MPEG3_BGR888:
217 DITHER_HEAD
218 STORE_PIXEL_BGR888
219 DITHER_TAIL
220 break;
221 case MPEG3_BGRA8888:
222 DITHER_HEAD
223 STORE_PIXEL_BGRA8888
224 DITHER_TAIL
225 break;
226 case MPEG3_RGB565:
227 DITHER_HEAD
228 STORE_PIXEL_RGB565
229 DITHER_TAIL
230 break;
231 case MPEG3_RGB888:
232 DITHER_HEAD
233 STORE_PIXEL_RGB888
234 DITHER_TAIL
235 break;
236 case MPEG3_RGBA8888:
237 DITHER_HEAD
238 STORE_PIXEL_RGBA8888
239 DITHER_TAIL
240 break;
241 case MPEG3_601_BGR888:
242 DITHER_601_HEAD
243 STORE_PIXEL_BGR888
244 DITHER_TAIL
245 break;
246 case MPEG3_601_BGRA8888:
247 DITHER_601_HEAD
248 STORE_PIXEL_BGRA8888
249 DITHER_TAIL
250 break;
251 case MPEG3_601_RGB565:
252 DITHER_601_HEAD
253 STORE_PIXEL_RGB565
254 DITHER_TAIL
255 break;
256 case MPEG3_601_RGB888:
257 DITHER_601_HEAD
258 STORE_PIXEL_RGB888
259 DITHER_TAIL
260 break;
261 case MPEG3_601_RGBA8888:
262 DITHER_601_HEAD
263 STORE_PIXEL_RGBA8888
264 DITHER_TAIL
265 break;
266 case MPEG3_RGBA16161616:
268 register unsigned short *data_s = (unsigned short*)data;
269 DITHER_HEAD
270 STORE_PIXEL_RGBA16161616
271 DITHER_TAIL
273 break;
276 DITHER_ROW_TAIL
278 return 0;
281 int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[])
283 return 0;
286 int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[])
288 return mpeg3video_ditherframe(video, src, video->output_rows);
291 int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[])
293 return 0;
296 int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[])
298 return 0;
301 int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[])
303 return 0;
306 void memcpy_fast(unsigned char *output, unsigned char *input, long len)
308 int i, len2;
309 /* 8 byte alignment */
311 * if(!((long)input & 0x7))
313 * len2 = len >> 4;
314 * for(i = 0; i < len2; )
316 * ((int64_t*)output)[i] = ((int64_t*)input)[i];
317 * i++;
318 * ((int64_t*)output)[i] = ((int64_t*)input)[i];
319 * i++;
322 * for(i *= 16; i < len; i++)
324 * output[i] = input[i];
327 * else
329 memcpy(output, input, len);
332 int mpeg3video_init_output()
334 int i, value;
335 for(i = 0; i < 256; i++)
337 value = (int)(1.1644 * i - 255 * 0.0627 + 0.5);
338 if(value < 0) value = 0;
339 else
340 if(value > 255) value = 255;
341 mpeg3_601_to_rgb[i] = value;
343 return 0;
346 int mpeg3video_present_frame(mpeg3video_t *video)
348 int i, j, k, l;
349 unsigned char *src[3];
350 src[0] = video->output_src[0];
351 src[1] = video->output_src[1];
352 src[2] = video->output_src[2];
354 /* Copy YUV buffers */
355 if(video->want_yvu)
357 long size0, size1;
358 long offset0, offset1;
359 int chroma_denominator;
361 if(video->chroma_format == CHROMA420)
362 chroma_denominator = 2;
363 else
364 chroma_denominator = 1;
366 /* Drop a frame */
367 if(!video->y_output) return 0;
369 /* Copy a frame */
370 /* Three blocks */
371 if(video->in_x == 0 &&
372 video->in_w >= video->coded_picture_width &&
373 video->row_span == video->coded_picture_width)
375 size0 = video->coded_picture_width * video->in_h;
376 size1 = video->chrom_width * (int)((float)video->in_h / chroma_denominator + 0.5);
377 offset0 = video->coded_picture_width * video->in_y;
378 offset1 = video->chrom_width * (int)((float)video->in_y / chroma_denominator + 0.5);
380 printf("mpeg3video_present_frame 1\n");
382 * if(video->in_y > 0)
384 * offset[1] += video->chrom_width / 2;
385 * size[1] += video->chrom_width / 2;
389 memcpy(video->y_output, src[0] + offset0, size0);
390 memcpy(video->u_output, src[1] + offset1, size1);
391 memcpy(video->v_output, src[2] + offset1, size1);
393 else
394 /* One block per row */
396 //printf("mpeg3video_present_frame 2 %d %d %d\n", video->in_w, video->coded_picture_width, video->chrom_width);
397 int row_span = video->in_w;
398 int row_span0;
399 int row_span1;
401 if(video->row_span)
402 row_span = video->row_span;
404 row_span0 = row_span;
405 row_span1 = (row_span >> 1);
406 size0 = video->in_w;
407 size1 = (video->in_w >> 1);
408 offset0 = video->coded_picture_width * video->in_y;
409 offset1 = video->chrom_width * video->in_y / chroma_denominator;
411 for(i = 0; i < video->in_h; i++)
413 memcpy(video->y_output + i * row_span0,
414 src[0] + offset0 + video->in_x,
415 size0);
417 offset0 += video->coded_picture_width;
419 if(chroma_denominator == 1 || !(i % 2))
421 memcpy(video->u_output + i / chroma_denominator * row_span1,
422 src[1] + offset1 + (video->in_x >> 1),
423 size1);
424 memcpy(video->v_output + i / chroma_denominator * row_span1,
425 src[2] + offset1 + (video->in_x >> 1),
426 size1);
427 if(video->horizontal_size < video->in_w)
429 memset(video->u_output +
430 i / chroma_denominator * row_span1 +
431 (video->horizontal_size >> 1),
432 0x80,
433 (video->in_w >> 1) -
434 (video->horizontal_size >> 1));
435 memset(video->v_output +
436 i / chroma_denominator * row_span1 +
437 (video->horizontal_size >> 1),
438 0x80,
439 (video->in_w >> 1) -
440 (video->horizontal_size >> 1));
445 if(chroma_denominator == 1 || (i % 2))
446 offset1 += video->chrom_width;
450 return 0;
453 /* Want RGB buffer */
454 /* Copy the frame to the output with YUV to RGB conversion */
455 if(video->prog_seq)
457 if(video->chroma_format != CHROMA444)
459 mpeg3video_ditherframe(video, src, video->output_rows);
461 else
462 mpeg3video_ditherframe444(video, src);
464 else
466 if((video->pict_struct == FRAME_PICTURE && video->topfirst) ||
467 video->pict_struct == BOTTOM_FIELD)
469 /* top field first */
470 if(video->chroma_format != CHROMA444)
472 mpeg3video_dithertop(video, src);
473 mpeg3video_ditherbot(video, src);
475 else
477 mpeg3video_dithertop444(video, src);
478 mpeg3video_ditherbot444(video, src);
481 else
483 /* bottom field first */
484 if(video->chroma_format != CHROMA444)
486 mpeg3video_ditherbot(video, src);
487 mpeg3video_dithertop(video, src);
489 else
491 mpeg3video_ditherbot444(video, src);
492 mpeg3video_dithertop444(video, src);
496 return 0;
499 int mpeg3video_display_second_field(mpeg3video_t *video)
501 /* Not used */
502 return 0;