add audio to proxy, and minor bug fixes
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / video / output.C
1 #include "../libzmpeg3.h"
2
3 /* Algorithm */
4 /*   r = (int)(*y + 1.371 * (*cr - 128)); */
5 /*   g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */
6 /*   b = (int)(*y + 1.732 * (*cb - 128)); */
7
8
9 #define INPUT_420 \
10     int yi = y_table[h] + in_y; int uvi = (yi >> 1) * chrom_width; \
11     uint8_t *y_in = &yy[yi * coded_picture_width] + in_x; \
12     uint8_t *cb_in = &uu[uvi] + in_x1; \
13     uint8_t *cr_in = &vv[uvi] + in_x1
14
15 #define INPUT_422 \
16     int yi = y_table[h] + in_y; int uvi = yi * chrom_width; \
17     uint8_t *y_in = &yy[yi * coded_picture_width] + in_x; \
18     uint8_t *cb_in = &uu[uvi] + in_x1; \
19     uint8_t *cr_in = &vv[uvi] + in_x1
20
21 #define OUTPUT_420 \
22     uint8_t *y_out = output_rows[h]; int h1 = h >> 1; \
23     uint8_t *u_out = output_rows[h1+offset0]; \
24     uint8_t *v_out = output_rows[h1+offset2]
25
26 #define OUTPUT_422 \
27     uint8_t *y_out = output_rows[h]; \
28     uint8_t *u_out = output_rows[h+offset0]; \
29     uint8_t *v_out = output_rows[h+offset1]
30
31 static int z601[256];
32 #define Y_YUV(v) (v)
33 #define Y_601(v) z601[v]
34
35 /* RGB output */
36
37 #define RGB_HEAD(fmt) \
38   for( int h=0; h<ht; ++h ) { INPUT_##fmt; \
39     uint8_t *rgb = output_rows[h];
40
41 #define RGB_TAIL \
42   }
43
44 #define RGB_UNSCALED(out,csp) \
45   for( int w=0, iuv=0; w<wd; w+=2, ++iuv ) { \
46     int cr = cr_in[iuv], cb = cb_in[iuv]; \
47     int y_l = Y_##csp(y_in[w+0]) << 16; { \
48     STORE_##out##_R(y_l + cr2r[cr]); \
49     STORE_##out##_G(y_l + crb2g[(cr<<8)|cb]); \
50     STORE_##out##_B(y_l + cb2b[cb]); \
51     STORE_##out##_A(0); } \
52     if( w+1 >= wd ) break; \
53     y_l = y_in[w+1] << 16; { \
54     STORE_##out##_R(y_l + cr2r[cr]); \
55     STORE_##out##_G(y_l + crb2g[(cr<<8)|cb]); \
56     STORE_##out##_B(y_l + cb2b[cb]); \
57     STORE_##out##_A(0); } \
58   }
59
60 #define RGB_SCALED(out,csp) \
61   for( int w=0; w<wd; ++w ) { \
62     int ix = x_table[w]; int iuv = ix >> 1; \
63     int cr = cr_in[iuv], cb = cb_in[iuv]; \
64     int y_l = Y_##csp(y_in[ix]) << 16; \
65     STORE_##out##_R(y_l + cr2r[cr]); \
66     STORE_##out##_G(y_l + crb2g[(cr<<8)|cb]); \
67     STORE_##out##_B(y_l + cb2b[cb]); \
68     STORE_##out##_A(0); \
69   }
70
71 #define STORE_BGR888_R(v) rgb[2] = clip((v) >> 16)
72 #define STORE_BGR888_G(v) rgb[1] = clip((v) >> 16)
73 #define STORE_BGR888_B(v) rgb[0] = clip((v) >> 16)
74 #define STORE_BGR888_A(v) rgb += 3
75
76 #define STORE_BGRA8888_R(v) rgb[2] = clip((v) >> 16)
77 #define STORE_BGRA8888_G(v) rgb[1] = clip((v) >> 16)
78 #define STORE_BGRA8888_B(v) rgb[0] = clip((v) >> 16)
79 #define STORE_BGRA8888_A(v) rgb[3] = 255;  rgb += 4
80
81 #define STORE_RGB565_R(v) int r = clip((v) >> 16)
82 #define STORE_RGB565_G(v) int g = clip((v) >> 16)
83 #define STORE_RGB565_B(v) int b = clip((v) >> 16)
84 #define STORE_RGB565_A(v) *((uint16_t*)rgb) = \
85   ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3); \
86   rgb += 2
87
88 #define STORE_RGB888_R(v) rgb[0] = clip((v) >> 16)
89 #define STORE_RGB888_G(v) rgb[1] = clip((v) >> 16)
90 #define STORE_RGB888_B(v) rgb[2] = clip((v) >> 16)
91 #define STORE_RGB888_A(v) rgb += 3
92
93 #define STORE_RGBA8888_R(v) rgb[0] = clip((v) >> 16)
94 #define STORE_RGBA8888_G(v) rgb[1] = clip((v) >> 16)
95 #define STORE_RGBA8888_B(v) rgb[2] = clip((v) >> 16)
96 #define STORE_RGBA8888_A(v) rgb[3] = 255;  rgb += 4
97
98 #define STORE_RGBA16161616_R(v) rgb_s[0] = clip((v) >> 8, -32768, 32767)
99 #define STORE_RGBA16161616_G(v) rgb_s[1] = clip((v) >> 8, -32768, 32767)
100 #define STORE_RGBA16161616_B(v) rgb_s[2] = clip((v) >> 8, -32768, 32767)
101 #define STORE_RGBA16161616_A(v) rgb_s[3] = 32767;  rgb_s += 4
102
103
104 /* YUV output */
105
106 #define YUV_HEAD_420 \
107   for( int h=0; h<ht; ++h ) { INPUT_420; \
108     uint8_t *yuv_out = output_rows[h];
109
110 #define YUV_HEAD_422 \
111   for( int h=0; h<ht; ++h ) { INPUT_422; \
112     uint8_t *yuv_out = output_rows[h];
113
114 #define YUV_TAIL \
115   }
116
117 #define YUV_SCALED_YUV888(csp) \
118   for( int w=0; w<wd; ) { \
119     int ix = x_table[w++]; int iuv = ix >> 1; \
120     STORE_Y(Y_##csp(y_in[ix])); STORE_U(cb_in[iuv]); \
121     STORE_V(cr_in[iuv]); \
122   }
123
124 #define YUV_SCALED_YUVA8888(csp) \
125   for( int w=0; w<wd; ) { \
126     int ix = x_table[w++]; int iuv = ix >> 1; \
127     STORE_Y(Y_##csp(y_in[ix])); STORE_U(cb_in[iuv]); \
128     STORE_V(cr_in[iuv]); STORE_A(255); \
129   }
130
131 #define YUV_SCALED_YUYV(csp) \
132   for( int w=0; w<wd; ) { \
133     int ix = x_table[w++]; int iuv = ix >> 1; \
134     STORE_Y(Y_##csp(y_in[ix])); STORE_U(cb_in[iuv]); \
135     ix = x_table[w++]; iuv = ix >> 1; \
136     STORE_Y(Y_##csp(y_in[ix])); STORE_V(cr_in[iuv]); \
137   }
138
139 #define YUV_SCALED_UYVY(csp) \
140   for( int w=0; w<wd; ) { \
141     int ix = x_table[w++]; int iuv = ix >> 1; \
142     STORE_U(cb_in[iuv]); STORE_Y(Y_##csp(y_in[ix])); \
143     ix = x_table[w++]; iuv = ix >> 1; \
144     STORE_V(cr_in[iuv]); STORE_Y(Y_##csp(y_in[ix])); \
145   }
146
147 #define YUV_UNSCALED_YUV888(csp) \
148   for( int w=0, iuv=0; w<wd; w+=2, ++iuv ) { \
149     STORE_Y(Y_##csp(y_in[w+0])); STORE_U(cb_in[iuv]); STORE_V(cr_in[iuv]); \
150     if( w+1 >= wd ) break; \
151     STORE_Y(Y_##csp(y_in[w+1])); STORE_U(cb_in[iuv]); STORE_V(cr_in[iuv]); \
152   }
153
154 #define YUV_UNSCALED_YUVA8888(csp) \
155   for( int w=0, iuv=0; w<wd; w+=2, ++iuv ) { \
156     STORE_Y(Y_##csp(y_in[w+0])); STORE_U(cb_in[iuv]); \
157     STORE_V(cr_in[iuv]); STORE_A(255); \
158     if( w+1 >= wd ) break; \
159     STORE_Y(Y_##csp(y_in[w+1])); STORE_U(cb_in[iuv]); \
160     STORE_V(cr_in[iuv]); STORE_A(255); \
161   }
162
163 #define YUV_UNSCALED_YUYV(csp) \
164   for( int w=0, iuv=0; w<wd; ++iuv ) { \
165     STORE_Y(Y_##csp(y_in[w++])); STORE_U(cb_in[iuv]); \
166     STORE_Y(Y_##csp(y_in[w++])); STORE_V(cr_in[iuv]); \
167   }
168
169 #define YUV_UNSCALED_UYVY(csp) \
170   for( int w=0, iuv=0; w<wd; ++iuv ) { \
171     STORE_U(cb_in[iuv]); STORE_Y(Y_##csp(y_in[w++])); \
172     STORE_V(cr_in[iuv]); STORE_Y(Y_##csp(y_in[w++])); \
173   }
174
175 #define STORE_Y(v) *yuv_out++ = (v)
176 #define STORE_U(v) *yuv_out++ = (v)
177 #define STORE_V(v) *yuv_out++ = (v)
178 #define STORE_A(v) *yuv_out++ = (v)
179
180 /* YUVP output */
181
182
183 #define YUV420P_HEAD_420 \
184   for( int h=0; h<ht; ++h ) { INPUT_420; OUTPUT_420;
185
186 #define YUV422P_HEAD_420 \
187   for( int h=0; h<ht; ++h ) { INPUT_420; OUTPUT_422;
188
189 #define YUV420P_HEAD_422 \
190   for( int h=0; h<ht; ++h ) { INPUT_422; OUTPUT_420;
191
192 #define YUV422P_HEAD_422 \
193   for( int h=0; h<ht; ++h ) { INPUT_422; OUTPUT_422;
194
195 #define YUVP_TAIL \
196   }
197
198 #define YUV_SCALED_YUVP(CSP) \
199   for( int w=0; w<wd; ) { \
200     int ix = x_table[w++]; int iuv = ix >> 1; \
201     STORE_UP(cb_in[iuv]); STORE_YP(Y_##CSP(y_in[ix])); \
202     ix = x_table[w++]; iuv = ix >> 1; \
203     STORE_VP(cr_in[iuv]); STORE_YP(Y_##CSP(y_in[ix])); \
204   }
205
206 #define YUV_UNSCALED_YUVP(CSP) \
207   for( int w=0, iuv=0; w<wd; ++iuv ) { \
208     STORE_UP(cb_in[iuv]); STORE_YP(Y_##CSP(y_in[w++])); \
209     STORE_VP(cr_in[iuv]); STORE_YP(Y_##CSP(y_in[w++])); \
210   }
211
212 #define STORE_YP(v) *y_out++ = (v)
213 #define STORE_UP(v) *u_out++ = (v)
214 #define STORE_VP(v) *v_out++ = (v)
215
216 /* transfer macros */
217 /*  CSP = input colorspace */
218 /*  FMT = input format */
219 /*  OUT = output colorspace/format */
220
221 #define SCALED_RGB(CSP,FMT,OUT) case cmdl_##CSP##_##OUT: { \
222   RGB_HEAD(FMT) \
223   RGB_SCALED(OUT,CSP) \
224   RGB_TAIL \
225   break; }
226
227 #define UNSCALED_RGB(CSP,FMT,OUT) case cmdl_##CSP##_##OUT: { \
228   RGB_HEAD(FMT) \
229   RGB_UNSCALED(OUT,CSP) \
230   RGB_TAIL \
231   break; }
232
233 #define SCALED_YUV(CSP,FMT,OUT) case cmdl_##CSP##_##OUT: { \
234   OUT##_HEAD(FMT) \
235   YUV_SCALED_##OUT(CSP) \
236   YUV_TAIL \
237   break; }
238
239 #define UNSCALED_YUV(CSP,FMT,OUT) case cmdl_##CSP##_##OUT: { \
240   OUT##_HEAD(FMT) \
241   YUV_UNSCALED_##OUT(CSP) \
242   YUV_TAIL \
243   break; }
244
245
246 /* naming equivalances */
247
248 #define YUV_UNSCALED_YUV420P YUV_UNSCALED_YUVP
249 #define YUV_UNSCALED_YUV422P YUV_UNSCALED_YUVP
250 #define YUV_SCALED_YUV420P YUV_SCALED_YUVP
251 #define YUV_SCALED_YUV422P YUV_SCALED_YUVP
252
253 #define YUYV_HEAD(fmt) YUV_HEAD_##fmt
254 #define UYVY_HEAD(fmt) YUV_HEAD_##fmt
255 #define YUV888_HEAD(fmt) YUV_HEAD_##fmt
256 #define YUVA8888_HEAD(fmt) YUV_HEAD_##fmt
257 #define YUV420P_HEAD(fmt) YUV420P_HEAD_##fmt
258 #define YUV422P_HEAD(fmt) YUV422P_HEAD_##fmt
259
260 #define cmdl_YUV_BGR888   cmdl_BGR888
261 #define cmdl_YUV_BGRA8888 cmdl_BGRA8888
262 #define cmdl_YUV_RGB565   cmdl_RGB565
263 #define cmdl_YUV_RGB888   cmdl_RGB888
264 #define cmdl_YUV_RGBA8888 cmdl_RGBA8888
265
266 #define cmdl_YUV_YUV888   cmdl_YUV888
267 #define cmdl_YUV_YUVA8888 cmdl_YUVA8888
268 #define cmdl_YUV_YUV420P  cmdl_YUV420P
269 #define cmdl_YUV_YUV422P  cmdl_YUV422P
270 #define cmdl_YUV_YUYV     cmdl_YUYV
271 #define cmdl_YUV_UYVY     cmdl_UYVY
272
273 int zvideo_t::
274 dither_frame(uint8_t *yy, uint8_t *uu, uint8_t *vv, uint8_t **output_rows)
275 {
276   int *cr2r = cr_to_r;
277   int *crb2g = crb_to_g;
278   int *cb2b = cb_to_b;
279   int wd = out_w, ht = out_h;
280   int offset0 = ht, in_x1 = in_x >> 1;
281   int offset1 = offset0 + ht;
282   int offset2 = offset0 + ht/2;
283   if( chroma_format == cfmt_420 ) {
284     if( out_w != horizontal_size ) {
285       switch( color_model ) {
286       SCALED_RGB(YUV,420,BGR888);
287       SCALED_RGB(YUV,420,BGRA8888);
288       SCALED_RGB(YUV,420,RGB565);
289       SCALED_RGB(YUV,420,RGB888);
290       SCALED_RGB(YUV,420,RGBA8888);
291       SCALED_RGB(601,420,BGR888);
292       SCALED_RGB(601,420,BGRA8888);
293       SCALED_RGB(601,420,RGB565);
294       SCALED_RGB(601,420,RGB888);
295       SCALED_RGB(601,420,RGBA8888);
296
297       SCALED_YUV(YUV,420,YUV420P);
298       SCALED_YUV(YUV,420,YUV422P);
299       SCALED_YUV(YUV,420,YUYV);
300       SCALED_YUV(YUV,420,UYVY);
301       SCALED_YUV(YUV,420,YUV888);
302       SCALED_YUV(YUV,420,YUVA8888);
303       SCALED_YUV(601,420,YUV420P);
304       SCALED_YUV(601,420,YUV422P);
305       SCALED_YUV(601,420,YUYV);
306       SCALED_YUV(601,420,UYVY);
307       SCALED_YUV(601,420,YUV888);
308       SCALED_YUV(601,420,YUVA8888);
309
310       case cmdl_RGBA16161616: {
311         RGB_HEAD(420) \
312         uint16_t *rgb_s = (uint16_t*)rgb;
313         RGB_SCALED(RGBA16161616,YUV)
314         RGB_TAIL
315         break;
316         }
317       }
318     }
319     else {
320       switch( color_model ) {
321       UNSCALED_RGB(YUV,420,BGR888);
322       UNSCALED_RGB(YUV,420,BGRA8888);
323       UNSCALED_RGB(YUV,420,RGB565);
324       UNSCALED_RGB(YUV,420,RGB888);
325       UNSCALED_RGB(YUV,420,RGBA8888);
326       UNSCALED_RGB(601,420,BGR888);
327       UNSCALED_RGB(601,420,BGRA8888);
328       UNSCALED_RGB(601,420,RGB565);
329       UNSCALED_RGB(601,420,RGB888);
330       UNSCALED_RGB(601,420,RGBA8888);
331
332       UNSCALED_YUV(YUV,420,YUV420P);
333       UNSCALED_YUV(YUV,420,YUV422P);
334       UNSCALED_YUV(YUV,420,YUYV);
335       UNSCALED_YUV(YUV,420,UYVY);
336       UNSCALED_YUV(YUV,420,YUV888);
337       UNSCALED_YUV(YUV,420,YUVA8888);
338       UNSCALED_YUV(601,420,YUV420P);
339       UNSCALED_YUV(601,420,YUV422P);
340       UNSCALED_YUV(601,420,YUYV);
341       UNSCALED_YUV(601,420,UYVY);
342       UNSCALED_YUV(601,420,YUV888);
343       UNSCALED_YUV(601,420,YUVA8888);
344
345       case cmdl_RGBA16161616: {
346         RGB_HEAD(420) \
347         uint16_t *rgb_s = (uint16_t*)rgb;
348         RGB_UNSCALED(RGBA16161616,YUV)
349         RGB_TAIL
350         break;
351         }
352       }
353     }
354   }
355   else {
356     if( out_w != horizontal_size ) {
357       switch( color_model ) {
358       SCALED_RGB(YUV,422,BGR888);
359       SCALED_RGB(YUV,422,BGRA8888);
360       SCALED_RGB(YUV,422,RGB565);
361       SCALED_RGB(YUV,422,RGB888);
362       SCALED_RGB(YUV,422,RGBA8888);
363       SCALED_RGB(601,422,BGR888);
364       SCALED_RGB(601,422,BGRA8888);
365       SCALED_RGB(601,422,RGB565);
366       SCALED_RGB(601,422,RGB888);
367       SCALED_RGB(601,422,RGBA8888);
368
369       SCALED_YUV(YUV,422,YUV420P);
370       SCALED_YUV(YUV,422,YUV422P);
371       SCALED_YUV(YUV,422,YUYV);
372       SCALED_YUV(YUV,422,UYVY);
373       SCALED_YUV(YUV,422,YUV888);
374       SCALED_YUV(YUV,422,YUVA8888);
375       SCALED_YUV(601,422,YUV420P);
376       SCALED_YUV(601,422,YUV422P);
377       SCALED_YUV(601,422,YUYV);
378       SCALED_YUV(601,422,UYVY);
379       SCALED_YUV(601,422,YUV888);
380       SCALED_YUV(601,422,YUVA8888);
381
382       case cmdl_RGBA16161616: {
383         RGB_HEAD(422) \
384         uint16_t *rgb_s = (uint16_t*)rgb;
385         RGB_SCALED(RGBA16161616,YUV)
386         RGB_TAIL
387         break;
388         }
389       }
390     }
391     else {
392       switch( color_model ) {
393       UNSCALED_RGB(YUV,422,BGR888);
394       UNSCALED_RGB(YUV,422,BGRA8888);
395       UNSCALED_RGB(YUV,422,RGB565);
396       UNSCALED_RGB(YUV,422,RGB888);
397       UNSCALED_RGB(YUV,422,RGBA8888);
398       UNSCALED_RGB(601,422,BGR888);
399       UNSCALED_RGB(601,422,BGRA8888);
400       UNSCALED_RGB(601,422,RGB565);
401       UNSCALED_RGB(601,422,RGB888);
402       UNSCALED_RGB(601,422,RGBA8888);
403
404       UNSCALED_YUV(YUV,422,YUV420P);
405       UNSCALED_YUV(YUV,422,YUV422P);
406       UNSCALED_YUV(YUV,422,YUYV);
407       UNSCALED_YUV(YUV,422,UYVY);
408       UNSCALED_YUV(YUV,422,YUV888);
409       UNSCALED_YUV(YUV,422,YUVA8888);
410       UNSCALED_YUV(601,422,YUV420P);
411       UNSCALED_YUV(601,422,YUV422P);
412       UNSCALED_YUV(601,422,YUYV);
413       UNSCALED_YUV(601,422,UYVY);
414       UNSCALED_YUV(601,422,YUV888);
415       UNSCALED_YUV(601,422,YUVA8888);
416
417       case cmdl_RGBA16161616: {
418         RGB_HEAD(422) \
419         uint16_t *rgb_s = (uint16_t*)rgb;
420         RGB_UNSCALED(RGBA16161616,YUV)
421         RGB_TAIL
422         break;
423         }
424       }
425     }
426   }
427   return 0;
428 }
429
430 int zvideo_t::
431 dither_frame444(uint8_t *yy, uint8_t *uu, uint8_t *vv)
432 {
433   return 0;
434 }
435
436 int zvideo_t::
437 dithertop(uint8_t *yy, uint8_t *uu, uint8_t *vv)
438 {
439   return dither_frame(yy, uu, vv, output_rows);
440 }
441
442 int zvideo_t::
443 dithertop444(uint8_t *yy, uint8_t *uu, uint8_t *vv)
444 {
445   return 0;
446 }
447
448 int zvideo_t::
449 ditherbot(uint8_t *yy, uint8_t *uu, uint8_t *vv)
450 {
451   return 0;
452 }
453
454 int zvideo_t::
455 ditherbot444(uint8_t *yy, uint8_t *uu, uint8_t *vv)
456 {
457   return 0;
458 }
459
460 int zvideo_t::
461 init_output()
462 {
463   int i, value;
464   for( i=0; i<256; ++i ) {
465     value = (int)(1.1644 * i - 255 * 0.0627 + 0.5);
466     z601[i] = clip(value) << 16;
467   }
468   return 0;
469 }
470
471 int zvideo_t::
472 present_frame(uint8_t *yy, uint8_t *uu, uint8_t *vv)
473 {
474   int i;
475   ++frame_time;
476   ++seek_time;
477
478   /* Copy YUV buffers */
479   if( want_yvu ) {
480     long size0, size1;
481     long offset0, offset1;
482     int chroma_denominator;
483     /* Drop a frame */
484     if( !y_output ) return 0;
485
486     chroma_denominator = chroma_format == cfmt_420 ? 2 : 1;
487
488     /* Copy a frame */
489     /* Three blocks */
490     if( in_x == 0 && in_w >= coded_picture_width &&
491         row_span == coded_picture_width ) {
492       size0 = coded_picture_width * in_h;
493       size1 = chrom_width * (int)((float)in_h / chroma_denominator + 0.5);
494       offset0 = coded_picture_width * in_y;
495       offset1 = chrom_width * (int)((float)in_y / chroma_denominator + 0.5);
496
497 //zmsg("1\n");
498 /*
499  *       if(in_y > 0)
500  *       {
501  *         offset[1] += chrom_width / 2;
502  *         size[1] += chrom_width / 2;
503  *       }
504  */
505
506       memcpy(y_output, yy + offset0, size0);
507       memcpy(u_output, uu + offset1, size1);
508       memcpy(v_output, vv + offset1, size1);
509     }
510     else {
511       /* One block per row */
512 //zmsgs("2 %d %d %d\n", in_w, coded_picture_width, chrom_width);
513       int row_span = in_w;
514       int row_span0, sofs;
515       int row_span1, dofs;
516
517       if( row_span )
518         row_span = row_span;
519
520       row_span0 = row_span;
521       row_span1 = (row_span >> 1);
522       size0 = in_w;
523       size1 = (in_w >> 1);
524       offset0 = coded_picture_width * in_y;
525       offset1 = chrom_width * in_y / chroma_denominator;
526   
527       for( i=0; i<in_h; ++i ) {
528         memcpy(y_output + i*row_span0, yy + offset0 + in_x, size0);
529         offset0 += coded_picture_width;
530         if( chroma_denominator == 1 || !(i % 2) ) {
531           sofs = offset1 + (in_x>>1);
532           dofs = i/chroma_denominator * row_span1; 
533           memcpy(u_output + dofs, uu + sofs, size1);
534           memcpy(v_output + dofs, vv + sofs, size1);
535           if( horizontal_size < in_w ) {
536             dofs = i/chroma_denominator * row_span1 + (horizontal_size>>1);
537             sofs = (in_w>>1) - (horizontal_size>>1);
538             memset(u_output + dofs, 0x80, sofs);
539             memset(v_output + dofs, 0x80, sofs);
540           }
541         }
542         
543
544         if( chroma_denominator == 1 || (i%2) )
545           offset1 += chrom_width;
546       }
547     }
548
549     return 0;
550   }
551
552 /* Want RGB buffer */
553 /* Copy the frame to the output with YUV to RGB conversion */
554   if( prog_seq ) {
555     if( chroma_format != cfmt_444 )
556       dither_frame(yy, uu, vv, output_rows);
557     else
558       dither_frame444(yy, uu, vv);
559   }
560   else {
561     if( (pict_struct == pics_FRAME_PICTURE && topfirst) || 
562          pict_struct == pics_BOTTOM_FIELD) {
563 /* top field first */
564       if( chroma_format != cfmt_444 ) {
565         dithertop(yy, uu, vv);
566         ditherbot(yy, uu, vv);
567       }
568       else {
569         dithertop444(yy, uu, vv);
570         ditherbot444(yy, uu, vv);
571       }
572     }
573     else {
574 /* bottom field first */
575       if( chroma_format != cfmt_444 ) {
576         ditherbot(yy, uu, vv);
577         dithertop(yy, uu, vv);
578       }
579       else {
580         ditherbot444(yy, uu, vv);
581         dithertop444(yy, uu, vv);
582       }
583     }
584   }
585   return 0;
586 }
587