Uint8 *GLCLDraw::GetBufPtr(Uint32 timeout) { Uint32 t = timeout / 10; Uint32 i; BOOL flag = FALSE; if(timeout == 0) { AG_MutexLock(&mutex_buffer); return TransferBuffer; } else { for(i = 0; i < t; i++) { if(AG_MutexTryLock(&mutex_buffer) == 0) { flag = TRUE; break; } AG_Delay(10); } if(flag == FALSE) { t = timeout % 10; AG_Delay(t); if(AG_MutexTryLock(&mutex_buffer) == 0) flag = TRUE; } if(flag == FALSE) return NULL; return TransferBuffer; } }
/* Animation processing loop */ static void * AnimProc(void *arg) { AG_AnimState *ast = arg; Uint32 delay; while (ast->play) { AG_MutexLock(&ast->lock); AG_MutexLock(&ast->an->lock); if (ast->an->n < 1) { AG_MutexUnlock(&ast->an->lock); AG_MutexUnlock(&ast->lock); goto out; } if (ast->f & AG_ANIM_REVERSE) { if (--ast->f < 0) { if (ast->flags & AG_ANIM_LOOP) { ast->f = (ast->an->n - 1); } else if (ast->flags & AG_ANIM_PINGPONG) { ast->f = 0; ast->flags &= ~(AG_ANIM_REVERSE); } else { ast->play = 0; AG_MutexUnlock(&ast->an->lock); AG_MutexUnlock(&ast->lock); goto out; } } } else { if (++ast->f >= ast->an->n) { if (ast->flags & AG_ANIM_LOOP) { ast->f = 0; } else if (ast->flags & AG_ANIM_PINGPONG) { ast->f--; ast->flags |= AG_ANIM_REVERSE; } else { ast->play = 0; AG_MutexUnlock(&ast->an->lock); AG_MutexUnlock(&ast->lock); goto out; } } } delay = (Uint32)(1000.0/ast->fps); AG_MutexUnlock(&ast->an->lock); AG_MutexUnlock(&ast->lock); AG_Delay(delay); } out: return (NULL); }
static void * drawVideoThread(void *data) { ffmpegPlayer *me = data; AG_ObjectLock(me); for (;;) { SDL_ffmpegVideoFrame *frame = me->videoFrame[me->curVideoFrame]; if (!frame->ready) { DEBUG("Video buffer underrun!"); SDL_ffmpegGetVideoFrame(me->file, frame); } uint64_t sync = getSync(me); uint64_t pts = frame->pts; if (pts >= sync) { AG_ObjectUnlock(me); /* condition variable waiting may be faster, test with 500mhz */ AG_Delay(pts - sync); AG_ObjectLock(me); if (me->file == NULL) { /* FIXME */ break; } if (pts > getSync(me)) continue; #ifdef USE_OVERLAY if (frame->overlay != NULL) { if (AG_WidgetVisible(me)) { int frame_x = (AGWIDGET(me)->w - me->disp_w) / 2; int frame_y = (AGWIDGET(me)->h - me->disp_h) / 2; SDL_Rect rect = { .x = AGWIDGET(me)->rView.x1 + frame_x, .y = AGWIDGET(me)->rView.y1 + frame_y, .w = me->disp_w, .h = me->disp_h }; SDL_DisplayYUVOverlay(frame->overlay, &rect); } } #else if (frame->surface != NULL) { #ifdef USE_SDL_SHADOWSURFACE if (me->surface != NULL) AG_SDL_ShadowSurfaceFree(me->surface); me->surface = AG_SDL_ShadowSurface(frame->surface); #else if (me->surface != NULL) AG_SurfaceFree(me->surface); me->surface = AG_SurfaceFromSDL(frame->surface); #endif if (me->surface == NULL) { /* FIXME */ break; } AG_Redraw(AGWIDGET(me)); } #endif } else { /* frame is skipped */ DEBUG("skip frame: %lums late", sync - frame->pts); } frame->ready = 0; RR_INC(me->curVideoFrame, FFMPEGPLAYER_BUFSIZE); /* wake up buffer-fill thread */ AG_CondSignal(&me->video_cond); }