/programs/media/Fplay/audio.c |
---|
0,0 → 1,240 |
#include <stdint.h> |
#include <libavcodec/avcodec.h> |
#include <libavformat/avformat.h> |
#include <libswscale/swscale.h> |
#include <stdio.h> |
#include <string.h> |
#include "sound.h" |
#include "fplay.h" |
astream_t astream; |
static SNDBUF hBuff; |
extern volatile uint32_t status; |
void audio_thread(void *param); |
void spinlock_lock(volatile uint32_t *val) |
{ |
uint32_t tmp; |
__asm__ __volatile__ ( |
"0:\n\t" |
"mov %0, %1\n\t" |
"testl %1, %1\n\t" |
"jz 1f\n\t" |
"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" ); |
} |
static int snd_format; |
int sample_rate; |
int init_audio(int format) |
{ |
int err; |
int version =-1; |
char *errstr; |
if((err = InitSound(&version)) !=0 ) |
{ |
errstr = "Sound service not installed\n\r"; |
goto exit_whith_error; |
} |
printf("sound version 0x%x\n", version); |
if( (SOUND_VERSION>(version&0xFFFF)) || |
(SOUND_VERSION<(version >> 16))) |
{ |
errstr = "Sound service version mismatch\n\r"; |
goto exit_whith_error; |
} |
snd_format = format; |
asm volatile ( "xchgw %bx, %bx"); |
create_thread(audio_thread, 0, 163840); |
return 1; |
exit_whith_error: |
printf(errstr); |
return 0; |
}; |
static uint64_t samples_lost; |
static double audio_delta; |
double get_master_clock() |
{ |
double tstamp; |
GetTimeStamp(hBuff, &tstamp); |
return tstamp - audio_delta; |
}; |
void audio_thread(void *param) |
{ |
SND_EVENT evnt; |
int buffsize; |
int samples; |
int err; |
char *errstr; |
if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0) |
{ |
errstr = "Cannot create sound buffer\n\r"; |
goto exit_whith_error; |
}; |
SetVolume(hBuff,-1000,-1000); |
if((err = GetBufferSize(hBuff, &buffsize)) != 0) |
{ |
errstr = "Cannot get buffer size\n\r"; |
goto exit_whith_error; |
}; |
buffsize = buffsize/2; |
samples = buffsize/4; |
while( (astream.count < buffsize*2) && |
(status != 0) ) |
yield(); |
spinlock_lock(&astream.lock); |
{ |
SetBuffer(hBuff, astream.buffer, 0, buffsize); |
astream.count -= buffsize; |
if(astream.count) |
memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
spinlock_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; |
spinlock_lock(&astream.lock); |
{ |
SetBuffer(hBuff, astream.buffer, offset, buffsize); |
astream.count -= buffsize; |
if(astream.count) |
memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
spinlock_unlock(&astream.lock); |
}; |
break; |
}; |
#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) |
{ |
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, &event_stamp); |
offset = evnt.offset; |
while( (astream.count < buffsize) && |
(status != 0) ) |
{ |
yield(); |
GetTimeStamp(hBuff, &wait_stamp); |
if( (wait_stamp - event_stamp) > |
samples*1500/sample_rate ) |
{ |
samples_lost+= samples; |
audio_delta = (double)samples_lost*1000/sample_rate; |
// printf("audio delta %f\n", audio_delta); |
too_late = 1; |
break; |
} |
}; |
if((too_late == 1) || (status == 0)) |
continue; |
spinlock_lock(&astream.lock); |
SetBuffer(hBuff, astream.buffer, offset, buffsize); |
astream.count -= buffsize; |
if(astream.count) |
memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
spinlock_unlock(&astream.lock); |
} |
return; |
exit_whith_error: |
printf(errstr); |
return ; |
}; |
/programs/media/Fplay/fplay.c |
---|
0,0 → 1,256 |
#include <stdint.h> |
#include <libavcodec/avcodec.h> |
#include <libavformat/avformat.h> |
#include <libavdevice/avdevice.h> |
#include <libswscale/swscale.h> |
#include <stdio.h> |
#include <string.h> |
#include <fcntl.h> |
#include "sound.h" |
#include "fplay.h" |
volatile uint32_t status = 1; |
uint32_t win_width, win_height; |
void decoder(); |
AVFormatContext *pFormatCtx; |
AVCodecContext *pCodecCtx; |
AVCodecContext *aCodecCtx; |
AVCodec *pCodec; |
AVCodec *aCodec; |
AVFrame *pFrame; |
int videoStream; |
int audioStream; |
int have_sound = 0; |
uint8_t *decoder_buffer; |
extern int sample_rate; |
int main( int argc, char *argv[]) |
{ |
int i; |
if(argc < 2) { |
printf("Please provide a movie file\n"); |
return -1; |
} |
/* register all codecs, demux and protocols */ |
avcodec_register_all(); |
avdevice_register_all(); |
av_register_all(); |
// Open video file |
if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0) |
{ |
printf("Cannot open file %s\n\r", argv[1]); |
return -1; // Couldn't open file |
}; |
// __asm__ __volatile__("int3"); |
// Retrieve stream information |
if(av_find_stream_info(pFormatCtx)<0) |
{ |
printf("Cannot find streams\n\r"); |
return -1; |
}; |
// __asm__ __volatile__("int3"); |
// dump_format(pFormatCtx, 0, argv[1], 0); |
// Find the first video stream |
videoStream=-1; |
audioStream=-1; |
for(i=0; i < pFormatCtx->nb_streams; i++) |
{ |
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO |
&& videoStream < 0) |
{ |
videoStream=i; |
video_time_base = pFormatCtx->streams[i]->time_base; |
} |
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO && |
audioStream < 0) |
{ |
audioStream=i; |
} |
} |
if(videoStream==-1) |
{ |
printf("Video stream not detected\n\r"); |
return -1; // Didn't find a video stream |
} |
// Get a pointer to the codec context for the video stream |
pCodecCtx=pFormatCtx->streams[videoStream]->codec; |
aCodecCtx=pFormatCtx->streams[audioStream]->codec; |
// Find the decoder for the video stream |
pCodec=avcodec_find_decoder(pCodecCtx->codec_id); |
if(pCodec==NULL) { |
printf("Unsupported video codec!\n"); |
return -1; // Codec not found |
} |
// Open codec |
if(avcodec_open(pCodecCtx, pCodec) < 0) |
{ |
printf("Cannot open video codec\n\r"); |
return -1; // Could not open codec |
}; |
if (aCodecCtx->channels > 0) |
aCodecCtx->request_channels = FFMIN(2, aCodecCtx->channels); |
else |
aCodecCtx->request_channels = 2; |
aCodec = avcodec_find_decoder(aCodecCtx->codec_id); |
if(aCodec) |
{ |
if(avcodec_open(aCodecCtx, aCodec) >= 0 ) |
{ |
WAVEHEADER whdr; |
int fmt; |
printf("audio stream rate %d channels %d\n", |
aCodecCtx->sample_rate, aCodecCtx->channels); |
whdr.riff_id = 0x46464952; |
whdr.riff_format = 0x45564157; |
whdr.wFormatTag = 0x01; |
whdr.nSamplesPerSec = aCodecCtx->sample_rate; |
whdr.nChannels = aCodecCtx->channels; |
whdr.wBitsPerSample = 16; |
sample_rate = aCodecCtx->sample_rate; |
fmt = test_wav(&whdr); |
if( init_audio(fmt) ) |
{ |
decoder_buffer = (uint8_t*)av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE); |
if( decoder_buffer != NULL ) |
{ |
astream.lock = 0; |
astream.count = 0; |
astream.buffer = (char *)av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE*8); |
if( astream.buffer != NULL ) |
have_sound = 1; |
else |
av_free(decoder_buffer); |
} |
if( have_sound == 0) |
{ |
printf("Not enough memory for audio buffers\n"); |
} |
} |
} |
else printf("Cannot open audio codec\n\r"); |
} |
else printf("Unsupported audio codec!\n"); |
if( !init_video(pCodecCtx)) |
return 0; |
// Assign appropriate parts of buffer to image planes in pFrameRGB |
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset |
// of AVPicture |
// __asm__ __volatile__("int3"); |
decoder(); |
status = 0; |
// Free the YUV frame |
av_free(pFrame); |
//__asm__ __volatile__("int3"); |
// Close the codec |
// avcodec_close(pCodecCtx); |
// Close the video file |
// av_close_input_file(pFormatCtx); |
//__asm__ __volatile__("int3"); |
return 0; |
} |
void decoder() |
{ |
AVPacket packet; |
while(av_read_frame(pFormatCtx, &packet) >=0 ) |
{ |
if(packet.stream_index==videoStream) |
{ |
decode_video(pCodecCtx, &packet); |
} |
else if( (packet.stream_index == audioStream) && |
(have_sound != 0) ) |
{ |
uint8_t *audio_data; |
int audio_size; |
int len; |
int data_size=0; |
audio_data = packet.data; |
audio_size = packet.size; |
while(audio_size > 0) |
{ |
data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
len = avcodec_decode_audio2(aCodecCtx,(int16_t*)decoder_buffer, |
&data_size, audio_data, audio_size); |
if(len >= 0) |
{ |
audio_data += len; |
audio_size -= len; |
while((astream.count + data_size) > |
AVCODEC_MAX_AUDIO_FRAME_SIZE*8) |
{ |
yield(); |
} |
spinlock_lock(&astream.lock); |
memcpy(astream.buffer+astream.count, decoder_buffer, data_size); |
astream.count += data_size; |
spinlock_unlock(&astream.lock); |
} |
else audio_size = 0; |
} |
} |
// Free the packet that was allocated by av_read_frame |
av_free_packet(&packet); |
}; |
}; |
__int64 _lseeki64(int fd, __int64 offset, int origin ) |
{ |
int off = offset; |
return lseek(fd, off, origin); |
} |
/programs/media/Fplay/fplay.h |
---|
0,0 → 1,79 |
#define BLACK_MAGIC_SOUND |
#define BLACK_MAGIC_VIDEO |
typedef struct |
{ |
volatile uint32_t lock; |
char *buffer; |
volatile uint32_t count; |
}astream_t; |
typedef struct |
{ |
unsigned int code; |
unsigned int sender; |
unsigned int stream; |
unsigned int offset; |
unsigned int size; |
unsigned int unused[2]; |
}SND_EVENT; |
extern astream_t astream; |
extern AVRational video_time_base; |
int init_audio(int format); |
int init_video(AVCodecContext *ctx); |
int decode_video(AVCodecContext *ctx, AVPacket *pkt); |
double get_master_clock(); |
int create_thread(void (*proc)(void *param), void *param, int stack_size); |
void spinlock_lock(volatile uint32_t *val); |
static inline void spinlock_unlock(volatile uint32_t *val) |
{ |
*val = 0; |
} |
static inline void GetNotify(void *event) |
{ |
__asm__ __volatile__ ( |
"int $0x40" |
::"a"(68),"b"(14),"c"(event)); |
} |
static inline uint32_t check_os_event() |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(11)); |
return val; |
}; |
static inline uint32_t get_os_button() |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(17)); |
return val>>8; |
}; |
static inline void yield(void) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(68), "b"(1)); |
}; |
static inline void delay(uint32_t time) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(5), "b"(time)); |
}; |
/programs/media/Fplay/sound.h |
---|
0,0 → 1,138 |
#ifndef _SOUND_H_ |
#define _SOUND_H_ |
#ifdef __cplusplus |
extern "C" |
{ |
#endif |
#define SOUND_VERSION 0x0101 |
#define PCM_ALL 0 |
#define PCM_OUT 0x08000000 |
#define PCM_RING 0x10000000 |
#define PCM_STATIC 0x20000000 |
#define PCM_FLOAT 0x40000000 |
#define PCM_FILTER 0x80000000 |
#define PCM_2_16_48 1 |
#define PCM_1_16_48 2 |
#define PCM_2_16_44 3 |
#define PCM_1_16_44 4 |
#define PCM_2_16_32 5 |
#define PCM_1_16_32 6 |
#define PCM_2_16_24 7 |
#define PCM_1_16_24 8 |
#define PCM_2_16_22 9 |
#define PCM_1_16_22 10 |
#define PCM_2_16_16 11 |
#define PCM_1_16_16 12 |
#define PCM_2_16_12 13 |
#define PCM_1_16_12 14 |
#define PCM_2_16_11 15 |
#define PCM_1_16_11 16 |
#define PCM_2_16_8 17 |
#define PCM_1_16_8 18 |
#define PCM_2_8_48 19 |
#define PCM_1_8_48 20 |
#define PCM_2_8_44 21 |
#define PCM_1_8_44 22 |
#define PCM_2_8_32 23 |
#define PCM_1_8_32 24 |
#define PCM_2_8_24 25 |
#define PCM_1_8_24 26 |
#define PCM_2_8_22 27 |
#define PCM_1_8_22 28 |
#define PCM_2_8_16 29 |
#define PCM_1_8_16 30 |
#define PCM_2_8_12 31 |
#define PCM_1_8_12 32 |
#define PCM_2_8_11 33 |
#define PCM_1_8_11 34 |
#define PCM_2_8_8 35 |
#define PCM_1_8_8 36 |
#define SRV_GETVERSION 0 |
#define SND_CREATE_BUFF 1 |
#define SND_DESTROY_BUFF 2 |
#define SND_SETFORMAT 3 |
#define SND_GETFORMAT 4 |
#define SND_RESET 5 |
#define SND_SETPOS 6 |
#define SND_GETPOS 7 |
#define SND_SETBUFF 8 |
#define SND_OUT 9 |
#define SND_PLAY 10 |
#define SND_STOP 11 |
#define SND_SETVOLUME 12 |
#define SND_GETVOLUME 13 |
#define SND_SETPAN 14 |
#define SND_GETPAN 15 |
#define SND_GETBUFFSIZE 16 |
#define SND_GETFREESPACE 17 |
#define SND_SETTIMEBASE 18 |
#define SND_GETTIMESTAMP 19 |
#define PLAY_SYNC 0x80000000 |
typedef struct |
{ |
unsigned int riff_id; |
unsigned int riff_size; |
unsigned int riff_format; |
unsigned int fmt_id; |
unsigned int fmt_size; |
unsigned short int wFormatTag; |
unsigned short int nChannels; |
unsigned int nSamplesPerSec; |
unsigned int nAvgBytesPerSec; |
unsigned short int nBlockAlign; |
unsigned short int wBitsPerSample; |
unsigned int data_id; |
unsigned int data_size; |
} WAVEHEADER; |
typedef unsigned int SNDBUF; |
int _stdcall InitSound(int *version); |
int _stdcall CreateBuffer(unsigned int format,int size,SNDBUF *buf); |
int _stdcall DestroyBuffer(SNDBUF hBuff); |
int _stdcall SetFormat(SNDBUF hBuff, unsigned int format); |
int _stdcall GetFormat(SNDBUF hBuff, unsigned int *format); |
int _stdcall ResetBuffer(SNDBUF hBuff, unsigned int flags); |
int _stdcall SetBufferPos(SNDBUF hBuff, int offset); |
int _stdcall GetBufferPos(SNDBUF hBuff, int *offset); |
int _stdcall GetBufferSize(SNDBUF hBuff, int *size); |
int _stdcall GetBufferFree(SNDBUF hBuff, int *free); |
int _stdcall SetBuffer(SNDBUF hBuff,void* buff, |
int offs, int size); |
int _stdcall WaveOut(SNDBUF hBuff,void *buff, int size); |
int _stdcall PlayBuffer(SNDBUF hBuff,unsigned int flags); |
int _stdcall StopBuffer(SNDBUF hBuff); |
int _stdcall SetVolume(SNDBUF hBuff, int left, int right); |
int _stdcall GetVolume(SNDBUF hBuff, int *left, int *right); |
int _stdcall SetPan(SNDBUF hBuff, int pan); |
int _stdcall GetPan(SNDBUF hBuff, int *pan); |
int _stdcall GetMasterVol(int* vol); |
int _stdcall SetMasterVol(int vol); |
int _stdcall SetTimeBase(SNDBUF hBuff, double base); |
int _stdcall GetTimeStamp(SNDBUF hBuff, double *stamp); |
unsigned int _stdcall test_wav(WAVEHEADER *hdr); |
#ifdef __cplusplus |
extern "C" |
} |
#endif |
#endif //_SOUND_H_ |
/programs/media/Fplay/video.c |
---|
0,0 → 1,272 |
#include <stdint.h> |
#include <libavcodec/avcodec.h> |
#include <libavformat/avformat.h> |
#include <libswscale/swscale.h> |
#include "fplay.h" |
void video_thread(void *param); |
void draw_bitmap(void *bitmap, int x, int y, int w, int h) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(7), "b"(bitmap), |
"c"((w << 16) | h), |
"d"((x << 16) | y)); |
} |
typedef struct |
{ |
AVFrame *frame; |
uint8_t *buffer; |
double pts; |
volatile int ready; |
}vframe_t; |
vframe_t frames[8]; |
struct SwsContext *cvt_ctx; |
int vfx = 0; |
int dfx = 0; |
int width; |
int height; |
AVRational video_time_base; |
AVFrame *Frame; |
int init_video(AVCodecContext *ctx) |
{ |
uint32_t size; |
int i; |
width = ctx->width; |
height = ctx->height; |
printf("w = %d h = %d\n\r", width, height); |
Frame = avcodec_alloc_frame(); |
if ( Frame == NULL ) |
{ |
printf("Cannot alloc video buffer\n\r"); |
return 0; |
}; |
cvt_ctx = sws_getContext( |
ctx->width, |
ctx->height, |
ctx->pix_fmt, |
ctx->width, |
ctx->height, |
PIX_FMT_BGR24, |
SWS_BILINEAR, |
NULL, NULL, NULL); |
if(cvt_ctx == NULL) |
{ |
printf("Cannot initialize the conversion context!\n"); |
return 0; |
} |
size = avpicture_get_size(PIX_FMT_RGB24, ctx->width, ctx->height); |
for( i=0; i < 8; i++) |
{ |
AVFrame *frame; |
frame = avcodec_alloc_frame(); |
if( frame ) |
{ |
uint8_t *buffer = (uint8_t*)av_malloc(size); |
if( buffer ) |
{ |
avpicture_fill((AVPicture *)frame, buffer, PIX_FMT_BGR24, |
ctx->width, ctx->height); |
frames[i].frame = frame; |
frames[i].buffer = buffer; |
frames[i].pts = 0; |
frames[i].ready = 0; |
continue; |
}; |
}; |
printf("Cannot alloc frame buffer\n\r"); |
return 0; |
}; |
create_thread(video_thread, 0, 163840); |
return 1; |
}; |
int frameFinished=0; |
int decode_video(AVCodecContext *ctx, AVPacket *pkt) |
{ |
double pts; |
AVPicture pict; |
const uint8_t *data[4]; |
double av_time; |
// __asm__("int3"); |
if(avcodec_decode_video(ctx, Frame, &frameFinished, |
pkt->data, pkt->size) <= 0) |
printf("decode error\n"); |
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); |
if(frameFinished) |
{ |
while( frames[dfx].ready != 0 ) |
yield(); |
pict.data[0] = frames[dfx].frame->data[0]; |
pict.data[1] = frames[dfx].frame->data[1]; |
pict.data[2] = frames[dfx].frame->data[2]; |
pict.data[3] = NULL; |
pict.linesize[0] = frames[dfx].frame->linesize[0]; |
pict.linesize[1] = frames[dfx].frame->linesize[1]; |
pict.linesize[2] = frames[dfx].frame->linesize[2]; |
pict.linesize[3] = 0; |
data[0] = Frame->data[0]; |
data[1] = Frame->data[1]; |
data[2] = Frame->data[2]; |
data[3] = NULL; |
sws_scale(cvt_ctx, data, Frame->linesize, 0, ctx->height, |
pict.data, pict.linesize); |
frames[dfx].pts = pts*1000.0; |
frames[dfx].ready = 1; |
dfx++; |
dfx&= 7; |
}; |
return 0; |
} |
extern volatile uint32_t status; |
typedef unsigned int color_t; |
typedef unsigned int count_t; |
typedef unsigned int u32_t; |
static void DrawWindow(int x, int y, int w, int h, char *name, |
color_t workcolor, u32_t style) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(0), |
"b"((x << 16) | (w & 0xFFFF)), |
"c"((y << 16) | (h & 0xFFFF)), |
"d"((style << 24) | (workcolor & 0xFFFFFF)), |
"D"(name)); |
}; |
static int check_events() |
{ |
int ev; |
ev = check_os_event(); |
switch(ev) |
{ |
case 1: |
DrawWindow(10, 10, width+9, height+26, NULL, 0x000000,0x74); |
break; |
case 3: |
if(get_os_button()==1) |
status = 0; |
break; |
}; |
return 1; |
} |
extern char __cmdline[]; |
void video_thread(void *param) |
{ |
char *path; |
path = strrchr(__cmdline,'/')+1; |
DrawWindow(10, 10, width+9, height+26, path, 0x000000,0x74); |
while( status != 0) |
{ |
double ctime; |
double fdelay; |
check_events(); |
if(frames[vfx].ready == 1 ) |
{ |
ctime = get_master_clock(); |
fdelay = (frames[vfx].pts - ctime); |
// printf("ctime %f pts %f delay %f\n", |
// ctime, frames[vfx].pts, fdelay); |
if(fdelay < 0.0 ) |
{ |
int next_vfx; |
fdelay = 0; |
next_vfx = (vfx+1) & 7; |
if( frames[next_vfx].ready == 1 ) |
{ |
if(frames[next_vfx].pts <= ctime) |
{ |
frames[vfx].ready = 0; // skip this frame |
vfx++; |
vfx&= 7; |
} |
else |
{ |
if( (frames[next_vfx].pts - ctime) < |
( ctime - frames[vfx].pts) ) |
{ |
frames[vfx].ready = 0; // skip this frame |
vfx++; |
vfx&= 7; |
fdelay = (frames[next_vfx].pts - ctime); |
} |
} |
}; |
}; |
if(fdelay > 10.0) |
{ |
delay( (uint32_t)(fdelay/10.0)); |
}; |
draw_bitmap(frames[vfx].buffer, 0, 0, width, height); |
frames[vfx].ready = 0; |
vfx++; |
vfx&= 7; |
} |
else |
{ |
yield(); |
}; |
}; |
}; |
/programs/media/Fplay |
---|
Property changes: |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |