diff --git a/contrib/media/fplay/Makefile b/contrib/media/fplay/Makefile index 5d90f34ddc..5b368df5df 100644 --- a/contrib/media/fplay/Makefile +++ b/contrib/media/fplay/Makefile @@ -8,28 +8,29 @@ LD = kos32-ld CPP= kos32-g++ STRIP = kos32-strip -CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fno-ident -fomit-frame-pointer - +CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fno-ident -fomit-frame-pointer -mno-ms-bitfields ARFLAG = crs SDK_DIR:= $(abspath ../../sdk) LIB_DIR:= $(SDK_DIR)/lib +INCLUDES= -I. -I$(SDK_DIR)/sources/newlib/libc/include -I$(SDK_DIR)/sources/ffmpeg +INCLUDES+=-I$(SDK_DIR)/sources/freetype/include +#-I$(SDK_DIR)/sources/vaapi/libva-1.4.1 -INCLUDES= -I. -I$(SDK_DIR)/sources/newlib/libc/include -I$(SDK_DIR)/sources/ffmpeg -I$(SDK_DIR)/sources/freetype/include - -LIBS:= -lavdevice.dll -lavformat.dll -lavcodec.dll -lavutil.dll -lswscale.dll -LIBS+= -lswresample.dll -lsound -lpixlib3 -lfreetype.dll -lgcc -lc.dll -lapp +#DEFINES= -DDEBUG=1 -DPACKAGE_NAME=\"Fplay-vaapi\" +LIBS:= -lsync -lavdevice.dll -lavformat.dll -lavcodec.dll -lavutil.dll -lswscale.dll +LIBS+= -lswresample.dll -lsound -lpixlib3 -lfreetype.dll -lva.dll -lgcc -lc.dll -lapp LIBPATH:= -L$(LIB_DIR) -L/home/autobuild/tools/win32/mingw32/lib -LDFLAGS = -static -nostdlib --stack 0x200000 -T$(SDK_DIR)/sources/newlib/app.lds --image-base 0 +LDFLAGS = -static -nostdlib --stack 0x200000 -Map fplay.map -T$(SDK_DIR)/sources/newlib/app.lds --image-base 0 SOURCES = opendial.asm \ audio.c \ fplay.c \ - utils.c \ video.c \ + utils.c \ skin/skin.asm \ winlib/button.c \ winlib/caption.c \ @@ -40,7 +41,6 @@ SOURCES = opendial.asm \ OBJECTS = $(patsubst %.asm, %.o, $(patsubst %.c, %.o, $(SOURCES))) - # targets all:$(NAME) diff --git a/contrib/media/fplay/audio.c b/contrib/media/fplay/audio.c index 5ecb699a72..43d7d7bc08 100644 --- a/contrib/media/fplay/audio.c +++ b/contrib/media/fplay/audio.c @@ -22,7 +22,7 @@ volatile enum player_state player_state; volatile enum player_state decoder_state; volatile enum player_state sound_state; -extern volatile uint32_t driver_lock; +extern mutex_t driver_lock; static SNDBUF hBuff; @@ -287,14 +287,13 @@ int audio_thread(void *param) char *errstr; int active; - if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0) { errstr = "Cannot create sound buffer\n\r"; goto exit_whith_error; }; - SetVolume(hBuff,-1875,-1875); + SetVolume(hBuff,-900,-900); if((err = GetBufferSize(hBuff, &buffsize)) != 0) { @@ -302,6 +301,8 @@ int audio_thread(void *param) goto exit_whith_error; }; + __sync_or_and_fetch(&threads_running,AUDIO_THREAD); + resampler_size = buffsize = buffsize/2; samples = buffsize/4; @@ -428,6 +429,8 @@ int audio_thread(void *param) }; } + __sync_and_and_fetch(&threads_running,~AUDIO_THREAD); + StopBuffer(hBuff); DestroyBuffer(hBuff); diff --git a/contrib/media/fplay/fplay.c b/contrib/media/fplay/fplay.c index 88d53e7697..9994de87eb 100644 --- a/contrib/media/fplay/fplay.c +++ b/contrib/media/fplay/fplay.c @@ -50,6 +50,9 @@ int64_t rewind_pos; int64_t stream_duration; +int threads_running = DECODER_THREAD; +mutex_t driver_lock; + extern double audio_base; double get_audio_base() @@ -169,6 +172,9 @@ int main( int argc, char *argv[]) // printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt); + mutex_init(&driver_lock); + mutex_init(&q_video.lock); + mutex_init(&q_audio.lock); if (aCodecCtx->channels > 0) aCodecCtx->request_channels = FFMIN(2, aCodecCtx->channels); @@ -203,7 +209,7 @@ int main( int argc, char *argv[]) decoder_buffer = (uint8_t*)av_mallocz(192000*2+64); if( decoder_buffer != NULL ) { - astream.lock = 0; + mutex_init(&astream.lock); astream.count = 0; astream.buffer = (char *)av_mallocz(192000*3); if( astream.buffer != NULL ) @@ -224,8 +230,6 @@ int main( int argc, char *argv[]) if( !init_video(pCodecCtx)) return 0; -// __asm__ __volatile__("int3"); - decoder(); // Free the YUV frame @@ -234,13 +238,16 @@ int main( int argc, char *argv[]) //__asm__ __volatile__("int3"); - // Close the codec - // avcodec_close(pCodecCtx); + while( threads_running & + (AUDIO_THREAD | VIDEO_THREAD)) + delay(1); - // Close the video file - // av_close_input_file(pFormatCtx); + if(astream.lock.handle) + mutex_destroy(&astream.lock); -//__asm__ __volatile__("int3"); + mutex_destroy(&driver_lock); + mutex_destroy(&q_video.lock); + mutex_destroy(&q_audio.lock); return 0; } @@ -431,16 +438,5 @@ void decoder() } }; - ret = 1; - - while( (player_state != CLOSED) && ret) - { - ret = decode_video(pCodecCtx, &q_video); - ret |= decode_audio(aCodecCtx, &q_audio); - delay(1); - }; - delay(50); - player_state = CLOSED; - delay(300); }; diff --git a/contrib/media/fplay/fplay.h b/contrib/media/fplay/fplay.h index 98faa22310..5bb40aa97f 100644 --- a/contrib/media/fplay/fplay.h +++ b/contrib/media/fplay/fplay.h @@ -1,5 +1,6 @@ #include "pixlib3.h" +#include #define BLACK_MAGIC_SOUND #define BLACK_MAGIC_VIDEO @@ -64,11 +65,12 @@ enum player_state #define ID_VOL_LEVEL 103 #define ID_VOL_CTRL 104 + typedef struct { - volatile uint32_t lock; - char *buffer; - volatile uint32_t count; + mutex_t lock; + char *buffer; + int count; }astream_t; typedef struct @@ -87,13 +89,18 @@ typedef struct { AVPacketList *last_pkt; int size; int count; - volatile uint32_t lock; + mutex_t lock; } queue_t; int put_packet(queue_t *q, AVPacket *pkt); int get_packet(queue_t *q, AVPacket *pkt); +#define DECODER_THREAD 1 +#define AUDIO_THREAD 2 +#define VIDEO_THREAD 4 + +extern int threads_running; extern astream_t astream; extern AVRational video_time_base; @@ -120,12 +127,6 @@ double get_master_clock(void); int create_thread(int (*proc)(void *param), void *param, int stack_size); -void mutex_lock(volatile uint32_t *val); - -static inline void mutex_unlock(volatile uint32_t *val) -{ - *val = 0; -} static inline void GetNotify(void *event) { diff --git a/contrib/media/fplay/utils.c b/contrib/media/fplay/utils.c index bb3f827c68..d8a998233e 100644 --- a/contrib/media/fplay/utils.c +++ b/contrib/media/fplay/utils.c @@ -10,29 +10,85 @@ extern uint32_t hw2d ; -void mutex_lock(volatile uint32_t *val) +#if 0 +#define FUTEX_INIT 0 +#define FUTEX_DESTROY 1 +#define FUTEX_WAIT 2 +#define FUTEX_WAKE 3 + +int __fastcall mutex_init(mutex_t *mutex) { - uint32_t tmp; + unsigned int handle; - __asm__ __volatile__ ( -"0:\n\t" - "mov %0, %1\n\t" - "testl %1, %1\n\t" - "jz 1f\n\t" + mutex->lock = 0; - "movl $68, %%eax\n\t" - "movl $1, %%ebx\n\t" - "int $0x40\n\t" - "jmp 0b\n\t" -"1:\n\t" - "incl %1\n\t" - "xchgl %0, %1\n\t" - "testl %1, %1\n\t" - "jnz 0b\n" - : "+m" (*val), "=&r"(tmp) - ::"eax","ebx" ); + asm volatile( + "int $0x40\t" + :"=a"(handle) + :"a"(77),"b"(FUTEX_INIT),"c"(mutex)); + mutex->handle = handle; + + return handle; +}; + +int __fastcall mutex_destroy(mutex_t *mutex) +{ + int retval; + + asm volatile( + "int $0x40\t" + :"=a"(retval) + :"a"(77),"b"(FUTEX_DESTROY),"c"(mutex->handle)); + + return retval; +}; + +#define exchange_acquire(ptr, new) \ + __atomic_exchange_4((ptr), (new), __ATOMIC_ACQUIRE) + +#define exchange_release(ptr, new) \ + __atomic_exchange_4((ptr), (new), __ATOMIC_RELEASE) + +void __fastcall mutex_lock(mutex_t *mutex) +{ + int tmp; + + if( __sync_fetch_and_add(&mutex->lock, 1) == 0) + return; + + while (exchange_acquire (&mutex->lock, 2) != 0) + { + asm volatile( + "int $0x40\t" + :"=a"(tmp) + :"a"(77),"b"(FUTEX_WAIT), + "c"(mutex->handle),"d"(2),"S"(0)); + } } +int __fastcall mutex_trylock (mutex_t *mutex) +{ + int zero = 0; + + return __atomic_compare_exchange_4(&mutex->lock, &zero, 1,0,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED); +} + +void __fastcall mutex_unlock(mutex_t *mutex) +{ + int prev; + + prev = exchange_release (&mutex->lock, 0); + + if (prev != 1) + { + asm volatile( + "int $0x40\t" + :"=a"(prev) + :"a"(77),"b"(FUTEX_WAKE), + "c"(mutex->handle),"d"(1)); + }; +}; +#endif int64_t _lseeki64(int fd, int64_t offset, int origin ) { @@ -40,7 +96,6 @@ int64_t _lseeki64(int fd, int64_t offset, int origin ) return lseek(fd, off, origin); } - int put_packet(queue_t *q, AVPacket *pkt) { AVPacketList *q_pkt; diff --git a/contrib/media/fplay/video.c b/contrib/media/fplay/video.c index 9b087555ce..96ee467be6 100644 --- a/contrib/media/fplay/video.c +++ b/contrib/media/fplay/video.c @@ -46,7 +46,7 @@ int height; AVRational video_time_base; AVFrame *Frame; -volatile uint32_t driver_lock; +extern mutex_t driver_lock; void get_client_rect(rect_t *rc); @@ -565,16 +565,12 @@ int video_thread(void *param) AVCodecContext *ctx = param; window_t *MainWindow; - - printf("%s\n", __FUNCTION__); - init_winlib(); MainWindow = create_window(movie_file,0, 10,10,width,height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc); MainWindow->panel.prg->max = stream_duration; -// printf("MainWindow %x\n", MainWindow); show_window(MainWindow, NORMAL); @@ -587,14 +583,17 @@ int video_thread(void *param) return 0; }; + __sync_or_and_fetch(&threads_running,VIDEO_THREAD); + render_draw_client(main_render); player_state = PLAY; run_render(MainWindow, main_render); + __sync_and_and_fetch(&threads_running,~VIDEO_THREAD); + destroy_render(main_render); fini_winlib(); - player_state = CLOSED; return 0; };