/* -*- 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 #ifdef USE_GUI #include "player.h" Player::Player(volatile int *grunning, sem_t *gsem, Queue *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 */