⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overlay.h

📁 linux下实现视频播放的播放器
💻 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 + -