1 #include "../libmpeg3.h"
2 #include "mpeg3video.h"
5 #define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
8 static unsigned char mpeg3_601_to_rgb
[256];
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++) \
19 y_in = &src[0][(video->y_table[h] + video->in_y) * \
20 video->coded_picture_width] + \
22 if(video->chroma_format == CHROMA420) \
24 cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * \
25 video->chrom_width] + \
27 cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * \
28 video->chrom_width] + \
33 cb_in = &src[1][(video->y_table[h] + video->in_y) * \
34 video->chrom_width] + \
36 cr_in = &src[2][(video->y_table[h] + video->in_y) * \
37 video->chrom_width] + \
40 data = output_rows[h];
42 #define DITHER_ROW_TAIL \
45 #define DITHER_SCALE_HEAD \
46 for(w = 0; w < video->out_w; w++) \
48 uv_subscript = video->x_table[w] / 2; \
49 y_l = y_in[video->x_table[w]]; \
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++) \
58 uv_subscript = video->x_table[w] / 2; \
59 y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \
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 \
69 for(w = 0; w < video->horizontal_size; w++) \
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++) \
80 y_l = mpeg3_601_to_rgb[*y_in++]; \
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;
95 #define STORE_PIXEL_BGR888 \
96 *data++ = CLIP(b_l); \
97 *data++ = CLIP(g_l); \
100 #define STORE_PIXEL_BGRA8888 \
101 *data++ = CLIP(b_l); \
102 *data++ = CLIP(g_l); \
103 *data++ = CLIP(r_l); \
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); \
113 #define STORE_PIXEL_RGB888 \
114 *data++ = CLIP(r_l); \
115 *data++ = CLIP(g_l); \
118 #define STORE_PIXEL_RGBA8888 \
119 *data++ = CLIP(r_l); \
120 *data++ = CLIP(g_l); \
121 *data++ = CLIP(b_l); \
124 #define STORE_PIXEL_RGBA16161616 \
125 *data_s++ = CLIP(r_l); \
126 *data_s++ = CLIP(g_l); \
127 *data_s++ = CLIP(b_l); \
132 /* Only good for YUV 4:2:0 */
133 int mpeg3video_ditherframe(mpeg3video_t
*video
,
135 unsigned char **output_rows
)
138 unsigned char *y_in
, *cb_in
, *cr_in
;
139 int y_l
, r_l
, b_l
, g_l
;
141 int uv_subscript
, step
, w
= -1;
146 /* Transfer row with scaling */
147 if(video
->out_w
!= video
->horizontal_size
)
149 switch(video
->color_model
)
176 case MPEG3_601_BGR888
:
177 DITHER_SCALE_601_HEAD
181 case MPEG3_601_BGRA8888
:
182 DITHER_SCALE_601_HEAD
186 case MPEG3_601_RGB565
:
187 DITHER_SCALE_601_HEAD
191 case MPEG3_601_RGB888
:
192 DITHER_SCALE_601_HEAD
196 case MPEG3_601_RGBA8888
:
197 DITHER_SCALE_601_HEAD
201 case MPEG3_RGBA16161616
:
203 register unsigned short *data_s
= (unsigned short*)data
;
205 STORE_PIXEL_RGBA16161616
213 /* Transfer row unscaled */
214 switch(video
->color_model
)
241 case MPEG3_601_BGR888
:
246 case MPEG3_601_BGRA8888
:
251 case MPEG3_601_RGB565
:
256 case MPEG3_601_RGB888
:
261 case MPEG3_601_RGBA8888
:
266 case MPEG3_RGBA16161616
:
268 register unsigned short *data_s
= (unsigned short*)data
;
270 STORE_PIXEL_RGBA16161616
281 int mpeg3video_ditherframe444(mpeg3video_t
*video
, unsigned char *src
[])
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
[])
296 int mpeg3video_ditherbot(mpeg3video_t
*video
, unsigned char *src
[])
301 int mpeg3video_ditherbot444(mpeg3video_t
*video
, unsigned char *src
[])
306 void memcpy_fast(unsigned char *output
, unsigned char *input
, long len
)
309 /* 8 byte alignment */
311 * if(!((long)input & 0x7))
314 * for(i = 0; i < len2; )
316 * ((int64_t*)output)[i] = ((int64_t*)input)[i];
318 * ((int64_t*)output)[i] = ((int64_t*)input)[i];
322 * for(i *= 16; i < len; i++)
324 * output[i] = input[i];
329 memcpy(output
, input
, len
);
332 int mpeg3video_init_output()
335 for(i
= 0; i
< 256; i
++)
337 value
= (int)(1.1644 * i
- 255 * 0.0627 + 0.5);
338 if(value
< 0) value
= 0;
340 if(value
> 255) value
= 255;
341 mpeg3_601_to_rgb
[i
] = value
;
346 int mpeg3video_present_frame(mpeg3video_t
*video
)
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 */
358 long offset0
, offset1
;
359 int chroma_denominator
;
361 if(video
->chroma_format
== CHROMA420
)
362 chroma_denominator
= 2;
364 chroma_denominator
= 1;
367 if(!video
->y_output
) return 0;
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
);
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
;
402 row_span
= video
->row_span
;
404 row_span0
= row_span
;
405 row_span1
= (row_span
>> 1);
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
,
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),
424 memcpy(video
->v_output
+ i
/ chroma_denominator
* row_span1
,
425 src
[2] + offset1
+ (video
->in_x
>> 1),
427 if(video
->horizontal_size
< video
->in_w
)
429 memset(video
->u_output
+
430 i
/ chroma_denominator
* row_span1
+
431 (video
->horizontal_size
>> 1),
434 (video
->horizontal_size
>> 1));
435 memset(video
->v_output
+
436 i
/ chroma_denominator
* row_span1
+
437 (video
->horizontal_size
>> 1),
440 (video
->horizontal_size
>> 1));
445 if(chroma_denominator
== 1 || (i
% 2))
446 offset1
+= video
->chrom_width
;
453 /* Want RGB buffer */
454 /* Copy the frame to the output with YUV to RGB conversion */
457 if(video
->chroma_format
!= CHROMA444
)
459 mpeg3video_ditherframe(video
, src
, video
->output_rows
);
462 mpeg3video_ditherframe444(video
, src
);
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
);
477 mpeg3video_dithertop444(video
, src
);
478 mpeg3video_ditherbot444(video
, src
);
483 /* bottom field first */
484 if(video
->chroma_format
!= CHROMA444
)
486 mpeg3video_ditherbot(video
, src
);
487 mpeg3video_dithertop(video
, src
);
491 mpeg3video_ditherbot444(video
, src
);
492 mpeg3video_dithertop444(video
, src
);
499 int mpeg3video_display_second_field(mpeg3video_t
*video
)