diff options
Diffstat (limited to 'src/player.cc')
-rw-r--r-- | src/player.cc | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/player.cc b/src/player.cc new file mode 100644 index 0000000..a860afa --- /dev/null +++ b/src/player.cc @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004 Bent Bisballe + * Copyright (C) 2004 B. Stultiens + * Copyright (C) 2004 Koen Otter and Glenn van der Meyden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <config.h> +#ifdef USE_GUI + +#include "player.h" + +Player::Player(volatile int *grunning, + sem_t *gsem, + Queue<FFFrame> *gqueue, + pthread_mutex_t *gmutex) +{ + running = grunning; + sem = gsem; + queue = gqueue; + mutex = gmutex; + + sem_init(&play_sem, 0, 1); + + if(SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); + exit(1); + } + screen = SDL_SetVideoMode(DISPLAYWIDTH, + DISPLAYHEIGHT, + 16, + SDL_HWSURFACE|SDL_ANYFORMAT|SDL_HWACCEL); + if(!screen) { + fprintf(stderr, "Unable to set %dx%d video: %s\n", + DISPLAYWIDTH, DISPLAYHEIGHT, SDL_GetError()); + exit(1); + } + + overlay = SDL_CreateYUVOverlay(DISPLAYWIDTH, DISPLAYHEIGHT, SDL_IYUV_OVERLAY, screen); +} + +Player::~Player() +{ + if(overlay) + SDL_FreeYUVOverlay(overlay); + SDL_Quit(); +} + +void Player::player() +{ + SDL_Event event; + SDL_Rect rect; + FFFrame *f; + AVPicture pict; + int i; + struct timespec ts; + + // rect.x = 20; + // rect.y = 182; + rect.x = 0; + rect.y = 0; + rect.w = DISPLAYWIDTH; + rect.h = DISPLAYHEIGHT; + + //+++++Reference to the overlay pixels/pitches, only after creating a new overlay+++++ + for(i = 0; i < 3; i++) { + pict.data[i] = overlay->pixels[i]; + pict.linesize[i] = overlay->pitches[i]; + } + + while(*running) { + // Wait for the semaphore to be free... then run + sem_wait(&play_sem); + sem_post(&play_sem); + + if(!SDL_WaitEvent(&event)) break; // FIXME: Gracefull exit... + + switch(event.type) { + case SDL_KEYDOWN: + switch(event.key.keysym.sym) { + case SDLK_q: + case SDLK_ESCAPE: + goto quitit; + default: + break; + } + break; + + case SDL_USEREVENT: + pthread_mutex_lock(mutex); + f = queue->pop(); + pthread_mutex_unlock(mutex); + if(!f) break; + + img_convert(&pict, PIX_FMT_YUV420P, (AVPicture *)f->frame, + PIX_FMT_YUV420P, DISPLAYWIDTH, DISPLAYHEIGHT); + + SDL_LockYUVOverlay(overlay); + overlay->pixels = pict.data; + SDL_UnlockYUVOverlay(overlay); + SDL_DisplayYUVOverlay(overlay, &rect); + break; + + case SDL_QUIT: + quitit: + *running = 0; + break; + + default: + break; + } + } + /* Remove any late buffer */ + /* We don't care, the encoder finishes them all */ + ts.tv_sec = 0; + ts.tv_nsec = 100000000L; // 100ms + nanosleep(&ts, NULL); + + pthread_mutex_lock(mutex); + f = queue->pop(); + pthread_mutex_unlock(mutex); + if(f) delete f; +} + +void Player::run() +{ + player(); +} + +void Player::start() +{ + sem_post(&play_sem); +} + +void Player::stop() +{ + sem_wait(&play_sem); +} + +#endif /* USE_GUI */ |