FPlay UI: PAUSE and even more PAUSE

git-svn-id: svn://kolibrios.org@2427 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2012-03-02 10:31:15 +00:00
parent 0f6f6895e1
commit d6faa0933b
7 changed files with 254 additions and 148 deletions

View File

@ -6,25 +6,26 @@
#include <stdio.h>
#include <string.h>
#include <winlib.h>
#include "../winlib/winlib.h"
#include "sound.h"
#include "fplay.h"
astream_t astream;
static SNDBUF hBuff;
extern uint8_t *decoder_buffer;
extern volatile uint32_t status;
extern volatile enum player_state player_state;
extern volatile uint32_t driver_lock;
static SNDBUF hBuff;
static int snd_format;
int sample_rate;
static uint32_t samples_written = 0;
int init_audio(int format)
{
int err;
@ -65,8 +66,10 @@ exit_whith_error:
static uint64_t samples_lost;
static double audio_delta;
static double last_time_stamp;
double get_master_clock()
double get_master_clock(void)
{
double tstamp;
@ -116,13 +119,61 @@ int decode_audio(AVCodecContext *ctx, queue_t *qa)
};
static void sync_audio(SNDBUF hbuff, int buffsize)
{
SND_EVENT evnt;
uint32_t offset;
double time_stamp;
#ifdef BLACK_MAGIC_SOUND
while( player_state != CLOSED)
{
GetNotify(&evnt);
if(evnt.code != 0xFF000001)
{
printf("invalid event code %d\n\r", evnt.code);
continue;
}
if(evnt.stream != hbuff)
{
printf("invalid stream %x hBuff= %x\n\r",
evnt.stream, hbuff);
continue;
}
GetTimeStamp(hbuff, &time_stamp);
audio_delta = time_stamp - last_time_stamp;
offset = evnt.offset;
mutex_lock(&astream.lock);
{
SetBuffer(hbuff, astream.buffer, offset, buffsize);
samples_written+= buffsize/4;
astream.count -= buffsize;
if(astream.count)
memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
mutex_unlock(&astream.lock);
};
break;
};
#endif
};
int audio_thread(void *param)
{
SND_EVENT evnt;
int buffsize;
int samples;
int err;
char *errstr;
int active;
if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0)
@ -144,71 +195,49 @@ int audio_thread(void *param)
samples = buffsize/4;
while( (astream.count < buffsize*2) &&
(status != 0) )
(player_state != CLOSED) )
yield();
mutex_lock(&astream.lock);
{
SetBuffer(hBuff, astream.buffer, 0, buffsize);
samples_written+= buffsize/4;
astream.count -= buffsize;
if(astream.count)
memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
mutex_unlock(&astream.lock);
};
if((err = PlayBuffer(hBuff, 0)) !=0 )
{
errstr = "Cannot play buffer\n\r";
goto exit_whith_error;
};
#ifdef BLACK_MAGIC_SOUND
while( status != 0)
{
uint32_t offset;
GetNotify(&evnt);
if(evnt.code != 0xFF000001)
{
printf("invalid event code %d\n\r", evnt.code);
continue;
}
if(evnt.stream != hBuff)
{
printf("invalid stream %x hBuff= %x\n\r",
evnt.stream, hBuff);
continue;
}
GetTimeStamp(hBuff, &audio_delta);
samples_lost = audio_delta*sample_rate/1000;
offset = evnt.offset;
mutex_lock(&astream.lock);
{
SetBuffer(hBuff, astream.buffer, offset, buffsize);
astream.count -= buffsize;
if(astream.count)
memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
mutex_unlock(&astream.lock);
};
break;
};
#endif
printf("initial audio delta %f\n", audio_delta);
while( status != 0)
while( player_state != CLOSED)
{
uint32_t offset;
double event_stamp, wait_stamp;
int too_late = 0;
if(player_state == PAUSE)
{
if( active )
{
StopBuffer(hBuff);
active = 0;
}
delay(1);
continue;
}
else if(player_state == PLAY_RESTART)
{
GetTimeStamp(hBuff, &last_time_stamp);
if((err = PlayBuffer(hBuff, 0)) !=0 )
{
errstr = "Cannot play buffer\n\r";
goto exit_whith_error;
};
active = 1;
sync_audio(hBuff, buffsize);
player_state = PLAY;
printf("audio delta %f\n", audio_delta);
};
GetNotify(&evnt);
if(evnt.code != 0xFF000001)
@ -229,7 +258,7 @@ int audio_thread(void *param)
offset = evnt.offset;
while( (astream.count < buffsize) &&
(status != 0) )
(player_state != CLOSED) )
{
yield();
GetTimeStamp(hBuff, &wait_stamp);
@ -244,11 +273,15 @@ int audio_thread(void *param)
}
};
if((too_late == 1) || (status == 0))
if((too_late == 1) || (player_state == CLOSED))
{
too_late = 0;
continue;
};
mutex_lock(&astream.lock);
SetBuffer(hBuff, astream.buffer, offset, buffsize);
samples_written+= buffsize/4;
astream.count -= buffsize;
if(astream.count)
memcpy(astream.buffer, astream.buffer+buffsize, astream.count);

