Update Copyright
[rawv.git] / view.cpp
blob8d59366857e480d0509c0cd5bd6d282fc400dca2
1 /* view submodule for rawv
2 * Copyright (C) 2010,2011 Kirill Smelkov <kirr@navytux.spb.ru>
3 * Copyright (C) 2011 Marine Bridge and Navigation Systems (http://mns.spb.ru/)
5 * This library is free software: you can Use, Study, Modify and Redistribute
6 * it under the terms of the GNU Lesser General Public License version 2.1, or
7 * any later version. This library is distributed WITHOUT ANY WARRANTY. See
8 * COPYING.LIB file for full License terms.
9 */
11 #include "rawv.h"
13 #include <stdio.h>
14 #include <SDL.h>
15 #include "sdlu.h"
17 using std::min;
19 namespace rawv {
21 /******** View ********/
23 View::View(int width, int height, bool upscale, const char *title)
25 fprintf(stderr, "Viewing w: %i h: %i upscale: %i\n", width, height, upscale);
27 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
28 die("SDL_INIT_VIDEO: %s", SDL_GetError());
30 display = SDL_SetVideoMode(width, height, /*bpp=*/0, /*flags=*/0UL);
31 if (!display)
32 die("SDL_SetVideoMode: %s", SDL_GetError());
34 if (title)
35 SDL_WM_SetCaption(title, NULL);
37 overlay = SDL_CreateYUVOverlay(width, height, SDL_YUY2_OVERLAY, display);
38 if (!overlay)
39 die("SDL_CreateYUVOverlay: %s", SDL_GetError());
41 this->upscale = upscale;
45 View::~View()
47 SDL_FreeYUVOverlay(overlay);
48 SDL_QuitSubSystem(SDL_INIT_VIDEO); // XXX needed at all?
52 void View::display_frame(const Frame *f)
54 #if 0
55 double tstamp = buf->timestamp.tv_sec + 1E-6*buf->timestamp.tv_usec;
57 fprintf(stderr, "buf[%i] timestamp: %.7lf sequence: %u\n", buf->index, tstamp, buf->sequence);
58 #endif
60 SDL_Rect rsrc, rdst;
61 int w, h;
62 int i, j, istart;
63 int bt;
66 w = min(f->width, overlay->w);
67 h = min(f->height, overlay->h);
69 bt = f->interlace_tb_swapped;
70 if (bt)
71 /* bt=+1 -> h=2k
72 * bt=-1 -> h=2k-1
74 h = (h & ~1U) - int((1-bt)/2);
76 /* for bt=-1, we have to start from 1, for bt=0,+1 - from 0'th line */
77 istart = 0;
78 if (bt==-1) {
79 istart = 1;
80 bt = -bt; /* account for i 0->1 move */
84 SDL_LockYUVOverlay(overlay);
86 switch (f->pixfmt_4cc) {
87 case MKTAG32('Y','U','Y','V'):
88 case MKTAG32('Y','U','Y','2'):
90 if (
91 overlay->pitches[0] == f->bytesperline &&
92 overlay->w == f->width && w == f->width &&
93 overlay->h == f->height && h == f->height &&
94 !bt
97 /* special case for w=w, h=h, fmt=fmt, stride=stride, lines=01234... -- one large memcpy */
98 memcpy(overlay->pixels[0], f->start, h*w * /*pixsize_yuy2*/ 2);
100 else {
101 for (i=istart; i<h; ++i) {
102 memcpy(overlay->pixels[0] + (i+bt)*overlay->pitches[0],
103 f->start + i*f->bytesperline,
104 w * /*pixsize_yuy2*/ 2);
106 bt = -bt;
110 break;
112 case MKTAG32('U','Y','V','Y'):
114 /* TODO optimize me through mmx */
115 for (i=istart; i<h; ++i) {
116 __u8 *dst = overlay->pixels[0] + (i+bt)*overlay->pitches[0];
117 __u8 *src = f->start + i*f->bytesperline;
119 for (j=0; j<w/2; j++) {
120 /* YUYV <- UYVY */
121 dst[0] = src[1];
122 dst[1] = src[0];
123 dst[2] = src[3];
124 dst[3] = src[2];
126 dst += 4;
127 src += 4;
130 bt = -bt;
133 break;
135 case MKTAG32('Y','8','0','0'):
136 case MKTAG32('Y','8',' ',' '):
137 case MKTAG32('G','R','E','Y'):
139 for (i=istart; i<h; ++i) {
140 __u8 *dst = overlay->pixels[0] + (i+bt)*overlay->pitches[0];
141 __u8 *src = f->start + i*f->bytesperline;
143 for (j=0; j<w; ++j) {
144 dst[0] = src[0];
145 dst[1] = 0x80; /* 0-level for Cb/Cr */
147 dst += 2;
148 src += 1;
151 bt = -bt;
154 break;
156 default:
157 die("view: W: unsupported pixfmt 0x%08x", f->pixfmt_4cc);
162 SDL_UnlockYUVOverlay(overlay);
164 /* blit overlay to its associated surface */
165 rsrc.x = 0;
166 rsrc.y = 0;
167 rsrc.w = w;
168 rsrc.h = h;
170 rdst.x = 0;
171 rdst.y = 0;
173 if (!upscale) {
174 rdst.w = w;
175 rdst.h = h;
177 else {
178 double ratio_w = (double)overlay->w / (w ? w : 1);
179 double ratio_h = (double)overlay->h / (h ? h : 1);
181 /* keep aspect ratio */
182 double ratio = min(ratio_w, ratio_h);
184 rdst.w = w * ratio;
185 rdst.h = h * ratio;
187 /* center picture */
188 rdst.x = w * (ratio_w - ratio) / 2;
189 rdst.y = h * (ratio_h - ratio) / 2;
192 SDLU_DisplayYUVOverlay(overlay, &rsrc, &rdst);
196 void View::__display_frame(const Frame *f, void *self)
198 ((View *)self)->display_frame(f);
202 } // rawv::