diff options
Diffstat (limited to 'xine_frontend.c')
-rw-r--r-- | xine_frontend.c | 105 |
1 files changed, 90 insertions, 15 deletions
diff --git a/xine_frontend.c b/xine_frontend.c index 96f9640f..40d8ce79 100644 --- a/xine_frontend.c +++ b/xine_frontend.c @@ -4,7 +4,7 @@ * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * - * $Id: xine_frontend.c,v 1.90 2008-11-16 15:27:54 rofafor Exp $ + * $Id: xine_frontend.c,v 1.91 2008-11-19 01:08:39 phintuka Exp $ * */ @@ -1645,6 +1645,89 @@ static char *frame_compress_jpeg(fe_t *this, int *size, int quality, vo_frame_t #endif /* HAVE_LIBJPEG */ +static vo_frame_t *yv12_to_yuy2_frame(xine_stream_t *stream, vo_frame_t *frame) +{ + /* convert yv12 frames to yuy2 */ + if (frame->format == XINE_IMGFMT_YV12) { + stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0); + vo_frame_t *img = stream->video_out->get_frame (stream->video_out, + frame->width, frame->height, + frame->ratio, XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + stream->xine->port_ticket->release(stream->xine->port_ticket, 0); + + if (!img) { + LOGMSG("yv12_to_yuy2_frame: get_frame failed"); + frame->free(frame); + return NULL; + } + + init_yuv_conversion(); + yv12_to_yuy2(frame->base[0], frame->pitches[0], + frame->base[1], frame->pitches[1], + frame->base[2], frame->pitches[2], + img->base[0], img->pitches[0], + frame->width, frame->height, + frame->progressive_frame); + + frame->free(frame); + return img; + } + + return frame; +} + +#define YCBCR_TO_RGB( y, cb, cr, r, g, b ) \ + do { \ + int _y, _cb, _cr, _r, _g, _b; \ + _y = ((y) - 16) * 76309; \ + _cb = (cb) - 128; \ + _cr = (cr) - 128; \ + _r = (_y + _cr * 104597 + 0x8000) >> 16; \ + _g = (_y - _cb * 25675 - _cr * 53279 + 0x8000) >> 16; \ + _b = (_y + _cb * 132201 + 0x8000) >> 16; \ + (r) = (_r < 0) ? 0 : ((_r > 255) ? 255 : _r); \ + (g) = (_g < 0) ? 0 : ((_g > 255) ? 255 : _g); \ + (b) = (_b < 0) ? 0 : ((_b > 255) ? 255 : _b); \ +} while (0) + +static char *frame_compress_pnm(fe_t *this, int *size, vo_frame_t *frame) +{ + /* ensure yuy2 */ + if (!(frame = yv12_to_yuy2_frame(this->stream, frame))) + return NULL; + + /* convert to PNM */ + + /* allocate memory for result */ + size_t bytes = frame->width * frame->height * 3; + uint8_t *pnm = malloc(bytes + 64); + if (!pnm) { + LOGMSG("fe_grab: malloc failed"); + return NULL; + } + + /* PNM header */ + sprintf((char*)pnm, "P6\n%d\n%d\n255\n", frame->width, frame->height); + int hdrlen = strlen((char*)pnm); + uint8_t *p = pnm + hdrlen; + uint8_t *s = frame->base[0]; + int x, y; + + *size = bytes + hdrlen; + + /* convert to RGB */ + for (y=0; y < frame->height; y++) { + for (x=0; x < frame->width; x+=2, s+=4, p+=6) { + YCBCR_TO_RGB(s[0], s[1], s[3], p[0], p[1], p[2]); + YCBCR_TO_RGB(s[2], s[1], s[3], p[3], p[4], p[5]); + } + s = frame->base[0] + y*frame->pitches[0]; + } + + return (char*)pnm; +} + static char *fe_grab(frontend_t *this_gen, int *size, int jpeg, int quality, int width, int height) { @@ -1658,15 +1741,6 @@ static char *fe_grab(frontend_t *this_gen, int *size, int jpeg, } #endif /* HAVE_LIBJPEG */ -#ifndef PPM_SUPPORTED - if(!jpeg) { - LOGMSG("fe_grab: PPM grab not implemented"); - return 0; - } -#else - /* #warning TODO: convert to RGB PPM */ -#endif - if(!find_input_plugin(this)) return 0; @@ -1694,11 +1768,12 @@ static char *fe_grab(frontend_t *this_gen, int *size, int jpeg, } /* Scale image */ - /* #warning TODO: no scaling implemented */ - if(width != frame->width) - width = frame->width; - if(height != frame->height) - height = frame->height; + if (frame->width != width || frame->height != height) { + /* #warning TODO - scaling here */ + } + + if (!jpeg) + return frame_compress_pnm(this, size, frame); #ifdef HAVE_LIBJPEG return frame_compress_jpeg(this, size, quality, frame); |