View File

@ -10,12 +10,12 @@
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <winlib.h>
#include "../winlib/winlib.h"
#include "sound.h"
#include "fplay.h"
volatile uint32_t status = 1;
volatile enum player_state player_state;
uint32_t win_width, win_height;
@ -102,6 +102,8 @@ int main( int argc, char *argv[])
return -1; // Didn't find a video stream
}
player_state = PLAY_RESTART;
// __asm__ __volatile__("int3");
// Get a pointer to the codec context for the video stream
@ -204,12 +206,18 @@ void decoder()
AVPacket packet;
int ret;
while( status != 0 && !eof)
while( player_state != CLOSED && !eof)
{
int err;
// __asm__ __volatile__("int3");
if( player_state == PAUSE )
{
delay(1);
continue;
};
if(q_video.size+q_audio.size < 12*1024*1024)
{
err = av_read_frame(pFormatCtx, &packet);
@ -244,15 +252,14 @@ void decoder()
ret = 1;
while( (status != 0) && ret)
while( (player_state != CLOSED) && ret)
{
ret = decode_video(pCodecCtx, &q_video);
ret |= decode_audio(aCodecCtx, &q_audio);
delay(1);
};
delay(50);
status = 0;
printf("status = 0\n");
player_state = CLOSED;
delay(300);
};

View File

@ -38,6 +38,8 @@ struct render
uint32_t layout;
bitmap_t bitmap[4];
bitmap_t *last_bitmap;
uint32_t ctx_format;
int target;
@ -49,6 +51,11 @@ struct render
void (*draw)(render_t *render, AVPicture *picture);
};
enum player_state
{ CLOSED=0, STOP, PLAY_RESTART, PLAY, PAUSE, REWIND };
#define ID_PLAY 100
typedef struct
{
volatile uint32_t lock;
@ -109,7 +116,7 @@ int video_thread(void *param);
int decode_video(AVCodecContext *ctx, queue_t *qv);
int decode_audio(AVCodecContext *ctx, queue_t *qa);
double get_master_clock();
double get_master_clock(void);
int create_thread(int (*proc)(void *param), void *param, int stack_size);

View File

@ -4,7 +4,7 @@
#include <libswscale/swscale.h>
#include <stdio.h>
#include <fcntl.h>
#include <winlib.h>
#include "../winlib/winlib.h"
#include "fplay.h"
#define DISPLAY_VERSION 0x0200 /* 2.00 */
@ -339,7 +339,7 @@ static inline void* user_realloc(void *mem, size_t size)
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(68),"b"(12),"c"(size),"d"(mem)
:"memory");

View File

