summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xine_frontend.c105
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);