/programs/media/Fplay/audio.c |
---|
6,7 → 6,7 |
#include <stdio.h> |
#include <string.h> |
#include <winlib.h> |
#include "../winlib/winlib.h" |
#include "sound.h" |
#include "fplay.h" |
13,18 → 13,19 |
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 |
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 |
}; |
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,12 → 195,13 |
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); |
156,59 → 208,36 |
mutex_unlock(&astream.lock); |
}; |
if((err = PlayBuffer(hBuff, 0)) !=0 ) |
while( player_state != CLOSED) |
{ |
errstr = "Cannot play buffer\n\r"; |
goto exit_whith_error; |
}; |
#ifdef BLACK_MAGIC_SOUND |
while( status != 0) |
{ |
uint32_t offset; |
double event_stamp, wait_stamp; |
int too_late = 0; |
GetNotify(&evnt); |
if(evnt.code != 0xFF000001) |
if(player_state == PAUSE) |
{ |
printf("invalid event code %d\n\r", evnt.code); |
continue; |
if( active ) |
{ |
StopBuffer(hBuff); |
active = 0; |
} |
if(evnt.stream != hBuff) |
{ |
printf("invalid stream %x hBuff= %x\n\r", |
evnt.stream, hBuff); |
delay(1); |
continue; |
} |
GetTimeStamp(hBuff, &audio_delta); |
samples_lost = audio_delta*sample_rate/1000; |
offset = evnt.offset; |
mutex_lock(&astream.lock); |
else if(player_state == PLAY_RESTART) |
{ |
SetBuffer(hBuff, astream.buffer, offset, buffsize); |
astream.count -= buffsize; |
if(astream.count) |
memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
mutex_unlock(&astream.lock); |
GetTimeStamp(hBuff, &last_time_stamp); |
if((err = PlayBuffer(hBuff, 0)) !=0 ) |
{ |
errstr = "Cannot play buffer\n\r"; |
goto exit_whith_error; |
}; |
break; |
active = 1; |
sync_audio(hBuff, buffsize); |
player_state = PLAY; |
printf("audio delta %f\n", audio_delta); |
}; |
#endif |
printf("initial audio delta %f\n", audio_delta); |
while( status != 0) |
{ |
uint32_t offset; |
double event_stamp, wait_stamp; |
int too_late = 0; |
GetNotify(&evnt); |
if(evnt.code != 0xFF000001) |
229,7 → 258,7 |
offset = evnt.offset; |
while( (astream.count < buffsize) && |
(status != 0) ) |
(player_state != CLOSED) ) |
{ |
yield(); |
GetTimeStamp(hBuff, &wait_stamp); |
244,11 → 273,15 |
} |
}; |
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); |
/programs/media/Fplay/fplay.c |
---|
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 |
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 |
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,7 → 252,7 |
ret = 1; |
while( (status != 0) && ret) |
while( (player_state != CLOSED) && ret) |
{ |
ret = decode_video(pCodecCtx, &q_video); |
ret |= decode_audio(aCodecCtx, &q_audio); |
251,8 → 259,7 |
delay(1); |
}; |
delay(50); |
status = 0; |
printf("status = 0\n"); |
player_state = CLOSED; |
delay(300); |
}; |
/programs/media/Fplay/fplay.h |
---|
38,6 → 38,8 |
uint32_t layout; |
bitmap_t bitmap[4]; |
bitmap_t *last_bitmap; |
uint32_t ctx_format; |
int target; |
49,6 → 51,11 |
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 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); |
/programs/media/Fplay/pixlib2.c |
---|
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 |
void *val; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(val) |
:"=a"(val) |
:"a"(68),"b"(12),"c"(size),"d"(mem) |
:"memory"); |
/programs/media/Fplay/system.h |
---|
67,7 → 67,7 |
__asm__ __volatile__( |
"int $0x40 \n\t" |
"rol $16, %%eax" |
:"=eax"(val) |
:"=a"(val) |
:"a"(37),"b"(1)); |
return val; |
} |
80,7 → 80,7 |
__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 val; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(val) |
:"=a"(val) |
:"a"(26),"b"(9)); |
return val; |
}; |
148,7 → 148,7 |
oskey_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(val) |
:"=a"(val) |
:"a"(2)); |
return val; |
} |
201,7 → 201,7 |
void *val; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(val) |
:"=a"(val) |
:"a"(68),"b"(12),"c"(size)); |
return val; |
} |
212,7 → 212,7 |
int val; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(val) |
:"=a"(val) |
:"a"(68),"b"(12),"c"(mem)); |
return val; |
} |
223,7 → 223,7 |
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 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 old; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(old) |
:"=a"(old) |
:"a"(37), "b"(5), "c"(cursor)); |
return old; |
} |
278,7 → 278,7 |
void *val; |
__asm__ __volatile__( |
"int $0x40" |
:"=eax"(val) |
:"=a"(val) |
:"a"(68),"b"(12),"c"(size),"d"(mem) |
:"memory"); |
309,3 → 309,8 |
int src_x, int src_y, int w, int h, |
int src_w, int src_h, int stride); |
/programs/media/Fplay/utils.c |
---|
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 ; |
/programs/media/Fplay/video.c |
---|
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 |
AVPacket pkt; |
double pts; |
int frameFinished; |
double current_clock; |
if(frames[dfx].ready != 0 ) |
return 1; |
105,6 → 113,20 |
if( get_packet(qv, &pkt) == 0 ) |
return 0; |
current_clock = -80.0 + get_master_clock(); |
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 *= av_q2d(video_time_base)*1000.0; |
if( pts > current_clock) |
{ |
frameFinished = 0; |
ctx->reordered_opaque = pkt.pts; |
116,7 → 138,6 |
{ |
AVPicture *dst_pic; |
if( pkt.dts == AV_NOPTS_VALUE && |
Frame->reordered_opaque != AV_NOPTS_VALUE) |
pts = Frame->reordered_opaque; |
145,13 → 166,14 |
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,13 → 193,49 |
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: |
def_window_proc(ctrl,msg,arg1,arg2); |
187,13 → 245,20 |
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 ) |
204,37 → 269,10 |
// 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 |
frames[vfx].ready = 0; |
vfx++; |
vfx&= 3; |
}; |
} |
else yield(); |
} |
extern char *movie_file; |
int video_thread(void *param) |
254,7 → 297,7 |
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 |
run_render(MainWindow, main_render); |
// printf("exit thread\n"); |
status = 0; |
player_state = CLOSED; |
return 0; |
}; |
366,7 → 409,7 |
if( create_bitmap(&render->bitmap[i]) != 0 ) |
{ |
status = 0; |
player_state = CLOSED; |
/* |
* Epic fail. Need exit_thread() here |
* |
405,7 → 448,7 |
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 |
}; |
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 |
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 |
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 |
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 |
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 |
} |