@ -67,7 +67,7 @@ pos_t get_mouse_pos(void)
__asm__ __volatile__(
"int $0x40 \n\t"
"rol $16, %%eax"
:"=eax"(val)
:"=a"(val)
:"a"(37),"b"(1));
return val;
}
@ -80,7 +80,7 @@ pos_t get_cursor_pos(void)
__asm__ __volatile__(
"int $0x40 \n\t"
"rol $16, %%eax"
:"=eax"(val)
:"=a"(val)
:"a"(37),"b"(0));
return val;
}
@ -137,7 +137,7 @@ uint32_t get_tick_count(void)
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(26),"b"(9));
return val;
};
@ -148,7 +148,7 @@ oskey_t get_key(void)
oskey_t val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(2));
return val;
}
@ -201,7 +201,7 @@ void *user_alloc(size_t size)
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(68),"b"(12),"c"(size));
return val;
}
@ -212,7 +212,7 @@ int user_free(void *mem)
int val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(68),"b"(12),"c"(mem));
return val;
}
@ -223,7 +223,7 @@ int *user_unmap(void *base, size_t offset, size_t size)
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(68),"b"(26),"c"(base),"d"(offset),"S"(size));
return val;
}
@ -248,7 +248,7 @@ uint32_t load_cursor(void *path, uint32_t flags)
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(37), "b"(4), "c"(path), "d"(flags));
return val;
}
@ -259,7 +259,7 @@ uint32_t set_cursor(uint32_t cursor)
uint32_t old;
__asm__ __volatile__(
"int $0x40"
:"=eax"(old)
:"=a"(old)
:"a"(37), "b"(5), "c"(cursor));
return old;
}
@ -278,7 +278,7 @@ void* user_realloc(void *mem, size_t size)
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"=a"(val)
:"a"(68),"b"(12),"c"(size),"d"(mem)
:"memory");
@ -309,3 +309,8 @@ void Blit(void *bitmap, int dst_x, int dst_y,
int src_x, int src_y, int w, int h,
int src_w, int src_h, int stride);

View File

@ -5,7 +5,7 @@
#include <libswscale/swscale.h>
#include <stdio.h>
#include <fcntl.h>
#include <winlib.h>
#include "../winlib/winlib.h"
#include "fplay.h"
extern uint32_t hw2d ;

View File

