?? overlay.h
字號:
/* * Copyright (C) 2005-2007 gulikoza * * 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. *//* $Id$ */#ifndef RENDERER_H#define RENDERER_H#define MODULE "Renderer"class Renderer : public Thread {private: MUTEX * data; MUTEX * display_lock; Videoinfo info; volatile bool sleeping; // Output mode Output * output; // Frame buffers and queue Frame frames[FRAMES]; QUEUE queue; int current_frame; // Internal routines for locking frame data int LockFrame(void) { // Wait until current frame is valid while((current_frame = queue.GetUsed()) == 0x80000000) { MUTEX_LOCK(data); sleeping = true; MUTEX_UNLOCK(data); // Wait and exit if required if(!ThreadPause()) return -1; MUTEX_LOCK(data); sleeping = false; MUTEX_UNLOCK(data); } return current_frame; } void UnlockFrame() { queue.AddFree(~current_frame); }protected: int Run(); int CreateOutput(OUTPUT);public: Renderer(OUTPUT output_mode):sleeping(false),output(NULL) { // Fill info structure info.changed = false; info.w = info.h = 0; info.cropx = info.cropy = 0; info.colorspace = SDL_IYUV_OVERLAY; info.display_change = SDL_CreateSemaphore(0); info.surface = NULL; info.aspect = 0.0; if(info.display_change == NULL) throw "Renderer: Failed to create semaphore"; data = MUTEX_CREATE(); if(data == NULL) throw "Renderer: Failed to create mutex"; display_lock = MUTEX_CREATE(); if(display_lock == NULL) throw "Renderer: Failed to create mutex"; for(unsigned int i = 0; i < FRAMES; i++) { frames[i].data[0] = NULL; queue.AddFree(i); } // Create output class CreateOutput(output_mode); DEBUG_MSG("Created renderer object"); } void FlushBuffers() { MUTEX_LOCK(data); LOG_MSG("Flushing buffers"); sleeping = false; queue.Flush(); ThreadUnpause(); // Wait for the thread to go to sleep while((!sleeping) && ThreadStatus()) { MUTEX_UNLOCK(data); SDL_Delay(10); LOG_MSG("Waiting for child thread to finish processing..."); MUTEX_LOCK(data); } for(int i = 0; i < FRAMES; i++) { if(frames[i].data[0]) _aligned_free(frames[i].data[0]); frames[i].data[0] = NULL; frames[i].w = frames[i].h = 0; queue.AddFree(i); } MUTEX_UNLOCK(data); LOG_MSG("Flush complete"); } // Call to get writable buffer void LockData(Frame * pt) { int i, l = 0; while((i = queue.GetFree()) < 0) { // crap...we've overrun the render thread if(!ThreadStatus() || (++l > 50)) { // Render thread is not running ? ERROR_MSG("Child thread not running!?"); pt->id = -1; return; } LOG_MSG("Waiting for free frame..."); SDL_Delay(20); } pt->id = i; Frame * fp = &frames[i]; DEBUG_MSG("Allocating frame %d", i); // Check if size changed if((pt->pitch != fp->pitch) || (pt->h != fp->h) || (pt->edge != fp->edge)) { fp->w = pt->w; fp->h = pt->h; fp->pitch = pt->pitch; fp->edge = pt->edge; if(fp->data[0]) _aligned_free(fp->data[0]); fp->data[0] = NULL; } // Allocate buffer if(fp->data[0] == NULL) { i = ((fp->pitch)*(fp->h+(fp->edge<<1)))>>1; fp->data[0] = (unsigned char*)_aligned_malloc(3*i, 64); LOG_MSG("Allocated %d bytes (%dx%d) at 0x%p", 3*i, fp->pitch, fp->h+(fp->edge<<1), fp->data[0]); if(fp->data[0] == NULL) { ERROR_MSG("Unable to allocate memory!"); queue.ReturnUsed(pt->id, false); pt->id = -1; return; } fp->data[1] = fp->data[0] + (i<<1); fp->data[2] = fp->data[1] + (i>>1); } pt->data[0] = fp->data[0]; pt->data[1] = fp->data[1]; pt->data[2] = fp->data[2]; } void UnlockData(int id, Frame * frame) { if(frame == NULL) { queue.ReturnUsed(id, false); return; } frames[id].changed = frame->changed; frames[id].aspect = frame->aspect; frames[id].time = frame->time; frames[id].pts = frame->pts; queue.ReturnUsed(id, true); ThreadUnpause(); } void ReleaseData(int id) { queue.Release(id); } void SetDeinterlace(int d); void Lock() { DEBUG_MSG("Display lock requested from %u", SDL_ThreadID()); if(MUTEX_LOCK(display_lock) == 0) { DEBUG_MSG("Lock() OK to %u", SDL_ThreadID()); return; } ERROR_MSG("Mutex lock failed!"); } void Unlock() { DEBUG_MSG("Display lock requested from %u", SDL_ThreadID()); if(MUTEX_UNLOCK(display_lock) == 0) { DEBUG_MSG("Unlock() OK to %u", SDL_ThreadID()); return; } ERROR_MSG("Mutex unlock failed!"); } Videoinfo * GetInfo() { return &info; } ~Renderer();};#undef MODULE#endif // RENDERER_H
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -