00001 #include "../libmpeg3.h"
00002 #include "mpeg3video.h"
00003 #include <string.h>
00004
00005 #define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
00006
00007
00008 static unsigned char mpeg3_601_to_rgb[256];
00009
00010
00011
00012
00013
00014
00015
00016 #define DITHER_ROW_HEAD \
00017 for(h = 0; h < video->out_h; h++) \
00018 { \
00019 y_in = &src[0][(video->y_table[h] + video->in_y) * \
00020 video->coded_picture_width] + \
00021 video->in_x; \
00022 if(video->chroma_format == CHROMA420) \
00023 { \
00024 cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * \
00025 video->chrom_width] + \
00026 (video->in_x >> 1); \
00027 cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * \
00028 video->chrom_width] + \
00029 (video->in_x >> 1); \
00030 } \
00031 else \
00032 { \
00033 cb_in = &src[1][(video->y_table[h] + video->in_y) * \
00034 video->chrom_width] + \
00035 (video->in_x >> 1); \
00036 cr_in = &src[2][(video->y_table[h] + video->in_y) * \
00037 video->chrom_width] + \
00038 (video->in_x >> 1); \
00039 } \
00040 data = output_rows[h];
00041
00042 #define DITHER_ROW_TAIL \
00043 }
00044
00045 #define DITHER_SCALE_HEAD \
00046 for(w = 0; w < video->out_w; w++) \
00047 { \
00048 uv_subscript = video->x_table[w] / 2; \
00049 y_l = y_in[video->x_table[w]]; \
00050 y_l <<= 16; \
00051 r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
00052 g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
00053 b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
00054
00055 #define DITHER_SCALE_601_HEAD \
00056 for(w = 0; w < video->out_w; w++) \
00057 { \
00058 uv_subscript = video->x_table[w] / 2; \
00059 y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \
00060 y_l <<= 16; \
00061 r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
00062 g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
00063 b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
00064
00065 #define DITHER_SCALE_TAIL \
00066 }
00067
00068 #define DITHER_HEAD \
00069 for(w = 0; w < video->horizontal_size; w++) \
00070 { \
00071 y_l = *y_in++; \
00072 y_l <<= 16; \
00073 r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
00074 g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
00075 b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
00076
00077 #define DITHER_601_HEAD \
00078 for(w = 0; w < video->horizontal_size; w++) \
00079 { \
00080 y_l = mpeg3_601_to_rgb[*y_in++]; \
00081 y_l <<= 16; \
00082 r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
00083 g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
00084 b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
00085
00086 #define DITHER_TAIL \
00087 if(w & 1) \
00088 { \
00089 cr_in++; \
00090 cb_in++; \
00091 } \
00092 }
00093
00094
00095 #define STORE_PIXEL_BGR888 \
00096 *data++ = CLIP(b_l); \
00097 *data++ = CLIP(g_l); \
00098 *data++ = CLIP(r_l);
00099
00100 #define STORE_PIXEL_BGRA8888 \
00101 *data++ = CLIP(b_l); \
00102 *data++ = CLIP(g_l); \
00103 *data++ = CLIP(r_l); \
00104 *data++ = 0;
00105
00106 #define STORE_PIXEL_RGB565 \
00107 *(*(unsigned short**)(&data))++ = \
00108 ((CLIP(r_l) & 0xf8) << 8) | \
00109 ((CLIP(g_l) & 0xfc) << 3) | \
00110 ((CLIP(b_l) & 0xf8) >> 3); \
00111 data += 2;
00112
00113 #define STORE_PIXEL_RGB888 \
00114 *data++ = CLIP(r_l); \
00115 *data++ = CLIP(g_l); \
00116 *data++ = CLIP(b_l);
00117
00118 #define STORE_PIXEL_RGBA8888 \
00119 *data++ = CLIP(r_l); \
00120 *data++ = CLIP(g_l); \
00121 *data++ = CLIP(b_l); \
00122 *data++ = 0;
00123
00124 #define STORE_PIXEL_RGBA16161616 \
00125 *data_s++ = CLIP(r_l); \
00126 *data_s++ = CLIP(g_l); \
00127 *data_s++ = CLIP(b_l); \
00128 *data_s++ = 0;
00129
00130
00131
00132
00133 int mpeg3video_ditherframe(mpeg3video_t *video,
00134 unsigned char **src,
00135 unsigned char **output_rows)
00136 {
00137 int h = 0;
00138 unsigned char *y_in, *cb_in, *cr_in;
00139 int y_l, r_l, b_l, g_l;
00140 unsigned char *data;
00141 int uv_subscript, step, w = -1;
00142
00143
00144
00145 DITHER_ROW_HEAD
00146
00147 if(video->out_w != video->horizontal_size)
00148 {
00149 switch(video->color_model)
00150 {
00151 case MPEG3_BGR888:
00152 DITHER_SCALE_HEAD
00153 STORE_PIXEL_BGR888
00154 DITHER_SCALE_TAIL
00155 break;
00156 case MPEG3_BGRA8888:
00157 DITHER_SCALE_HEAD
00158 STORE_PIXEL_BGRA8888
00159 DITHER_SCALE_TAIL
00160 break;
00161 case MPEG3_RGB565:
00162 DITHER_SCALE_HEAD
00163 STORE_PIXEL_RGB565
00164 DITHER_SCALE_TAIL
00165 break;
00166 case MPEG3_RGB888:
00167 DITHER_SCALE_HEAD
00168 STORE_PIXEL_RGB888
00169 DITHER_SCALE_TAIL
00170 break;
00171 case MPEG3_RGBA8888:
00172 DITHER_SCALE_HEAD
00173 STORE_PIXEL_RGBA8888
00174 DITHER_SCALE_TAIL
00175 break;
00176 case MPEG3_601_BGR888:
00177 DITHER_SCALE_601_HEAD
00178 STORE_PIXEL_BGR888
00179 DITHER_SCALE_TAIL
00180 break;
00181 case MPEG3_601_BGRA8888:
00182 DITHER_SCALE_601_HEAD
00183 STORE_PIXEL_BGRA8888
00184 DITHER_SCALE_TAIL
00185 break;
00186 case MPEG3_601_RGB565:
00187 DITHER_SCALE_601_HEAD
00188 STORE_PIXEL_RGB565
00189 DITHER_SCALE_TAIL
00190 break;
00191 case MPEG3_601_RGB888:
00192 DITHER_SCALE_601_HEAD
00193 STORE_PIXEL_RGB888
00194 DITHER_SCALE_TAIL
00195 break;
00196 case MPEG3_601_RGBA8888:
00197 DITHER_SCALE_601_HEAD
00198 STORE_PIXEL_RGBA8888
00199 DITHER_SCALE_TAIL
00200 break;
00201 case MPEG3_RGBA16161616:
00202 {
00203 register unsigned short *data_s = (unsigned short*)data;
00204 DITHER_SCALE_HEAD
00205 STORE_PIXEL_RGBA16161616
00206 DITHER_SCALE_TAIL
00207 }
00208 break;
00209 }
00210 }
00211 else
00212 {
00213
00214 switch(video->color_model)
00215 {
00216 case MPEG3_BGR888:
00217 DITHER_HEAD
00218 STORE_PIXEL_BGR888
00219 DITHER_TAIL
00220 break;
00221 case MPEG3_BGRA8888:
00222 DITHER_HEAD
00223 STORE_PIXEL_BGRA8888
00224 DITHER_TAIL
00225 break;
00226 case MPEG3_RGB565:
00227 DITHER_HEAD
00228 STORE_PIXEL_RGB565
00229 DITHER_TAIL
00230 break;
00231 case MPEG3_RGB888:
00232 DITHER_HEAD
00233 STORE_PIXEL_RGB888
00234 DITHER_TAIL
00235 break;
00236 case MPEG3_RGBA8888:
00237 DITHER_HEAD
00238 STORE_PIXEL_RGBA8888
00239 DITHER_TAIL
00240 break;
00241 case MPEG3_601_BGR888:
00242 DITHER_601_HEAD
00243 STORE_PIXEL_BGR888
00244 DITHER_TAIL
00245 break;
00246 case MPEG3_601_BGRA8888:
00247 DITHER_601_HEAD
00248 STORE_PIXEL_BGRA8888
00249 DITHER_TAIL
00250 break;
00251 case MPEG3_601_RGB565:
00252 DITHER_601_HEAD
00253 STORE_PIXEL_RGB565
00254 DITHER_TAIL
00255 break;
00256 case MPEG3_601_RGB888:
00257 DITHER_601_HEAD
00258 STORE_PIXEL_RGB888
00259 DITHER_TAIL
00260 break;
00261 case MPEG3_601_RGBA8888:
00262 DITHER_601_HEAD
00263 STORE_PIXEL_RGBA8888
00264 DITHER_TAIL
00265 break;
00266 case MPEG3_RGBA16161616:
00267 {
00268 register unsigned short *data_s = (unsigned short*)data;
00269 DITHER_HEAD
00270 STORE_PIXEL_RGBA16161616
00271 DITHER_TAIL
00272 }
00273 break;
00274 }
00275 }
00276 DITHER_ROW_TAIL
00277
00278 return 0;
00279 }
00280
00281 int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[])
00282 {
00283 return 0;
00284 }
00285
00286 int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[])
00287 {
00288 return mpeg3video_ditherframe(video, src, video->output_rows);
00289 }
00290
00291 int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[])
00292 {
00293 return 0;
00294 }
00295
00296 int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[])
00297 {
00298 return 0;
00299 }
00300
00301 int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[])
00302 {
00303 return 0;
00304 }
00305
00306 void memcpy_fast(unsigned char *output, unsigned char *input, long len)
00307 {
00308 int i, len2;
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 memcpy(output, input, len);
00330 }
00331
00332 int mpeg3video_init_output()
00333 {
00334 int i, value;
00335 for(i = 0; i < 256; i++)
00336 {
00337 value = (int)(1.1644 * i - 255 * 0.0627 + 0.5);
00338 if(value < 0) value = 0;
00339 else
00340 if(value > 255) value = 255;
00341 mpeg3_601_to_rgb[i] = value;
00342 }
00343 return 0;
00344 }
00345
00346 int mpeg3video_present_frame(mpeg3video_t *video)
00347 {
00348 int i, j, k, l;
00349 unsigned char *src[3];
00350 src[0] = video->output_src[0];
00351 src[1] = video->output_src[1];
00352 src[2] = video->output_src[2];
00353
00354
00355 if(video->want_yvu)
00356 {
00357 long size0, size1;
00358 long offset0, offset1;
00359 int chroma_denominator;
00360
00361 if(video->chroma_format == CHROMA420)
00362 chroma_denominator = 2;
00363 else
00364 chroma_denominator = 1;
00365
00366
00367 if(!video->y_output) return 0;
00368
00369
00370
00371 if(video->in_x == 0 &&
00372 video->in_w >= video->coded_picture_width &&
00373 video->row_span == video->coded_picture_width)
00374 {
00375 size0 = video->coded_picture_width * video->in_h;
00376 size1 = video->chrom_width * (int)((float)video->in_h / chroma_denominator + 0.5);
00377 offset0 = video->coded_picture_width * video->in_y;
00378 offset1 = video->chrom_width * (int)((float)video->in_y / chroma_denominator + 0.5);
00379
00380 printf("mpeg3video_present_frame 1\n");
00381
00382
00383
00384
00385
00386
00387
00388
00389 memcpy(video->y_output, src[0] + offset0, size0);
00390 memcpy(video->u_output, src[1] + offset1, size1);
00391 memcpy(video->v_output, src[2] + offset1, size1);
00392 }
00393 else
00394
00395 {
00396
00397 int row_span = video->in_w;
00398 int row_span0;
00399 int row_span1;
00400
00401 if(video->row_span)
00402 row_span = video->row_span;
00403
00404 row_span0 = row_span;
00405 row_span1 = (row_span >> 1);
00406 size0 = video->in_w;
00407 size1 = (video->in_w >> 1);
00408 offset0 = video->coded_picture_width * video->in_y;
00409 offset1 = video->chrom_width * video->in_y / chroma_denominator;
00410
00411 for(i = 0; i < video->in_h; i++)
00412 {
00413 memcpy(video->y_output + i * row_span0,
00414 src[0] + offset0 + video->in_x,
00415 size0);
00416
00417 offset0 += video->coded_picture_width;
00418
00419 if(chroma_denominator == 1 || !(i % 2))
00420 {
00421 memcpy(video->u_output + i / chroma_denominator * row_span1,
00422 src[1] + offset1 + (video->in_x >> 1),
00423 size1);
00424 memcpy(video->v_output + i / chroma_denominator * row_span1,
00425 src[2] + offset1 + (video->in_x >> 1),
00426 size1);
00427 if(video->horizontal_size < video->in_w)
00428 {
00429 memset(video->u_output +
00430 i / chroma_denominator * row_span1 +
00431 (video->horizontal_size >> 1),
00432 0x80,
00433 (video->in_w >> 1) -
00434 (video->horizontal_size >> 1));
00435 memset(video->v_output +
00436 i / chroma_denominator * row_span1 +
00437 (video->horizontal_size >> 1),
00438 0x80,
00439 (video->in_w >> 1) -
00440 (video->horizontal_size >> 1));
00441 }
00442 }
00443
00444
00445 if(chroma_denominator == 1 || (i % 2))
00446 offset1 += video->chrom_width;
00447 }
00448 }
00449
00450 return 0;
00451 }
00452
00453
00454
00455 if(video->prog_seq)
00456 {
00457 if(video->chroma_format != CHROMA444)
00458 {
00459 mpeg3video_ditherframe(video, src, video->output_rows);
00460 }
00461 else
00462 mpeg3video_ditherframe444(video, src);
00463 }
00464 else
00465 {
00466 if((video->pict_struct == FRAME_PICTURE && video->topfirst) ||
00467 video->pict_struct == BOTTOM_FIELD)
00468 {
00469
00470 if(video->chroma_format != CHROMA444)
00471 {
00472 mpeg3video_dithertop(video, src);
00473 mpeg3video_ditherbot(video, src);
00474 }
00475 else
00476 {
00477 mpeg3video_dithertop444(video, src);
00478 mpeg3video_ditherbot444(video, src);
00479 }
00480 }
00481 else
00482 {
00483
00484 if(video->chroma_format != CHROMA444)
00485 {
00486 mpeg3video_ditherbot(video, src);
00487 mpeg3video_dithertop(video, src);
00488 }
00489 else
00490 {
00491 mpeg3video_ditherbot444(video, src);
00492 mpeg3video_dithertop444(video, src);
00493 }
00494 }
00495 }
00496 return 0;
00497 }
00498
00499 int mpeg3video_display_second_field(mpeg3video_t *video)
00500 {
00501
00502 return 0;
00503 }