@ -5,12 +5,19 @@
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include "system.h"
#include <winlib.h>
#include "../winlib/winlib.h"
#include "sound.h"
#include "fplay.h"
#define CAPTION_HEIGHT 24
extern int res_pause_btn[];
extern int res_pause_btn_pressed[];
extern int res_play_btn[];
extern int res_play_btn_pressed[];
typedef struct
{
AVPicture picture;
@ -98,6 +105,7 @@ int decode_video(AVCodecContext *ctx, queue_t *qv)
AVPacket pkt;
double pts;
int frameFinished;
double current_clock;
if(frames[dfx].ready != 0 )
return 1;
@ -105,25 +113,38 @@ int decode_video(AVCodecContext *ctx, queue_t *qv)
if( get_packet(qv, &pkt) == 0 )
return 0;
frameFinished = 0;
current_clock = -80.0 + get_master_clock();
ctx->reordered_opaque = pkt.pts;
if(avcodec_decode_video2(ctx, Frame, &frameFinished, &pkt) <= 0)
printf("video decoder error\n");
if(frameFinished)
{
AVPicture *dst_pic;
if( pkt.dts == AV_NOPTS_VALUE &&
Frame->reordered_opaque != AV_NOPTS_VALUE)
pts = Frame->reordered_opaque;
if( pkt.dts == AV_NOPTS_VALUE &&
Frame->reordered_opaque != AV_NOPTS_VALUE)
pts = Frame->reordered_opaque;
else if(pkt.dts != AV_NOPTS_VALUE)
pts= pkt.dts;
else
pts= 0;
pts= pkt.dts;
else
pts= 0;
pts *= av_q2d(video_time_base)*1000.0;
if( pts > current_clock)
{
frameFinished = 0;
ctx->reordered_opaque = pkt.pts;
if(avcodec_decode_video2(ctx, Frame, &frameFinished, &pkt) <= 0)
printf("video decoder error\n");
if(frameFinished)
{
AVPicture *dst_pic;
if( pkt.dts == AV_NOPTS_VALUE &&
Frame->reordered_opaque != AV_NOPTS_VALUE)
pts = Frame->reordered_opaque;
else if(pkt.dts != AV_NOPTS_VALUE)
pts= pkt.dts;
else
pts= 0;
// pts = *(int64_t*)av_opt_ptr(avcodec_get_frame_class(),
// Frame, "best_effort_timestamp");
@ -131,27 +152,28 @@ int decode_video(AVCodecContext *ctx, queue_t *qv)
// if (pts == AV_NOPTS_VALUE)
// pts = 0;
pts *= av_q2d(video_time_base);
pts *= av_q2d(video_time_base);
dst_pic = &frames[dfx].picture;
dst_pic = &frames[dfx].picture;
av_image_copy(dst_pic->data, dst_pic->linesize,
av_image_copy(dst_pic->data, dst_pic->linesize,
(const uint8_t**)Frame->data,
Frame->linesize, ctx->pix_fmt, ctx->width, ctx->height);
frames[dfx].pts = pts*1000.0;
frames[dfx].ready = 1;
frames[dfx].pts = pts*1000.0;
frames[dfx].ready = 1;
dfx++;
dfx&= 3;
dfx++;
dfx&= 3;
};
};
av_free_packet(&pkt);
return 1;
}
extern volatile uint32_t status;
rect_t win_rect;
extern volatile enum player_state player_state;
//rect_t win_rect;
int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
@ -171,12 +193,48 @@ int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
render_draw_client(main_render);
break;
case MSG_LBTNDOWN:
if(player_state == PAUSE)
{
win->panel.play_btn->img_default = res_play_btn;
win->panel.play_btn->img_hilite = res_play_btn;
win->panel.play_btn->img_pressed = res_play_btn_pressed;
send_message(win->panel.play_btn, MSG_PAINT, 0, 0);
player_state = PLAY_RESTART;
}
else if(player_state == PLAY)
{
win->panel.play_btn->img_default = res_pause_btn;
win->panel.play_btn->img_hilite = res_pause_btn;
win->panel.play_btn->img_pressed = res_pause_btn_pressed;
send_message(win->panel.play_btn, MSG_PAINT, 0, 0);
player_state = PAUSE;
}
break;
case MSG_COMMAND:
switch((short)arg1)
{
case ID_CLOSE:
exit(0);
};
case ID_PLAY:
if(player_state == PAUSE)
{
win->panel.play_btn->img_default = res_play_btn;
win->panel.play_btn->img_hilite = res_play_btn;
win->panel.play_btn->img_pressed = res_play_btn_pressed;
player_state = PLAY_RESTART;
}
else if(player_state == PLAY)
{
win->panel.play_btn->img_default = res_pause_btn;
win->panel.play_btn->img_hilite = res_pause_btn;
win->panel.play_btn->img_pressed = res_pause_btn_pressed;
player_state = PAUSE;
}
break;
default:
break;
}
break;
default:
@ -187,13 +245,20 @@ int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
void render_time(render_t *render)
{
double ctime;
double fdelay;
double ctime; /* milliseconds */
double fdelay; /* milliseconds */
if(status == 0)
//again:
if(player_state == CLOSED)
{
render->win->win_command = WIN_CLOSED;
return;
}
else if(player_state != PLAY)
{
yield();
return;
};
if(frames[vfx].ready == 1 )
@ -201,40 +266,13 @@ void render_time(render_t *render)
ctime = get_master_clock();
fdelay = (frames[vfx].pts - ctime);
// printf("pts %f time %f delay %f\n",
// frames[vfx].pts, ctime, fdelay);
// printf("pts %f time %f delay %f\n",
// frames[vfx].pts, ctime, fdelay);
if(fdelay < 0.0 )
if(fdelay > 20.0)
{
int next_vfx;
fdelay = 0;
next_vfx = (vfx+1) & 3;
if( frames[next_vfx].ready == 1 )
{
if(frames[next_vfx].pts <= ctime)
{
frames[vfx].ready = 0; // skip this frame
vfx++;
vfx&= 3;
}
else
{
if( (frames[next_vfx].pts - ctime) <
( ctime - frames[vfx].pts) )
{
frames[vfx].ready = 0; // skip this frame
vfx++;
vfx&= 3;
fdelay = (frames[next_vfx].pts - ctime);
}
}
};
};
if(fdelay > 10.0)
{
// delay( (uint32_t)(fdelay/10.0));
yield();
delay(2);
// yield();
return;
};
@ -242,9 +280,14 @@ void render_time(render_t *render)
frames[vfx].ready = 0;
vfx++;
vfx&= 3;
};
}
else yield();
}
extern char *movie_file;
int video_thread(void *param)
@ -254,7 +297,7 @@ int video_thread(void *param)
init_winlib();
MainWindow = create_window(movie_file,0,
10,10,width+14,height+29,MainWindowProc);
10,10,width,height+29+75,MainWindowProc);
// printf("MainWindow %x\n", MainWindow);
@ -264,7 +307,7 @@ int video_thread(void *param)
run_render(MainWindow, main_render);
// printf("exit thread\n");
status = 0;
player_state = CLOSED;
return 0;
};
@ -366,7 +409,7 @@ int render_set_size(render_t *render, int width, int height)
if( create_bitmap(&render->bitmap[i]) != 0 )
{
status = 0;
player_state = CLOSED;
/*
* Epic fail. Need exit_thread() here
*
@ -405,7 +448,7 @@ void render_adjust_size(render_t *render, window_t *win)
right = win->w;
bottom = win->h-CAPTION_HEIGHT;
bottom = win->h-CAPTION_HEIGHT-75;
render->win_state = win->win_state;
if(render->win_state == MINIMIZED)
@ -439,7 +482,7 @@ void render_adjust_size(render_t *render, window_t *win)
};
render->win_width = win->w;
render->win_height = win->h-CAPTION_HEIGHT;
render->win_height = win->h-CAPTION_HEIGHT-75;
render_set_size(render, new_w, new_h);
};
@ -451,7 +494,8 @@ void draw_hw_picture(render_t *render, AVPicture *picture)
int linesize[4];
int ret;
if(render->win_state == ROLLED)
if(render->win_state == MINIMIZED ||
render->win_state == ROLLED)
return;
if(render->caps & HW_TEX_BLIT)
@ -502,6 +546,7 @@ void draw_hw_picture(render_t *render, AVPicture *picture)
blit_bitmap(bitmap, render->rcvideo.l,
CAPTION_HEIGHT+render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b);
render->last_bitmap = bitmap;
// printf("blit_bitmap\n");
@ -546,6 +591,7 @@ void draw_sw_picture(render_t *render, AVPicture *picture)
blit_bitmap(&render->bitmap[0], render->rcvideo.l,
render->rcvideo.t+CAPTION_HEIGHT,
render->rcvideo.r, render->rcvideo.b);
render->last_bitmap = &render->bitmap[0];
}
void render_draw_client(render_t *render)
@ -554,6 +600,11 @@ void render_draw_client(render_t *render)
render->win_state == ROLLED)
return;
if(player_state == PAUSE)
{
main_render->draw(main_render, &frames[vfx].picture);
};
if(render->layout & HAS_TOP)
draw_bar(0, CAPTION_HEIGHT, render->win_width,
render->rctop.b, 0);
@ -569,3 +620,6 @@ void render_draw_client(render_t *render)
}