Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 4437 → Rev 4438

/contrib/media/fplay/audio.c
0,0 → 1,442
 
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include "libswresample/swresample.h"
 
#include <stdio.h>
#include <string.h>
#include "../winlib/winlib.h"
#include "sound.h"
#include "fplay.h"
 
 
astream_t astream;
 
extern uint8_t *decoder_buffer;
int resampler_size;
volatile int sound_level_0;
volatile int sound_level_1;
 
volatile enum player_state player_state;
volatile enum player_state decoder_state;
volatile enum player_state sound_state;
 
extern volatile uint32_t driver_lock;
 
static SNDBUF hBuff;
 
static int snd_format;
int sample_rate;
 
static uint32_t samples_written = 0;
double audio_base = -1.0;
 
double get_audio_base();
 
int init_audio(int format)
{
int err;
int version =-1;
char *errstr;
 
mutex_lock(&driver_lock);
 
if((err = InitSound(&version)) !=0 )
{
mutex_unlock(&driver_lock);
errstr = "Sound service not installed\n\r";
goto exit_whith_error;
};
 
mutex_unlock(&driver_lock);
 
// 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;
 
create_thread(audio_thread, 0, 163840);
 
return 1;
 
exit_whith_error:
 
printf(errstr);
return 0;
};
 
void set_audio_volume(int left, int right)
{
SetVolume(hBuff, left, right);
};
 
static uint64_t samples_lost;
static double audio_delta;
static double last_time_stamp;
 
 
double get_master_clock(void)
{
double tstamp;
 
GetTimeStamp(hBuff, &tstamp);
return tstamp - audio_delta;
};
 
int decode_audio(AVCodecContext *ctx, queue_t *qa)
{
static struct SwrContext *swr_ctx;
static int64_t src_layout;
static int src_freq;
static int src_channels;
static enum AVSampleFormat src_fmt = -1;
static AVFrame *aFrame;
 
AVPacket pkt;
AVPacket pkt_tmp;
int64_t dec_channel_layout;
int len, len2;
int got_frame;
int data_size;
 
 
if( astream.count > 192000*2)
return -1;
 
if( get_packet(qa, &pkt) == 0 )
return 0;
 
// __asm__("int3");
 
if (!aFrame)
{
if (!(aFrame = avcodec_alloc_frame()))
return -1;
} else
avcodec_get_frame_defaults(aFrame);
 
pkt_tmp = pkt;
 
while(pkt_tmp.size > 0)
{
data_size = 192000;
 
// len = avcodec_decode_audio3(ctx,(int16_t*)decoder_buffer,
// &data_size, &pkt_tmp);
got_frame = 0;
len = avcodec_decode_audio4(ctx, aFrame, &got_frame, &pkt_tmp);
 
if(len >= 0 && got_frame)
{
char *samples;
int ch, plane_size;
int planar = av_sample_fmt_is_planar(ctx->sample_fmt);
int data_size = av_samples_get_buffer_size(&plane_size, ctx->channels,
aFrame->nb_samples,
ctx->sample_fmt, 1);
 
// if(audio_base == -1.0)
// {
// if (pkt.pts != AV_NOPTS_VALUE)
// audio_base = get_audio_base() * pkt.pts;
// printf("audio base %f\n", audio_base);
// };
 
pkt_tmp.data += len;
pkt_tmp.size -= len;
 
dec_channel_layout =
(aFrame->channel_layout && aFrame->channels == av_get_channel_layout_nb_channels(aFrame->channel_layout)) ?
aFrame->channel_layout : av_get_default_channel_layout(aFrame->channels);
 
if (aFrame->format != src_fmt ||
dec_channel_layout != src_layout ||
aFrame->sample_rate != src_freq ||
!swr_ctx)
{
swr_free(&swr_ctx);
swr_ctx = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16,
aFrame->sample_rate, dec_channel_layout,aFrame->format,
aFrame->sample_rate, 0, NULL);
if (!swr_ctx || swr_init(swr_ctx) < 0)
{
printf("Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
aFrame->sample_rate, av_get_sample_fmt_name(aFrame->format), (int)aFrame->channels,
aFrame->sample_rate, av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 2);
break;
}
 
src_layout = dec_channel_layout;
src_channels = aFrame->channels;
src_freq = aFrame->sample_rate;
src_fmt = aFrame->format;
};
 
if (swr_ctx)
{
const uint8_t **in = (const uint8_t **)aFrame->extended_data;
uint8_t *out[] = {decoder_buffer};
int out_count = 192000 * 3 / 2 / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
len2 = swr_convert(swr_ctx, out, out_count, in, aFrame->nb_samples);
if (len2 < 0) {
printf("swr_convert() failed\n");
break;
}
if (len2 == out_count) {
printf("warning: audio buffer is probably too small\n");
swr_init(swr_ctx);
}
data_size = len2 * 2 * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
 
mutex_lock(&astream.lock);
 
samples = astream.buffer+astream.count;
 
memcpy(samples, decoder_buffer, data_size);
/*
memcpy(samples, aFrame->extended_data[0], plane_size);
 
if (planar && ctx->channels > 1)
{
uint8_t *out = ((uint8_t *)samples) + plane_size;
for (ch = 1; ch < ctx->channels; ch++)
{
memcpy(out, aFrame->extended_data[ch], plane_size);
out += plane_size;
}
}
*/
astream.count += data_size;
mutex_unlock(&astream.lock);
};
}
else pkt_tmp.size = 0;
}
av_free_packet(&pkt);
return 1;
};
 
 
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);
{
if(astream.count < buffsize)
{
memset(astream.buffer+astream.count,
0, buffsize-astream.count);
astream.count = buffsize;
};
 
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)
{
errstr = "Cannot create sound buffer\n\r";
goto exit_whith_error;
};
 
SetVolume(hBuff,-1875,-1875);
 
if((err = GetBufferSize(hBuff, &buffsize)) != 0)
{
errstr = "Cannot get buffer size\n\r";
goto exit_whith_error;
};
 
resampler_size = buffsize = buffsize/2;
 
samples = buffsize/4;
 
while( player_state != CLOSED)
{
uint32_t offset;
double event_stamp, wait_stamp;
int too_late = 0;
 
switch(sound_state)
{
case PREPARE:
 
mutex_lock(&astream.lock);
if(astream.count < buffsize*2)
{
memset(astream.buffer+astream.count,
0, buffsize*2-astream.count);
astream.count = buffsize*2;
};
 
SetBuffer(hBuff, astream.buffer, 0, buffsize*2);
astream.count -= buffsize*2;
if(astream.count)
memcpy(astream.buffer, astream.buffer+buffsize*2, astream.count);
mutex_unlock(&astream.lock);
 
SetTimeBase(hBuff, audio_base);
 
case PAUSE_2_PLAY:
GetTimeStamp(hBuff, &last_time_stamp);
// printf("last audio time stamp %f\n", 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);
sound_state = PLAY;
// printf("render: set audio latency to %f\n", audio_delta);
 
/* breaktrough */
 
case PLAY:
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;
};
 
offset = evnt.offset;
 
mutex_lock(&astream.lock);
if(astream.count < buffsize)
{
memset(astream.buffer+astream.count,
0, buffsize-astream.count);
astream.count = buffsize;
};
 
SetBuffer(hBuff, astream.buffer, offset, buffsize);
 
{
double val = 0;
int16_t *src = (int16_t*)astream.buffer;
int samples = buffsize/2;
int i;
 
for(i = 0, val = 0; i < samples/2; i++, src++)
if(val < abs(*src))
val= abs(*src); // * *src;
 
sound_level_0 = val; //sqrt(val / (samples/2));
 
for(i = 0, val = 0; i < samples/2; i++, src++)
if(val < abs(*src))
val= abs(*src); // * *src;
 
sound_level_1 = val; //sqrt(val / (samples/2));
 
// printf("%d\n", sound_level);
};
 
samples_written+= buffsize/4;
 
astream.count -= buffsize;
if(astream.count)
memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
mutex_unlock(&astream.lock);
break;
 
case PLAY_2_STOP:
if( active )
{
ResetBuffer(hBuff, SND_RESET_ALL);
audio_base = -1.0;
active = 0;
}
sound_state = STOP;
break;
 
case PLAY_2_PAUSE:
if( active )
{
StopBuffer(hBuff);
};
sound_state = PAUSE;
 
case PAUSE:
case STOP:
delay(1);
};
}
 
StopBuffer(hBuff);
DestroyBuffer(hBuff);
 
return 0;
 
exit_whith_error:
 
printf(errstr);
return -1;
 
};
 
/contrib/media/fplay/fplay.c
0,0 → 1,530
 
#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 <ctype.h>
#include <kos32sys.h>
#include "../winlib/winlib.h"
 
#include "sound.h"
#include "fplay.h"
 
volatile enum player_state player_state = STOP;
volatile enum player_state decoder_state = PREPARE;
volatile enum player_state sound_state = STOP;
 
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 resampler_size;
 
extern int sample_rate;
char *movie_file;
 
void flush_video();
 
queue_t q_video;
queue_t q_audio;
int64_t rewind_pos;
 
int64_t stream_duration;
 
extern double audio_base;
 
double get_audio_base()
{
 
return (double)av_q2d(pFormatCtx->streams[audioStream]->time_base)*1000;
 
};
 
 
 
int main( int argc, char *argv[])
{
int i;
char *file_name, *dot;
 
if(argc < 2)
{
movie_file = get_moviefile();
if(movie_file == NULL)
{
printf("Please provide a movie file\n");
return -1;
}
}
else movie_file = argv[1];
 
/* register all codecs, demux and protocols */
 
#if 0
{
int fd, i;
char *buff;
uint32_t start, stop;
 
fd = open(movie_file,O_RDONLY);
 
if(fd < 0)
return 0;
 
buff = user_alloc(65536);
memset(buff, 0, 65536);
 
start = get_tick_count();
 
for(i = 0; i < 1024*1024*1024; i+=65536)
{
if(read(fd, buff, 65536) < 0)
break;
 
};
stop = get_tick_count();
 
printf("average speed %d Kbytes/c\n", ((i/1024)*100)/(stop-start));
};
return 0;
};
 
#else
 
av_log_set_level(AV_LOG_FATAL);
 
avcodec_register_all();
avdevice_register_all();
av_register_all();
 
// init_pixlib(HW_BIT_BLIT|HW_TEX_BLIT);
 
if( avformat_open_input(&pFormatCtx, movie_file, NULL, NULL) < 0)
{
printf("Cannot open file %s\n\r", movie_file);
return -1; // Couldn't open file
};
 
pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
 
// Retrieve stream information
if(avformat_find_stream_info(pFormatCtx, NULL)<0)
{
printf("Cannot find streams\n\r");
return -1;
};
 
file_name = strrchr(movie_file,'/')+1;
dot = strrchr(file_name,'.');
if(dot)
{
movie_file = malloc(dot-file_name+1);
memcpy(movie_file, file_name, dot-file_name);
movie_file[dot-file_name] = 0;
}
else movie_file = file_name;
 
 
// __asm__ __volatile__("int3");
 
// dump_format(pFormatCtx, 0, argv[1], 0);
 
// stream_duration = 1000.0 * pFormatCtx->duration * av_q2d(AV_TIME_BASE_Q);
stream_duration = pFormatCtx->duration;
 
printf("duration %f\n", (double)stream_duration);
// Find the first video stream
videoStream=-1;
audioStream=-1;
for(i=0; i < pFormatCtx->nb_streams; i++)
{
// pFormatCtx->streams[i]->discard = AVDISCARD_ALL;
 
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
&& videoStream < 0)
{
videoStream=i;
video_time_base = pFormatCtx->streams[i]->time_base;
if(stream_duration == 0)
// stream_duration = 1000.0 *
// pFormatCtx->streams[i]->duration *
// av_q2d(pFormatCtx->streams[i]->time_base);
stream_duration = pFormatCtx->streams[i]->duration;
 
}
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
audioStream < 0)
{
audioStream=i;
if(stream_duration == 0)
// stream_duration = 1000.0 *
// pFormatCtx->streams[i]->duration *
// av_q2d(pFormatCtx->streams[i]->time_base);
stream_duration = pFormatCtx->streams[i]->duration;
 
}
}
 
if(videoStream==-1)
{
printf("Video stream not detected\n\r");
return -1; // Didn't find a video stream
};
 
#if 0
{
AVPacket packet;
int psize = 0;
uint32_t start, stop;
 
int err;
start = get_tick_count();
 
while(psize < 1024*1024*1024)
{
err = av_read_frame(pFormatCtx, &packet);
if(err != 0)
break;
psize+= packet.size;
av_free_packet(&packet);
};
 
stop = get_tick_count();
 
printf("average speed %d Kbytes/c\n", ((psize/1024)*100)/(stop-start));
 
return 1;
};
};
#else
 
 
// __asm__ __volatile__("int3");
 
// 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
 
// init_hw_context(pCodecCtx);
 
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
 
// printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
 
if(pCodec==NULL) {
printf("Unsupported codec with id %d for input stream %d\n",
pCodecCtx->codec_id, videoStream);
return -1; // Codec not found
}
 
if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
printf("Error while opening codec for input stream %d\n",
videoStream);
return -1; // Could not open codec
};
 
// printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
 
 
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_open2(aCodecCtx, aCodec, NULL) >= 0 )
{
WAVEHEADER whdr;
int fmt;
int channels;
 
printf("audio stream rate %d channels %d format %d\n",
aCodecCtx->sample_rate, aCodecCtx->channels, aCodecCtx->sample_fmt );
whdr.riff_id = 0x46464952;
whdr.riff_format = 0x45564157;
whdr.wFormatTag = 0x01;
whdr.nSamplesPerSec = aCodecCtx->sample_rate;
whdr.nChannels = 2;
whdr.wBitsPerSample = 16;
 
sample_rate = aCodecCtx->sample_rate;
 
fmt = test_wav(&whdr);
 
if( init_audio(fmt) )
{
decoder_buffer = (uint8_t*)av_mallocz(192000*2+64);
if( decoder_buffer != NULL )
{
astream.lock = 0;
astream.count = 0;
astream.buffer = (char *)av_mallocz(192000*3);
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;
 
// __asm__ __volatile__("int3");
 
decoder();
 
// 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;
}
 
 
static int load_frame()
{
AVPacket packet;
int err;
 
err = av_read_frame(pFormatCtx, &packet);
if( err == 0)
{
if(packet.stream_index==videoStream)
put_packet(&q_video, &packet);
else if( (packet.stream_index == audioStream) &&
(have_sound != 0) )
{
put_packet(&q_audio, &packet);
if(audio_base == -1.0)
{
if (packet.pts != AV_NOPTS_VALUE)
audio_base = get_audio_base() * packet.pts;
// printf("audio base %f\n", audio_base);
};
}
else av_free_packet(&packet);
}
else if (err != AVERROR_EOF)
printf("av_read_frame: error %x\n", err);
 
return err;
}
 
 
 
static int fill_queue()
{
int err = 0;
AVPacket packet;
 
// __asm__ __volatile__("int3");
 
while( (q_video.size < 4*1024*1024) &&
!err )
err = load_frame();
 
return err;
 
};
 
 
static void flush_all()
{
AVPacket packet;
 
avcodec_flush_buffers(pCodecCtx);
avcodec_flush_buffers(aCodecCtx);
while( get_packet(&q_video, &packet) != 0)
av_free_packet(&packet);
 
while( get_packet(&q_audio, &packet)!= 0)
av_free_packet(&packet);
 
flush_video();
 
astream.count = 0;
};
 
void decoder()
{
int eof;
AVPacket packet;
int ret, vret, aret;
 
int64_t min_pos, max_pos;
 
while( player_state != CLOSED )
{
int err;
 
// __asm__ __volatile__("int3");
 
switch(decoder_state)
{
case PREPARE:
eof = fill_queue();
 
do
{
if( (q_video.size < 4*1024*1024) &&
(eof == 0) )
{
eof = load_frame();
}
decode_video(pCodecCtx, &q_video);
ret = decode_audio(aCodecCtx, &q_audio);
}while(astream.count < resampler_size*2 &&
ret == 1);
 
sound_state = PREPARE;
decoder_state = PLAY;
player_state = PLAY;
 
case PLAY:
if( (q_video.size < 4*1024*1024) &&
(eof == 0) )
{
eof = load_frame();
}
vret = decode_video(pCodecCtx, &q_video);
aret = decode_audio(aCodecCtx, &q_audio);
ret = vret | aret;
 
if( eof && !ret)
{
decoder_state = STOP;
continue;
};
 
if( (vret & aret) == -1)
{
if( (q_video.size < 4*1024*1024) &&
(eof == 0) )
{
eof = load_frame();
yield();
continue;
};
delay(1);
continue;
}
 
yield();
continue;
 
case STOP:
delay(1);
continue;
 
 
case PLAY_2_STOP:
while(sound_state != STOP)
delay(1);
 
flush_all();
 
if (pFormatCtx->start_time != AV_NOPTS_VALUE)
rewind_pos = pFormatCtx->start_time;
else
rewind_pos = 0;
 
ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
rewind_pos, INT64_MAX, 0);
 
decoder_state = STOP;
break;
 
case REWIND:
while(sound_state != STOP)
yield();
 
flush_all();
int opts = 0;
if(rewind_pos < 0)
{
rewind_pos = -rewind_pos;
opts = AVSEEK_FLAG_BACKWARD;
};
 
if (pFormatCtx->start_time != AV_NOPTS_VALUE)
rewind_pos += pFormatCtx->start_time;
 
// printf("rewind %8"PRId64"\n", rewind_pos);
min_pos = rewind_pos - 1000000;
max_pos = rewind_pos + 1000000;
 
ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
rewind_pos, INT64_MAX, 0);
 
// ret = avformat_seek_file(pFormatCtx, -1, min_pos,
// rewind_pos, max_pos, opts);
// __asm__ __volatile__("int3");
 
if (ret < 0)
{
printf("could not seek to position %f\n",
(double)rewind_pos / AV_TIME_BASE);
}
 
// printf("restart\n");
decoder_state = PREPARE;
break;
}
};
 
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);
};
#endif
#endif
/contrib/media/fplay/fplay.h
0,0 → 1,143
 
#include "pixlib2.h"
 
#define BLACK_MAGIC_SOUND
#define BLACK_MAGIC_VIDEO
 
typedef unsigned int color_t;
typedef unsigned int count_t;
 
typedef struct render render_t;
 
#define HAS_LEFT (1<<0)
#define HAS_TOP (1<<1)
#define HAS_RIGHT (1<<2)
#define HAS_BOTTOM (1<<3)
 
struct render
{
uint32_t caps;
uint32_t ctx_width;
uint32_t ctx_height;
uint32_t win_width;
uint32_t win_height;
 
rect_t rc_client;
rect_t rcvideo;
rect_t rcleft;
rect_t rctop;
rect_t rcright;
rect_t rcbottom;
 
uint32_t layout;
bitmap_t bitmap[4];
bitmap_t *last_bitmap;
 
uint32_t ctx_format;
int target;
 
window_t *win;
enum{
EMPTY, INIT }state;
enum win_state win_state;
 
void (*draw)(render_t *render, AVPicture *picture);
};
 
enum player_state
{
CLOSED = 0,
PREPARE,
STOP,
PAUSE,
PLAY,
REWIND,
PLAY_2_STOP,
PLAY_2_PAUSE,
PAUSE_2_PLAY,
REWIND_2_PLAY,
};
 
#define ID_PLAY 100
#define ID_STOP 101
#define ID_PROGRESS 102
#define ID_VOL_LEVEL 103
#define ID_VOL_CTRL 104
 
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;
 
 
typedef struct {
AVPacketList *first_pkt;
AVPacketList *last_pkt;
int size;
int count;
volatile uint32_t lock;
} queue_t;
 
int put_packet(queue_t *q, AVPacket *pkt);
int get_packet(queue_t *q, AVPacket *pkt);
 
 
extern astream_t astream;
extern AVRational video_time_base;
 
render_t *create_render(window_t *win, AVCodecContext *ctx, uint32_t flags);
void destroy_render(render_t *render);
int init_render(render_t *render, int width, int height);
void render_adjust_size(render_t *render, window_t *win);
void render_set_size(render_t *render, int width, int height);
void render_draw_client(render_t *render);
 
 
int init_audio(int format);
int audio_thread(void *param);
void set_audio_volume(int left, int right);
 
int init_video(AVCodecContext *ctx);
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(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)
{
__asm__ __volatile__ (
"int $0x40"
::"a"(68),"b"(14),"c"(event));
}
 
 
 
int init_fontlib();
int draw_text(bitmap_t *winbitmap, int face, char *text, int x, int y, int color);
int draw_text_ext(bitmap_t *winbitmap, int face, char *text, rect_t *rc, int color);
char *get_moviefile();
 
/contrib/media/fplay/opendial.asm
0,0 → 1,149
format MS COFF
 
public _get_moviefile
 
section '.text' align 16
 
align 4
getprocaddress:
mov edx, [esp + 8] ; hlib
xor eax, eax
test edx, edx ; If hlib = 0 then goto .end
jz .end
 
.next:
cmp [edx], dword 0 ; If end of export table then goto .end
jz .end
 
xor eax, eax
mov esi, [edx]
mov edi, [esp + 4] ; name
 
.next_:
lodsb
scasb
jne .fail
or al, al
jnz .next_
jmp .ok
.fail:
add edx, 8
jmp .next
 
.ok: ; return address
mov eax, [edx + 4]
.end:
ret 8
 
 
 
align 8
_get_moviefile:
 
pushad
mov eax, 68
mov ebx, 19
mov ecx, sz_proc_lib
int 0x40
mov [proclib], eax
test eax, eax
jz .fail
 
push [proclib]
push sz_OpenDialog_init
call getprocaddress
mov [opendialog_init], eax
 
push dword[proclib]
push sz_OpenDialog_start
call getprocaddress
mov [opendialog_start], eax
 
mov eax, 68
mov ebx, 12
mov ecx, 4096*3
int 0x40
 
mov [od.procinfo], eax
 
add eax, 1024
mov [od.filename_area], eax
 
add eax, 3072
mov [od.opendir_path], eax
 
add eax, 4096
mov [od.openfile_path], eax
 
push od
call [opendialog_init]
 
mov eax, [od.openfile_path]
mov [eax], byte 0 ; end of ASCIIZ-string(may be don't need?)
 
push od
call [opendialog_start]
 
popad
mov eax, [od.openfile_path]; selected filePath
 
ret
.fail:
xor eax, eax
ret
 
align 4
fake_on_redraw:
ret
 
section '.rdata' align 16
 
sz_proc_lib db "/rd/1/lib/proc_lib.obj",0
sz_OpenDialog_init db "OpenDialog_init",0
sz_OpenDialog_start db "OpenDialog_start",0
sz_com_area_name db "FFFFFFFF_open_dialog",0
sz_dir_default_path db "/rd/1",0
sz_start_path db "/rd/1/File managers/opendial",0
 
 
section '.data' align 16
 
od:
.mode dd 0
.procinfo dd 0
.com_area_name dd sz_com_area_name
.com_area dd 0
.opendir_path dd 0
.dir_default_path dd sz_dir_default_path
.start_path dd sz_start_path
.draw_window dd fake_on_redraw
.status dd 0
.openfile_path dd 0
.filename_area dd 0
.filter_area dd filefilter
.x_size dw 512
.x_start dw 512
.y_size dw 512
.y_start dw 512
 
filefilter:
dd filefilter.end - filefilter
db 'avi',0
db 'flv',0
db 'mov',0
db 'mpg',0
db 'mpeg',0
db 'mkv',0
db 'mp4',0
db 'webm',0
db 'wmv',0
.end:
db 0
 
 
section '.bss' align 16
 
proclib dd ?
opendialog_init dd ?
opendialog_start dd ?
 
/contrib/media/fplay/skin/clbhl.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/clbn.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/clbp.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/cptbody.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/cptleft.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/cptright.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/fullbhl.raw
0,0 → 1,27
ÿ
ÿÿ
+ÿ ÿ ÿ ÿÿÿGFBÿaa[ÿcb\ÿfe\ÿgf]ÿhg]ÿih]ÿji]ÿji]ÿih]ÿih]ÿhg]ÿfe\ÿdd\ÿbb\ÿGGAÿ
+ ÿÿGGAÿ;:1ÿ>=2ÿB@3ÿCB3ÿEC3ÿGF4ÿHF4ÿHF4ÿGF4ÿGE4ÿDC3ÿBA3ÿ@?2ÿ?>4ÿED=ÿ
+ÿ
+ ÿ.-"ÿ&%ÿb\ÿßÑ.ÿŒ„"ÿŒ„"ÿ…"ÿŽ…"ÿŽ…"ÿŽ…"ÿ„"ÿŒ„"ÿ§&ÿ÷*ÿ*(ÿ., ÿÿ
+ÿÿ%$ÿÿÿ!ÿ" ÿ#!ÿ$"ÿ%#ÿ%#ÿ%#ÿ$"ÿ#!ÿ" ÿ ÿÿ$#ÿ
+ÿÿ!!ÿ ÿ#"ÿ%$ÿ%$ÿ&%ÿ'&ÿ'&ÿ('ÿ'&ÿ&%ÿ%$ÿ%$ÿ$#ÿ! ÿ ÿ ÿ
+
+ÿ ÿ ÿÿÿ
\ No newline at end of file
/contrib/media/fplay/skin/fullbn.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/fullbp.raw
0,0 → 1,26
ÿ
ÿÿ
+ÿ ÿ ÿ
+ÿÿÿ"!ÿÿ#!ÿ&%ÿ(&ÿ*(ÿ-+ÿ.,ÿ.,ÿ-+ÿ,*ÿ)'ÿ'&ÿ%#ÿ! ÿ%$ÿ
+ÿ
+ ÿ/.#ÿ'&ÿb]ÿßÑ.ÿ„#ÿ„#ÿŽ…#ÿŽ…#ÿ†#ÿŽ…#ÿ…#ÿ„#ÿ¨&ÿ÷*ÿ)(ÿ1/#ÿÿ
+ ÿ++"ÿ$"ÿ53ÿb\ÿb] ÿb] ÿd^ ÿe_ ÿe_ ÿd^ ÿc] ÿb] ÿb] ÿSOÿ%$ÿ-,#ÿÿÿ*)"ÿ ÿ$"ÿ%$ÿ&%ÿ'&ÿ('ÿ)(ÿ)(ÿ)(ÿ('ÿ'&ÿ&%ÿ%#ÿ"!ÿ**"ÿ ÿÿ&% ÿ%$ÿ('ÿ)(ÿ*)ÿ+*ÿ,+ÿ,+ÿ-,ÿ,+ÿ+*ÿ*)ÿ)(ÿ('ÿ&%ÿ'&!ÿ
+ ÿ
+
+ÿ ÿ ÿÿÿ
\ No newline at end of file
/contrib/media/fplay/skin/istokweb.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/lborder.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/minbhl.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/minbn.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/minbp.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/panel.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/panelleft.raw
0,0 → 1,0
QQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ,,,ÿÿÿÿÿÿÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ
/contrib/media/fplay/skin/panelright.raw
0,0 → 1,0
QQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿQQQÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿÿÿÿÿÿÿ,,,ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ333ÿ
/contrib/media/fplay/skin/pausebp.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/pausebtn.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/pbar.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/playbp.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/playbtn.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/prg_level.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/rborder.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/size_nesw.cur
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/size_ns.cur
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/size_nwse.cur
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/size_we.cur
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/skin.asm
0,0 → 1,103
 
format MS COFF
 
public _res_caption_left
public _res_caption_right
public _res_caption_body
 
public _res_panel_left
public _res_panel_right
public _res_panel_body
 
public _res_border_left
public _res_border_right
 
 
public _res_full_btn
public _res_full_btn_hl
public _res_full_btn_pressed
public _res_minimize_btn
public _res_minimize_btn_hl
public _res_minimize_btn_pressed
public _res_close_btn
public _res_close_btn_hl
public _res_close_btn_pressed
 
 
public _res_play_btn
public _res_play_btn_pressed
 
public _res_pause_btn
public _res_pause_btn_pressed
 
public _res_stop_btn
public _res_stop_btn_pressed
 
 
public _res_cursor_ns
public _res_cursor_we
public _res_cursor_nwse
public _res_cursor_nesw
 
;public _res_logo
 
public _res_level
public _res_slider
public _res_vol_slider
 
public _res_progress_bar
public _res_prg_level
 
public _res_def_font
 
section '.rdata' data readable align 16
 
_res_caption_left: file 'cptleft.raw'
_res_caption_right: file 'cptright.raw'
_res_caption_body: file 'cptbody.raw'
 
_res_panel_left: file 'panelleft.raw'
_res_panel_right: file 'panelright.raw'
_res_panel_body: file 'panel.raw'
 
_res_border_left: file 'lborder.raw'
_res_border_right: file 'rborder.raw'
 
_res_full_btn: file 'fullbn.raw'
_res_full_btn_hl: file 'fullbhl.raw'
_res_full_btn_pressed: file 'fullbp.raw'
 
_res_minimize_btn: file 'minbn.raw'
_res_minimize_btn_hl: file 'minbhl.raw'
_res_minimize_btn_pressed: file 'minbp.raw'
 
_res_close_btn: file 'clbn.raw'
_res_close_btn_hl: file 'clbhl.raw'
_res_close_btn_pressed: file 'clbp.raw'
 
 
_res_play_btn: file 'playbtn.raw'
_res_play_btn_pressed: file 'playbp.raw'
_res_pause_btn: file 'pausebtn.raw'
_res_pause_btn_pressed: file 'pausebp.raw'
 
_res_stop_btn: file 'stopbtn.raw'
_res_stop_btn_pressed: file 'stopbtnp.raw'
 
 
 
_res_cursor_ns: file 'size_ns.cur'
_res_cursor_we: file 'size_we.cur'
_res_cursor_nwse: file 'size_nwse.cur'
_res_cursor_nesw: file 'size_nesw.cur'
 
;_res_logo: file 'logo.raw'
 
_res_level: file 'vol_level.raw'
_res_vol_slider: file 'vol_slider.raw'
_res_slider: file 'slider.raw'
 
_res_progress_bar: file 'pbar.raw'
_res_prg_level: file 'prg_level.raw'
 
_res_def_font: file 'IstokWeb.ttf'
/contrib/media/fplay/skin/slider.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/stopbtn.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/stopbtnp.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/vol_level.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/skin/vol_slider.raw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/fplay/utils.c
0,0 → 1,117
 
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <stdio.h>
#include <fcntl.h>
#include "../winlib/winlib.h"
#include "fplay.h"
 
extern uint32_t hw2d ;
 
void mutex_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" );
}
 
 
int64_t _lseeki64(int fd, int64_t offset, int origin )
{
int off = offset;
return lseek(fd, off, origin);
}
 
 
int put_packet(queue_t *q, AVPacket *pkt)
{
AVPacketList *q_pkt;
 
/* duplicate the packet */
// if (av_dup_packet(pkt) < 0)
// return -1;
 
q_pkt = av_malloc(sizeof(AVPacketList));
if (!q_pkt)
return -1;
 
q_pkt->pkt = *pkt;
q_pkt->next = NULL;
 
mutex_lock(&q->lock);
 
if (!q->last_pkt)
q->first_pkt = q_pkt;
else
q->last_pkt->next = q_pkt;
 
q->last_pkt = q_pkt;
q->size += q_pkt->pkt.size + sizeof(*q_pkt);
q->count++;
 
mutex_unlock(&q->lock);
 
return 0;
}
 
int get_packet(queue_t *q, AVPacket *pkt)
{
AVPacketList *q_pkt;
int ret = 0;
 
mutex_lock(&q->lock);
 
q_pkt = q->first_pkt;
if (q_pkt)
{
q->first_pkt = q_pkt->next;
if (!q->first_pkt)
q->last_pkt = NULL;
 
q->count--;
q->size -= q_pkt->pkt.size + sizeof(*q_pkt);
*pkt = q_pkt->pkt;
av_free(q_pkt);
ret = 1;
};
 
mutex_unlock(&q->lock);
 
return ret;
}
 
void blit_raw(ctx_t *ctx, void *raw, int x, int y, int w, int h, int pitch)
{
int *dst = (int*)ctx->pixmap->data;
int *src = raw;
int i, j;
 
dst+= y * ctx->pixmap->pitch/4 + x;
 
 
for(i=0; i < h; i++)
{
for(j = 0; j < w; j++)
dst[j] = src[j];
dst+= ctx->pixmap->pitch/4;
src+= pitch/4;
};
};
/contrib/media/fplay/video.c
0,0 → 1,1022
 
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <kos32sys.h>
#include "../winlib/winlib.h"
#include <sound.h>
#include "fplay.h"
#include <math.h>
 
int fplay_blit_bitmap(bitmap_t *bitmap, int dst_x, int dst_y,int w, int h);
 
extern int res_pause_btn[];
extern int res_pause_btn_pressed[];
 
extern int res_play_btn[];
extern int res_play_btn_pressed[];
 
extern int64_t stream_duration;
extern volatile int sound_level_0;
extern volatile int sound_level_1;
 
typedef struct
{
AVPicture picture;
double pts;
volatile int ready;
}vframe_t;
 
vframe_t frames[4];
volatile int frames_count = 0;
 
struct SwsContext *cvt_ctx = NULL;
 
int vfx = 0;
int dfx = 0;
 
render_t *main_render;
 
int width;
int height;
 
AVRational video_time_base;
AVFrame *Frame;
 
volatile uint32_t driver_lock;
 
void get_client_rect(rect_t *rc);
 
void flush_video()
{
int i;
 
for(i = 0; i < 4; i++)
{
frames[i].pts = 0;
frames[i].ready = 0;
};
frames_count = 0;
vfx = 0;
dfx = 0;
};
 
int init_video(AVCodecContext *ctx)
{
int i;
 
width = ctx->width;
height = ctx->height;
 
 
Frame = avcodec_alloc_frame();
if ( Frame == NULL )
{
printf("Cannot alloc video frame\n\r");
return 0;
};
 
for( i=0; i < 4; i++)
{
int ret;
 
// printf("alloc picture %d %d %x\n",
// ctx->width, ctx->height, ctx->pix_fmt );
 
ret = avpicture_alloc(&frames[i].picture, ctx->pix_fmt,
ctx->width, ctx->height);
if ( ret != 0 )
{
printf("Cannot alloc video buffer\n\r");
return 0;
};
 
frames[i].pts = 0;
frames[i].ready = 0;
};
 
create_thread(video_thread, ctx, 1024*1024);
 
delay(50);
return 1;
};
 
int decode_video(AVCodecContext *ctx, queue_t *qv)
{
AVPacket pkt;
double pts;
int frameFinished;
double current_clock;
 
if(frames[dfx].ready != 0 )
return -1;
 
if( get_packet(qv, &pkt) == 0 )
return 0;
 
/*
current_clock = -90.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( 1 /*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");
 
// if (pts == AV_NOPTS_VALUE)
// pts = 0;
 
pts *= av_q2d(video_time_base);
 
dst_pic = &frames[dfx].picture;
 
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;
// printf("pts %f\n", frames[dfx].pts);
 
frames[dfx].ready = 1;
 
dfx++;
dfx&= 3;
frames_count++;
};
};
av_free_packet(&pkt);
 
return 1;
}
 
extern volatile enum player_state player_state;
extern volatile enum player_state decoder_state;
extern volatile enum player_state sound_state;
 
//rect_t win_rect;
 
extern int64_t rewind_pos;
 
static void player_stop()
{
window_t *win;
 
win = main_render->win;
 
rewind_pos = 0;
 
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;
win->panel.prg->current = rewind_pos;
 
send_message(&win->panel.ctrl, MSG_PAINT, 0, 0);
player_state = STOP;
decoder_state = PLAY_2_STOP;
sound_state = PLAY_2_STOP;
render_draw_client(main_render);
// printf("stop player\n");
 
};
 
int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
window_t *win = (window_t*)ctrl;
static int spc_down = 0;
static int ent_down = 0;
 
switch(msg)
{
case MSG_SIZE:
//printf("MSG_SIZE\n");
if(main_render)
{
render_adjust_size(main_render, win);
render_draw_client(main_render);
};
break;
 
case MSG_KEY:
switch((short)arg2)
{
case 0x39:
if(spc_down == 0)
{
spc_down = 1;
send_message(win, MSG_LBTNDOWN, 0, 0);
}
break;
 
case 0xB9:
spc_down = 0;
break;
 
case 0x1C:
if(ent_down == 0)
{
int screensize;
if(win->win_state == NORMAL)
{
win->saved = win->rc;
win->saved_state = win->win_state;
 
screensize = GetScreenSize();
__asm__ __volatile__(
"int $0x40"
::"a"(67), "b"(0), "c"(0),
"d"((screensize >> 16)-1),"S"((screensize & 0xFFFF)-1) );
win->win_state = FULLSCREEN;
window_update_layout(win);
}
else if(win->win_state == FULLSCREEN)
{
__asm__ __volatile__(
"int $0x40"
::"a"(67), "b"(win->saved.l), "c"(win->saved.t),
"d"(win->saved.r-win->saved.l-1),"S"(win->saved.b-win->saved.t-1));
win->win_state = win->saved_state;
window_update_layout(win);
// if(win->saved_state == MAXIMIZED)
{
blit_caption(&win->caption);
blit_panel(&win->panel);
}
}
ent_down = 1;
};
break;
 
case 0x9C:
ent_down = 0;
break;
};
 
case MSG_DRAW_CLIENT:
if(main_render)
{
render_draw_client(main_render);
};
break;
 
case MSG_LBTNDOWN:
 
if(player_state == PAUSE)
{
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->ctrl, MSG_PAINT, 0, 0);
player_state = PLAY;
sound_state = PAUSE_2_PLAY;
 
}
else if(player_state == PLAY)
{
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->ctrl, MSG_PAINT, 0, 0);
player_state = PAUSE;
sound_state = PLAY_2_PAUSE;
}
break;
 
case MSG_COMMAND:
switch((short)arg1)
{
case ID_PLAY:
if(player_state == PAUSE)
{
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 = PLAY;
sound_state = PAUSE_2_PLAY;
}
else if(player_state == PLAY)
{
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 = PAUSE;
sound_state = PLAY_2_PAUSE;
}
else if(player_state == STOP)
{
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;
rewind_pos = 0;
send_message(&win->panel.ctrl, MSG_PAINT, 0, 0);
player_state = PLAY;
decoder_state = PREPARE;
}
break;
 
case ID_STOP:
player_stop();
break;
 
case ID_PROGRESS:
if(player_state != REWIND)
{
progress_t *prg = (progress_t*)arg2;
 
rewind_pos = (prg->max - prg->min)*prg->pos/prg->ctrl.w;
 
// printf("progress action pos: %d time: %f\n", prg->pos, (double)rewind_pos);
player_state = REWIND;
decoder_state = REWIND;
sound_state = PLAY_2_STOP;
if(rewind_pos < prg->current)
{
prg->current = rewind_pos;
rewind_pos = -rewind_pos;
}
else
prg->current = rewind_pos;
 
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(&prg->ctrl, MSG_PAINT, 0, 0);
};
break;
 
case ID_VOL_CTRL:
{
slider_t *sld = (slider_t*)arg2;
int peak;
int level;
 
peak = sld->min + sld->pos * (sld->max - sld->min)/(96);
// level = (log2(peak+16384)*10000.0)/15 - 10000;
level = peak;
 
// printf("level %d\n", level);
set_audio_volume(level, level);
send_message(&sld->ctrl, MSG_PAINT, 0, 0);
win->panel.lvl->vol = level;
}
 
default:
break;
}
break;
 
default:
def_window_proc(ctrl,msg,arg1,arg2);
};
return 0;
};
 
#define VERSION_A 1
 
extern queue_t q_video;
extern queue_t q_audio;
 
void render_time(render_t *render)
{
progress_t *prg = main_render->win->panel.prg;
level_t *lvl = main_render->win->panel.lvl;
 
double ctime; /* milliseconds */
double fdelay; /* milliseconds */
 
//again:
 
if(player_state == CLOSED)
{
render->win->win_command = WIN_CLOSED;
return;
}
else if((player_state == PAUSE) || (player_state == REWIND))
{
delay(1);
return;
}
else if (decoder_state == STOP && frames_count == 0 &&
player_state != STOP)
{
player_stop();
}
else if(player_state != PLAY)
{
delay(1);
return;
};
 
 
#ifdef VERSION_A
if(frames[vfx].ready == 1 )
{
int sys_time;
 
ctime = get_master_clock();
fdelay = (frames[vfx].pts - ctime);
 
// printf("pts %f time %f delay %f\n",
// frames[vfx].pts, ctime, fdelay);
 
if(fdelay > 15.0)
{
delay((int)fdelay/10);
// return;
};
#if 0
ctime = get_master_clock();
fdelay = (frames[vfx].pts - ctime);
 
// while(fdelay > 0)
// {
// yield();
// ctime = get_master_clock();
// fdelay = (frames[vfx].pts - ctime);
// }
 
// sys_time = get_tick_count();
 
// if(fdelay < 0)
// printf("systime %d pts %f time %f delay %f\n",
// sys_time*10, frames[vfx].pts, ctime, fdelay);
 
printf("pts %f time %f delay %f\n",
frames[vfx].pts, ctime, fdelay);
printf("video cache %d audio cache %d\n", q_video.size/1024, q_audio.size/1024);
#endif
 
main_render->draw(main_render, &frames[vfx].picture);
if(main_render->win->win_state != FULLSCREEN)
{
prg->current = frames[vfx].pts*1000;
// printf("current %f\n", prg->current);
lvl->current = vfx & 1 ? sound_level_1 : sound_level_0;
 
send_message(&prg->ctrl, PRG_PROGRESS, 0, 0);
 
if(main_render->win->panel.layout)
send_message(&lvl->ctrl, MSG_PAINT, 0, 0);
}
 
frames_count--;
frames[vfx].ready = 0;
vfx++;
vfx&= 3;
}
else delay(1);
 
#else
 
if(frames[vfx].ready == 1 )
{
ctime = get_master_clock();
fdelay = (frames[vfx].pts - ctime);
 
// printf("pts %f time %f delay %f\n",
// frames[vfx].pts, ctime, fdelay);
 
if(fdelay < 0.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)
{
int val = fdelay;
printf("pts %f time %f delay %d\n",
frames[vfx].pts, ctime, val);
delay(val/10);
};
 
ctime = get_master_clock();
fdelay = (frames[vfx].pts - ctime);
 
printf("pts %f time %f delay %f\n",
frames[vfx].pts, ctime, fdelay);
 
main_render->draw(main_render, &frames[vfx].picture);
main_render->win->panel.prg->current = frames[vfx].pts;
// send_message(&render->win->panel.prg->ctrl, MSG_PAINT, 0, 0);
frames[vfx].ready = 0;
vfx++;
vfx&= 3;
}
else yield();
#endif
 
}
 
 
extern char *movie_file;
 
int video_thread(void *param)
{
AVCodecContext *ctx = param;
window_t *MainWindow;
 
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);
 
// __asm__ __volatile__("int3");
 
main_render = create_render(MainWindow, ctx, HW_TEX_BLIT|HW_BIT_BLIT);
if( main_render == NULL)
{
printf("Cannot create render\n\r");
return 0;
};
 
render_draw_client(main_render);
player_state = PLAY;
 
run_render(MainWindow, main_render);
 
destroy_render(main_render);
fini_winlib();
 
player_state = CLOSED;
return 0;
};
 
 
void draw_hw_picture(render_t *render, AVPicture *picture);
void draw_sw_picture(render_t *render, AVPicture *picture);
 
render_t *create_render(window_t *win, AVCodecContext *ctx, uint32_t flags)
{
render_t *render;
 
uint32_t right, bottom, draw_w, draw_h;
uint32_t s, sw, sh;
uint8_t state;
 
// __asm__ __volatile__("int3");
 
render = (render_t*)malloc(sizeof(render_t));
memset(render, 0, sizeof(render_t));
 
render->win = win;
 
render->ctx_width = ctx->width;
render->ctx_height = ctx->height;
render->ctx_format = ctx->pix_fmt;
 
mutex_lock(&driver_lock);
render->caps = init_pixlib(flags);
mutex_unlock(&driver_lock);
 
right = win->w;
bottom = win->h-CAPTION_HEIGHT-PANEL_HEIGHT;
 
// printf("window width %d height %d\n",
// right, bottom);
 
render->win_state = win->win_state;
 
draw_w = bottom*render->ctx_width/render->ctx_height;
draw_h = right*render->ctx_height/render->ctx_width;
 
if(draw_w > right)
{
draw_w = right;
draw_h = right*render->ctx_height/render->ctx_width;
};
 
if(draw_h > bottom)
{
draw_h = bottom;
draw_w = bottom*render->ctx_width/render->ctx_height;
};
 
render->win_width = win->w;
render->win_height = win->h-CAPTION_HEIGHT-PANEL_HEIGHT;
 
render_set_size(render, draw_w, draw_h);
 
 
if(render->caps==0)
{
render->bitmap[0].width = draw_w;
render->bitmap[0].height = draw_h;
 
if( create_bitmap(&render->bitmap[0]) != 0 )
{
free(render);
return NULL;
}
render->draw = draw_sw_picture;
}
else
{
int width, height, flags;
int i;
 
if(render->caps & HW_TEX_BLIT)
{
sna_create_mask();
 
width = render->ctx_width;
height = render->ctx_height;
flags = HW_TEX_BLIT;
}
else
{
width = draw_w;
height = draw_h;;
flags = HW_BIT_BLIT;
}
 
for( i=0; i < 2; i++)
{
render->bitmap[i].width = width;
render->bitmap[i].height = height;
render->bitmap[i].flags = flags;
 
if( create_bitmap(&render->bitmap[i]) != 0 )
{
player_state = CLOSED;
free(render);
return NULL;
};
}
 
render->state = INIT;
render->target = 0;
render->draw = draw_hw_picture;
};
 
 
printf("FPlay %s render engine: context %dx%d picture %dx%d\n",
render->caps & HW_TEX_BLIT ? "hw_tex_blit":
render->caps & HW_BIT_BLIT ? "hw_bit_blit":"software",
render->ctx_width, render->ctx_height,
draw_w, draw_h);
 
// if(init_hw_context(ctx) == 0)
// printf("create hardware decoder context\n");
 
return render;
};
 
void destroy_render(render_t *render)
{
 
destroy_bitmap(&render->bitmap[0]);
 
if(render->caps & (HW_BIT_BLIT|HW_TEX_BLIT)) /* hw blitter */
destroy_bitmap(&render->bitmap[1]);
 
done_pixlib();
};
 
void render_set_size(render_t *render, int width, int height)
{
int i;
 
render->layout = 0;
render->rcvideo.l = 0;
render->rcvideo.t = 0;
render->rcvideo.r = width;
render->rcvideo.b = height;
 
// printf("render width %d height %d\n",width, height);
 
if( render->win_height > height )
{
int yoffs;
yoffs = (render->win_height-height)/2;
if(yoffs)
{
render->rctop.t = 0;
render->rctop.b = yoffs;
render->rcvideo.t = yoffs;
render->layout |= HAS_TOP;
}
 
yoffs = render->win_height-(render->rcvideo.t+render->rcvideo.b);
if(yoffs)
{
render->rcbottom.t = render->rcvideo.t+render->rcvideo.b;
render->rcbottom.b = yoffs;
render->layout |= HAS_BOTTOM;
}
}
 
if( render->win_width > width )
{
int xoffs;
xoffs = (render->win_width-width)/2;
if(xoffs)
{
render->rcleft.r = xoffs;
render->rcvideo.l = xoffs;
render->layout |= HAS_LEFT;
}
xoffs = render->win_width-(render->rcvideo.l+render->rcvideo.r);
if(xoffs)
{
render->rcright.l = render->rcvideo.l+render->rcvideo.r;
render->rcright.r = xoffs;
render->layout |= HAS_RIGHT;
}
};
};
 
void render_adjust_size(render_t *render, window_t *win)
{
uint32_t right, bottom, new_w, new_h;
uint32_t s, sw, sh;
uint8_t state;
 
right = win->w;
bottom = win->h;
 
if(win->win_state != FULLSCREEN)
bottom-= CAPTION_HEIGHT+PANEL_HEIGHT;
 
// printf("window width %d height %d\n",
// right, bottom);
 
render->win_state = win->win_state;
 
if(render->win_state == MINIMIZED)
return;
 
if(render->win_state == ROLLED)
return;
 
if( right == render->win_width &&
bottom == render->win_height)
return;
 
// printf("%s r: %d b: %d\n", __FUNCTION__, right, bottom);
 
new_w = bottom*render->ctx_width/render->ctx_height;
new_h = right*render->ctx_height/render->ctx_width;
 
if(new_w > right)
{
new_w = right;
new_h = right*render->ctx_height/render->ctx_width;
};
if(new_h > bottom)
{
new_h = bottom;
new_w = bottom*render->ctx_width/render->ctx_height;
};
 
render->win_width = right;
render->win_height = bottom;
render_set_size(render, new_w, new_h);
 
if(render->caps & HW_TEX_BLIT) /* hw scaler */
return;
 
render->bitmap[0].width = new_w;
render->bitmap[0].height = new_h;
resize_bitmap(&render->bitmap[0]);
 
if(render->caps & HW_BIT_BLIT) /* hw blitter */
{
render->bitmap[1].width = new_w;
render->bitmap[1].height = new_h;
resize_bitmap(&render->bitmap[1]);
};
return;
};
 
void draw_hw_picture(render_t *render, AVPicture *picture)
{
int dst_width, dst_height;
bitmap_t *bitmap;
uint8_t *data[4];
int linesize[4];
int ret;
 
if(render->win->win_state == MINIMIZED ||
render->win->win_state == ROLLED)
return;
 
if(render->caps & HW_TEX_BLIT)
{
dst_width = render->ctx_width;
dst_height = render->ctx_height;
}
else
{
dst_width = render->rcvideo.r;
dst_height = render->rcvideo.b;
};
 
cvt_ctx = sws_getCachedContext(cvt_ctx,
render->ctx_width, render->ctx_height, render->ctx_format,
dst_width, dst_height, PIX_FMT_BGRA,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
if(cvt_ctx == NULL)
{
printf("Cannot initialize the conversion context!\n");
return ;
};
 
bitmap = &render->bitmap[render->target];
 
ret = lock_bitmap(bitmap);
if( ret != 0)
{
printf("Cannot lock bitmap!\n");
return ;
}
 
// printf("sws_getCachedContext\n");
data[0] = bitmap->data;
data[1] = bitmap->data+1;
data[2] = bitmap->data+2;
data[3] = bitmap->data+3;
 
linesize[0] = bitmap->pitch;
linesize[1] = bitmap->pitch;
linesize[2] = bitmap->pitch;
linesize[3] = bitmap->pitch;
 
sws_scale(cvt_ctx, (const uint8_t* const *)picture->data,
picture->linesize, 0, render->ctx_height, data, linesize);
// printf("sws_scale\n");
 
 
if(render->caps & HW_TEX_BLIT)
{
 
if(render->win->win_state == FULLSCREEN)
fplay_blit_bitmap(bitmap,render->rcvideo.l,render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b);
else
fplay_blit_bitmap(bitmap, render->rcvideo.l,
CAPTION_HEIGHT+render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b);
}
else
{
if(render->win->win_state == FULLSCREEN)
blit_bitmap(bitmap,render->rcvideo.l,render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b, 0,0);
else
blit_bitmap(bitmap, render->rcvideo.l,
CAPTION_HEIGHT+render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b, 0, 0);
};
 
render->last_bitmap = bitmap;
render->target++;
render->target&= 1;
}
 
void draw_sw_picture(render_t *render, AVPicture *picture)
{
uint8_t *data[4];
int linesize[4];
 
if(render->win->win_state == MINIMIZED ||
render->win->win_state == ROLLED)
return;
 
cvt_ctx = sws_getCachedContext(cvt_ctx,
render->ctx_width, render->ctx_height,
render->ctx_format,
render->rcvideo.r, render->rcvideo.b,
PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL);
if(cvt_ctx == NULL)
{
printf("Cannot initialize the conversion context!\n");
return ;
}
 
lock_bitmap(&render->bitmap[0]);
 
data[0] = render->bitmap[0].data;
data[1] = render->bitmap[0].data+1;
data[2] = render->bitmap[0].data+2;
data[3] = render->bitmap[0].data+3;
 
linesize[0] = render->bitmap[0].pitch;
linesize[1] = render->bitmap[0].pitch;
linesize[2] = render->bitmap[0].pitch;
linesize[3] = render->bitmap[0].pitch;
 
sws_scale(cvt_ctx, (const uint8_t* const *)picture->data,
picture->linesize, 0, render->ctx_height, data, linesize);
 
if(render->win->win_state == FULLSCREEN)
fplay_blit_bitmap(&render->bitmap[0],render->rcvideo.l,render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b);
else
fplay_blit_bitmap(&render->bitmap[0], render->rcvideo.l,
CAPTION_HEIGHT+render->rcvideo.t,
render->rcvideo.r, render->rcvideo.b);
 
render->last_bitmap = &render->bitmap[0];
}
 
void render_draw_client(render_t *render)
{
int y;
 
if(render->win_state == MINIMIZED ||
render->win_state == ROLLED )
return;
if(render->win_state == FULLSCREEN)
y = 0;
else
y = CAPTION_HEIGHT;
 
if(player_state == PAUSE)
{
if(frames[vfx].ready == 1 )
main_render->draw(main_render, &frames[vfx].picture);
else
draw_bar(0, y, render->win_width,
render->rcvideo.b, 0);
}
else if( player_state == STOP )
{
draw_bar(0,y, render->win_width,
render->rcvideo.b, 0);
};
 
if(render->layout & HAS_TOP)
draw_bar(0, y, render->win_width,
render->rctop.b, 0);
if(render->layout & HAS_LEFT)
draw_bar(0, render->rcvideo.t+y, render->rcleft.r,
render->rcvideo.b, 0);
if(render->layout & HAS_RIGHT)
draw_bar(render->rcright.l, render->rcvideo.t+y,
render->rcright.r, render->rcvideo.b, 0);
if(render->layout & HAS_BOTTOM)
draw_bar(0, render->rcbottom.t+y,
render->win_width, render->rcbottom.b, 0);
}
 
 
 
 
 
/contrib/media/fplay/winlib/button.c
0,0 → 1,574
 
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include "winlib.h"
 
extern int res_level[];
extern int res_slider[];
extern int res_vol_slider[];
extern int res_progress_bar[];
extern int res_prg_level[];
 
extern ctrl_t *mouse_capture;
uint32_t main_cursor;
 
static int button_proc(ctrl_t *btn, uint32_t msg, uint32_t arg1, uint32_t arg2);
static int spinbtn_proc(ctrl_t *btn, uint32_t msg, uint32_t arg1, uint32_t arg2);
 
ctrl_t *create_control(size_t size, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
 
ctrl_t *ctrl;
 
if( !parent )
return NULL;
 
ctrl = (ctrl_t*)malloc(size);
 
link_initialize(&ctrl->link);
list_initialize(&ctrl->child);
 
ctrl->parent = parent;
 
ctrl->ctx = parent->ctx;
ctrl->id = id;
 
ctrl->rc.l = x;
ctrl->rc.t = y ;
 
ctrl->rc.r = x + w;
ctrl->rc.b = y + h;
 
ctrl->w = w;
ctrl->h = h;
 
list_append(&ctrl->link, &parent->child);
 
return ctrl;
};
 
 
button_t *create_button(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
button_t *btn;
int len;
 
if( !parent )
return NULL;
 
btn = (button_t*)create_control(sizeof(button_t), id, x, y, w, h, parent);
btn->ctrl.handler = button_proc;
btn->state = 0;
btn->caption = caption;
 
if( !caption )
btn->capt_len = 0;
else
{
len = strlen(caption);
btn->capt_len = len;
if( len )
btn->caption = strdup(caption);
else
btn->caption = NULL;
}
 
btn->img_default = NULL;
btn->img_hilite = NULL;
btn->img_pressed = NULL;
 
return btn;
};
 
#if 0
int draw_button(button_t *btn)
{
void *bitmap;
 
bitmap = btn->img_default;
 
if(btn->state & bPressed)
bitmap = btn->img_pressed;
else if(btn->state & bHighlight)
bitmap = btn->img_hilite;
 
if( bitmap )
draw_bitmap(bitmap, btn->rc.l, btn->rc.t, btn->w, btn->h);
 
if( btn->caption && btn->capt_len)
{
int txt_w;
int txt_x, txt_y;
txt_w = btn->capt_len*8-2;
 
txt_x = btn->rc.l + 1 + (btn->w - txt_w)/2;
txt_y = btn->rc.t + 9;
 
if(btn->state & bPressed){
txt_x++;
txt_y++;
};
draw_text(btn->caption, txt_x, txt_y, btn->capt_len, 0x10000000);
};
return 0;
};
#endif
 
int draw_button_cairo(button_t *btn)
{
int *src;
ctx_t *ctx;
int x, y;
 
ctx = btn->ctrl.ctx;
 
lock_bitmap(ctx->pixmap);
x = btn->ctrl.rc.l - ctx->offset_x;
y = btn->ctrl.rc.t - ctx->offset_y;
 
src = btn->img_default;
 
if(btn->state & bPressed)
src = btn->img_pressed;
else if(btn->state & bHighlight)
src = btn->img_hilite;
 
blit_raw(ctx, src, x, y, btn->ctrl.w, btn->ctrl.h, btn->ctrl.w*4);
 
return 0;
};
 
 
int draw_spin_cairo(button_t *btn)
{
void *ctx;
 
return 0;
};
 
 
int button_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
int x, y;
int state;
int old_state;
int action=0;
 
button_t *btn = (button_t*)ctrl;
 
switch( msg )
{
case MSG_PAINT:
draw_button_cairo(btn);
update_rect((ctrl_t*)btn);
break;
 
case MSG_MOUSEENTER:
// printf("mouse enter\n");
btn->state|= bHighlight;
send_message(&btn->ctrl, MSG_PAINT, 0, 0);
break;
 
case MSG_MOUSELEAVE:
// printf("mouse leave\n");
if( (ctrl_t*)btn != mouse_capture) {
btn->state &= ~bHighlight;
send_message(&btn->ctrl, MSG_PAINT, 0, 0);
};
break;
 
case MSG_LBTNDOWN:
case MSG_LBTNDBLCLK:
// printf("push button\n");
capture_mouse((ctrl_t*)btn);
btn->state|= bPressed;
send_message(&btn->ctrl, MSG_PAINT, 0, 0);
break;
 
case MSG_LBTNUP:
 
// printf("button action\n");
if(btn->state & bPressed)
action = MSG_COMMAND;
 
release_mouse();
 
x = ((pos_t)arg2).x;
y = ((pos_t)arg2).y;
 
if( pt_in_rect( &btn->ctrl.rc, x, y) )
state = bHighlight;
else
state = 0;
 
if(action)
send_message(btn->ctrl.parent,MSG_COMMAND,btn->ctrl.id,(int)btn);
 
btn->state = state;
send_message(&btn->ctrl, MSG_PAINT, 0, 0);
break;
 
case MSG_MOUSEMOVE:
 
if(main_cursor != 0)
{
set_cursor(0);
main_cursor = 0;
}
 
if( ! (btn->state & bHighlight))
{
btn->state|= bHighlight;
send_message(&btn->ctrl, MSG_PAINT, 0, 0);
};
 
if( (ctrl_t*)btn != mouse_capture)
return 0;
 
x = ((pos_t)arg2).x;
y = ((pos_t)arg2).y;
 
old_state = btn->state;
 
if( pt_in_rect(&btn->ctrl.rc, x, y) )
btn->state |= bPressed;
else
btn->state &= ~bPressed;
 
if( old_state ^ btn->state)
send_message(&btn->ctrl, MSG_PAINT, 0, 0);
}
return 0;
};
 
 
int draw_progress(progress_t *prg, int background)
{
int *pixmap, *src;
ctx_t *ctx;
int i, j;
int x, y;
rect_t rc = prg->ctrl.rc;
 
int len = prg->ctrl.w;
 
ctx = prg->ctrl.ctx;
lock_bitmap(ctx->pixmap);
 
x = prg->ctrl.rc.l - ctx->offset_x;
y = prg->ctrl.rc.t - ctx->offset_y;
 
if( background )
{
src = res_progress_bar;
 
pixmap = (int*)ctx->pixmap->data;
pixmap+= y * ctx->pixmap->pitch/4 + x;
 
for(i=0; i < 10; i++)
{
for(j = 0; j < len; j++)
pixmap[j] = *src;
 
pixmap+= ctx->pixmap->pitch/4;
src++;
};
};
 
 
len = prg->current*prg->ctrl.w/(prg->max - prg->min);
 
src = res_prg_level;
 
pixmap = (int*)ctx->pixmap->data;
pixmap+= y*ctx->pixmap->pitch/4 + x;
 
for(i=0; i < prg->ctrl.h ;i++)
{
for(j=0; j < len; j++)
pixmap[j] = *src;
pixmap+= ctx->pixmap->pitch/4;
src++;
};
 
return 0;
};
 
 
int prg_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
progress_t *prg = (progress_t*)ctrl;
int pos;
 
switch( msg )
{
case MSG_PAINT:
draw_progress(prg, 1);
update_rect(ctrl);
break;
 
case MSG_LBTNDOWN:
prg->pos = ((pos_t)arg2).x - ctrl->rc.l;
send_message(ctrl->parent,MSG_COMMAND,ctrl->id,(int)ctrl);
break;
 
case PRG_PROGRESS:
draw_progress(prg, 0);
update_rect(ctrl);
break;
 
default:
break;
}
return 0;
};
 
 
progress_t *create_progress(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
progress_t *prg;
int len;
 
if( !parent )
return NULL;
 
prg = (progress_t*)create_control(sizeof(progress_t), id, x, y, w, h, parent);
 
prg->ctrl.handler = prg_proc;
 
prg->min = 0;
prg->max = 1;
prg->current = 0;
prg->pos = 0;
 
return prg;
};
 
int draw_level(level_t *lvl)
{
int *pixmap;
ctx_t *ctx;
int i, j;
int x, y;
 
int len;
double level;
 
ctx = lvl->ctrl.ctx;
 
lock_bitmap(ctx->pixmap);
x = lvl->ctrl.rc.l - ctx->offset_x;
y = lvl->ctrl.rc.t - ctx->offset_y;
 
level = (log2(lvl->current+1)-7)*12 + lvl->vol/50 ;
 
len = level;
 
if(len < 0)
len = 0;
if(len > 96)
len = 96;
 
pixmap = (int*)ctx->pixmap->data;
 
pixmap+= y*ctx->pixmap->pitch/4 + x;
 
for(i=0; i < 10; i++)
{
for(j = 0; j < 96; j++)
pixmap[j] = 0xFF1C1C1C;
pixmap+= ctx->pixmap->pitch/4;
};
 
blit_raw(ctx, lvl->img_level, x, y, len, 10, 96*4);
 
return 0;
};
 
 
int lvl_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
level_t *lvl = (level_t*)ctrl;
// int pos;
 
switch( msg )
{
case MSG_PAINT:
if(lvl->visible)
{
draw_level(lvl);
update_rect(ctrl);
};
break;
 
// case MSG_LBTNDOWN:
// prg->pos = ((pos_t)arg2).x - ctrl->rc.l;
// send_message(ctrl->parent,MSG_COMMAND,ctrl->id,(int)ctrl);
// break;
 
default:
break;
}
return 0;
};
 
level_t *create_level(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
level_t *lvl;
 
if( !parent )
return NULL;
 
lvl = (level_t*)create_control(sizeof(level_t), id, x, y, w, h, parent);
lvl->ctrl.handler = lvl_proc;
 
lvl->min = 0;
lvl->max = 1;
lvl->current = 0;
lvl->pos = 0;
lvl->visible = 0;
lvl->img_level = res_level;
 
return lvl;
};
 
 
int draw_slider(slider_t *sld)
{
int *pixmap;
ctx_t *ctx;
int i, j;
int x, y;
 
int32_t len;
double level;
 
ctx = sld->ctrl.ctx;
 
lock_bitmap(ctx->pixmap);
x = sld->ctrl.rc.l - ctx->offset_x;
y = sld->ctrl.rc.t - ctx->offset_y;
 
len = 96 + 12;
 
pixmap = (int*)ctx->pixmap->data;
pixmap+= y*ctx->pixmap->pitch/4 + x;
 
for(i=0; i < 11; i++)
{
for(j = 0; j < len; j++)
pixmap[j] = 0xFF1C1C1C;
pixmap+= ctx->pixmap->pitch/4;
};
 
blit_raw(ctx, sld->img_vol_slider, x+6, y+4, 96, 4, 96*4);
 
blit_raw(ctx, res_slider, x+sld->pos, y, 12, 11, 12*4);
 
return 0;
};
 
 
int sld_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
slider_t *sld = (slider_t*)ctrl;
int pos;
 
switch( msg )
{
case MSG_PAINT:
draw_slider(sld);
update_rect(ctrl);
break;
 
case MSG_LBTNDOWN:
capture_mouse(ctrl);
sld->mode = 1;
 
pos = ((pos_t)arg2).x - ctrl->rc.l - 6;
if( pos < 0 )
pos = 0;
else if(pos > 96)
pos = 96;
if( sld->pos != pos)
{
sld->pos = pos;
send_message(ctrl->parent,MSG_COMMAND,ctrl->id,(int)ctrl);
};
break;
 
case MSG_LBTNUP:
if(sld->mode)
{
release_mouse();
sld->mode = 0;
};
break;
 
case MSG_MOUSEMOVE:
if(sld->mode)
{
pos = ((pos_t)arg2).x - ctrl->rc.l - 6;
if( pos < 0 )
pos = 0;
else if(pos > 96)
pos = 96;
if( sld->pos != pos)
{
sld->pos = pos;
// printf("slider pos %d\n", sld->pos);
send_message(ctrl->parent,MSG_COMMAND,ctrl->id,(int)ctrl);
}
};
break;
 
case MSG_MOUSEENTER:
panel_set_layout(ctrl->parent, 1);
// printf("level on\n");
break;
 
case MSG_MOUSELEAVE:
panel_set_layout(ctrl->parent, 0);
// printf("level off\n");
break;
 
 
default:
break;
}
return 0;
};
 
 
slider_t *create_slider(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
 
slider_t *sld;
 
if( !parent )
return NULL;
 
sld = (slider_t*)create_control(sizeof(slider_t), id, x, y, w, h, parent);
sld->ctrl.handler = sld_proc;
 
sld->min = -5000;
sld->max = 0;
sld->current = 0;
sld->pos = 60;
sld->mode = 0;
sld->img_vol_slider = res_vol_slider;
 
return sld;
};
 
/contrib/media/fplay/winlib/caption.c
0,0 → 1,272
 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "winlib.h"
 
#define CAPTION_CORNER_W 8
 
extern int res_caption_left[];
extern int res_caption_right[];
extern int res_caption_body[];
 
extern int res_close_btn[];
extern int res_close_btn_hl[];
extern int res_close_btn_pressed[];
 
extern int res_minimize_btn[];
extern int res_minimize_btn_hl[];
extern int res_minimize_btn_pressed[];
 
extern int res_full_btn[];
extern int res_full_btn_hl[];
extern int res_full_btn_pressed[];
 
extern uint32_t main_cursor;
 
void update_caption_size(window_t *win);
 
int caption_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2);
 
 
int init_caption(window_t *win)
{
button_t *btn;
 
caption_t *cpt = &win->caption;
ctx_t *ctx = &cpt->ctx;
 
link_initialize(&cpt->ctrl.link);
list_initialize(&cpt->ctrl.child);
 
cpt->ctrl.handler = caption_proc;
cpt->ctrl.parent = (ctrl_t*)win;
 
cpt->text = win->caption_txt;
 
cpt->bitmap.width = 1920;
cpt->bitmap.height = CAPTION_HEIGHT;
cpt->bitmap.flags = 0;
 
if( create_bitmap(&cpt->bitmap) )
{
printf("not enough memory for caption bitmap\n");
return 0;
}
 
 
// printf("win_w %d win_h %d\n", win->w, win->h);
ctx->pixmap = &cpt->bitmap;
ctx->offset_x = 0;
ctx->offset_y = 0;
 
cpt->ctrl.ctx = ctx;
 
btn = create_button(NULL, ID_CLOSE,0,5,18,18,(ctrl_t*)cpt);
cpt->close_btn = btn;
 
btn->img_default = res_close_btn;
btn->img_hilite = res_close_btn_hl;
btn->img_pressed = res_close_btn_pressed;
 
btn = create_button(NULL, ID_MINIMIZE,0,5,18,18,(ctrl_t*)cpt);
cpt->minimize_btn = btn;
 
btn->img_default = res_minimize_btn;
btn->img_hilite = res_minimize_btn_hl;
btn->img_pressed = res_minimize_btn_pressed;
 
btn = create_button(NULL, ID_FULLSCREEN,0,5,18,18,(ctrl_t*)cpt);
cpt->full_btn = btn;
 
btn->img_default = res_full_btn;
btn->img_hilite = res_full_btn_hl;
btn->img_pressed = res_full_btn_pressed;
 
update_caption_size(win);
 
return 1;
};
 
 
void update_caption_size(window_t *win)
{
caption_t *cpt = &win->caption;
bitmap_t *bitmap = &cpt->bitmap;
 
bitmap->width = win->w;
resize_bitmap(bitmap);
 
cpt->ctrl.rc.l = 0;
cpt->ctrl.rc.t = 0;
cpt->ctrl.rc.r = win->w;
cpt->ctrl.rc.b = CAPTION_HEIGHT;
cpt->ctrl.w = win->w;
cpt->ctrl.h = CAPTION_HEIGHT;
win->client.t = CAPTION_HEIGHT;
 
cpt->close_btn->ctrl.rc.l = win->w - 27;
cpt->close_btn->ctrl.rc.r = cpt->close_btn->ctrl.rc.l +
cpt->close_btn->ctrl.w;
 
cpt->minimize_btn->ctrl.rc.l = win->w - 27 - 18 - 5;
cpt->minimize_btn->ctrl.rc.r = cpt->minimize_btn->ctrl.rc.l +
cpt->minimize_btn->ctrl.w;
 
cpt->full_btn->ctrl.rc.l = win->w - 27 - 18 -18 - 5 - 5;
cpt->full_btn->ctrl.rc.r = cpt->full_btn->ctrl.rc.l +
cpt->full_btn->ctrl.w;
 
};
 
 
extern int win_font;
 
void draw_caption(caption_t *cpt)
{
int *pixmap, *src;
rect_t rc;
int i, j, w;
 
lock_bitmap(&cpt->bitmap);
 
blit_raw(&cpt->ctx, res_caption_left, 0, 0,
CAPTION_CORNER_W, CAPTION_HEIGHT, CAPTION_CORNER_W*4);
 
w = cpt->ctrl.w - (2*CAPTION_CORNER_W);
if( w > 0)
{
pixmap = (int*)cpt->ctx.pixmap->data;
pixmap+= CAPTION_CORNER_W;
src = res_caption_body;
 
for(i = 0; i < CAPTION_HEIGHT; i++)
{
for(j = 0; j < w; j++)
pixmap[j] = src[i];
pixmap+= cpt->ctx.pixmap->pitch/4;
}
 
// blit_raw(&cpt->ctx,res_caption_body, CAPTION_CORNER_W, 0,
// w, CAPTION_HEIGHT, 0);
 
};
 
 
blit_raw(&cpt->ctx,res_caption_right, cpt->ctrl.w - CAPTION_CORNER_W, 0,
CAPTION_CORNER_W, CAPTION_HEIGHT,CAPTION_CORNER_W*4);
 
rc.l = 8;
rc.t = 0;
rc.r = cpt->ctrl.w - 27 - 18 - 18 - 5 - 5 - 8;
rc.b = 18;
 
draw_text_ext(cpt->ctx.pixmap, win_font, cpt->text, &rc, 0xFFFFFFFF);
 
ctrl_t *child;
child = (ctrl_t*)cpt->ctrl.child.next;
 
while( &child->link != &cpt->ctrl.child)
{
send_message(child, 1, 0, 0);
child = (ctrl_t*)child->link.next;
};
};
 
 
int caption_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
caption_t *cpt = (caption_t*)ctrl;
window_t *win = (window_t*)ctrl->parent;
 
ctrl_t *child;
int x, y;
 
x = ((pos_t)arg2).x;
y = ((pos_t)arg2).y;
 
switch( msg )
{
case 1:
break;
 
 
case MSG_MOUSEMOVE:
child = get_child(ctrl, x, y);
if( win->child_over )
{
if(child == win->child_over)
send_message(child, msg, 0, arg2);
else
send_message(win->child_over, MSG_MOUSELEAVE, 0, arg2);
};
 
win->child_over = child;
if( child )
{
send_message(child, MSG_MOUSEENTER, 0, arg2);
send_message(child,msg,0,arg2);
}
else if(main_cursor != 0)
{
set_cursor(0);
main_cursor = 0;
}
break;
 
 
case MSG_COMMAND:
switch((short)arg1)
{
case ID_CLOSE:
win->win_command = WIN_CLOSED;
break;
 
case ID_MINIMIZE:
__asm__ __volatile__(
"int $0x40"
::"a"(18),"b"(10));
win->win_state = MINIMIZED;
send_message((ctrl_t*)win, MSG_SIZE, 0, 0);
break;
case ID_FULLSCREEN:
{
int screensize;
 
win->saved = win->rc;
win->saved_state = win->win_state;
screensize = GetScreenSize();
__asm__ __volatile__(
"int $0x40"
::"a"(67), "b"(0), "c"(0),
"d"((screensize >> 16)-1),"S"((screensize & 0xFFFF)-1) );
win->win_state = FULLSCREEN;
window_update_layout(win);
};
break;
 
default:
break;
};
 
default:
child = get_child(ctrl, x, y);
if(child)
return send_message(child, msg, 0, arg2);
}
return 1;
};
 
 
 
void blit_caption(caption_t *cpt)
{
// printf("%s w:%d h:%d stride: %d\n",__FUNCTION__,
// cpt->ctrl.w, cpt->ctrl.h, cpt->ctx.stride);
 
lock_bitmap(&cpt->bitmap);
 
Blit(cpt->ctx.pixmap->data, 0, 0, 0, 0, cpt->ctrl.w, cpt->ctrl.h,
cpt->ctrl.w, cpt->ctrl.h, cpt->ctx.pixmap->pitch);
};
 
/contrib/media/fplay/winlib/control.h
0,0 → 1,212
#ifndef __CONTROL_H__
#define __CONTROL_H_
 
#include <pixlib2.h>
#include "link.h"
 
typedef struct
{
int l;
int t;
int r;
int b;
}rect_t;
 
typedef struct ctx
{
bitmap_t *pixmap;
int offset_x;
int offset_y;
}ctx_t;
 
ctx_t *get_window_ctx();
 
typedef struct tag_control ctrl_t;
 
typedef int (handler_t)(ctrl_t*, uint32_t, uint32_t, uint32_t);
 
struct tag_control
{
link_t link;
link_t child;
 
handler_t *handler;
ctrl_t *parent;
 
ctx_t *ctx;
uint32_t id;
uint32_t style;
 
rect_t rc;
int w;
int h;
};
 
 
typedef struct timer
{
link_t link;
ctrl_t *ctrl;
uint32_t exp_time; /* expiration time */
uint32_t tmr_arg; /* random argument */
} ostimer_t;
 
 
typedef struct
{
ctrl_t ctrl;
 
uint32_t state;
ostimer_t timer;
 
char *caption;
int capt_len;
 
void *img_default;
void *img_hilite;
void *img_pressed;
}button_t;
 
typedef struct
{
ctrl_t ctrl;
float min;
float max;
float current;
int pos;
}progress_t;
 
typedef struct
{
ctrl_t ctrl;
int min;
int max;
int current;
int pos;
int vol;
int visible;
void *img_level;
}level_t;
 
typedef struct
{
ctrl_t ctrl;
int min;
int max;
int current;
int pos;
int mode;
void *img_slider;
void *img_vol_slider;
}slider_t;
 
typedef struct
{
link_t link;
link_t child;
 
handler_t *handler;
ctrl_t *parent;
 
ctx_t *ctx;
uint32_t id;
uint32_t style;
 
rect_t rc;
int w;
int h;
 
uint32_t state;
 
int pix_range;
 
int min_range;
int max_range;
int page_size;
int thumb_pos;
 
rect_t tl_rect;
rect_t br_rect;
 
button_t *btn_up;
button_t *btn_down;
button_t *thumb;
}scroller_t;
 
#define bPressed 2
#define bHighlight 1
 
#define MSG_PAINT 0x001
#define MSG_KEY 0x002
#define MSG_BUTTON 0x003
#define MSG_DRAW_CLIENT 0x004
 
#define MSG_LBTNDOWN 0x010
#define MSG_LBTNUP 0x011
#define MSG_RBTNDOWN 0x012
#define MSG_RBTNUP 0x013
#define MSG_MBTNDOWN 0x014
#define MSG_MBTNUP 0x015
#define MSG_WHEELDOWN 0x016
#define MSG_WHEELUP 0x017
 
#define MSG_LBTNDBLCLK 0x018
 
#define MSG_MOUSEMOVE 0x019
#define MSG_MOUSEENTER 0x01A
#define MSG_MOUSELEAVE 0x01B
 
#define MSG_SIZE 0x020
 
#define MSG_COMMAND 0x030
#define MSG_TIMER 0x031
 
#define LBN_DBLCLK 0x100
#define LBOX_READDIR 0x100
#define LBOX_GETFILENAME 0x101
 
#define PRG_PROGRESS 0x102
 
#define ID_CLOSE 1
#define ID_MINIMIZE 2
#define ID_FULLSCREEN 3
 
#define ID_SCROLLER_UP 10
#define ID_SCROLLER_DOWN 11
#define ID_SCROLLER_THUMB 12
 
#define send_message( ctrl, msg, arg1, arg2) \
(ctrl)->handler( (ctrl_t*)(ctrl), \
(uint32_t)(msg), (uint32_t)(arg1), (uint32_t)(arg2))
 
static inline handler_t *subclass_control(ctrl_t *ctrl, handler_t *handler)
{
handler_t *old = ctrl->handler;
ctrl->handler = handler;
return old;
};
 
//int inline send_message(ctrl_t *ctrl, u32_t msg, u32_t arg1, u32_t arg2)
//{
// return ctrl->handler(ctrl, msg, arg1, arg2);
//};
 
static inline int pt_in_rect(rect_t *rc, int x, int y)
{
if( (x >= rc->l) && (x < rc->r) &&
(y >= rc->t) && (y < rc->b) )
return 1;
return 0;
};
 
ctrl_t *get_child(ctrl_t *ctrl, int x, int y);
 
ctrl_t *capture_mouse(ctrl_t *newm);
 
void blit_raw(ctx_t *ctx, void *raw, int x, int y, int w, int h, int pitch);
 
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
 
 
#endif
/contrib/media/fplay/winlib/fontlib.c
0,0 → 1,184
 
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
//#include "font_droid.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include <pixlib2.h>
 
extern char res_def_font[];
 
typedef struct
{
int l;
int t;
int r;
int b;
}rect_t;
 
typedef unsigned int color_t;
 
unsigned int ansi2utf32(unsigned char ch);
 
void my_draw_bitmap(bitmap_t *win, FT_Bitmap *bitmap, int dstx, int dsty, int col)
{
uint8_t *dst;
uint8_t *src, *tmpsrc;
 
uint32_t *tmpdst;
int i, j;
 
dst = win->data + dsty * win->pitch + dstx*4;
src = bitmap->buffer;
 
for( i = 0; i < bitmap->rows; i++ )
{
tmpdst = (uint32_t*)dst;
tmpsrc = src;
 
dst+= win->pitch;
src+= bitmap->pitch;
 
for( j = 0; j < bitmap->width; j++)
{
int a = *tmpsrc++;
int sr, sg, sb;
int dr, dg, db;
 
if( a != 0) a++;
 
db = *tmpdst & 0xFF;
dg = (*tmpdst >> 8) & 0xFF;
dr = (*tmpdst >> 16) &0xFF;
 
sb = col & 0xFF;
sg = (col >> 8) & 0xFF;
sr = (col >> 16) &0xFF;
 
db = (a*sb + db*(256-a))/256;
dg = (a*sg + dg*(256-a))/256;
dr = (a*sr + dr*(256-a))/256;
 
*tmpdst++ = 0xFF000000|(dr<<16)|(dg<<8)|db;
};
}
};
 
 
int draw_text_ext(bitmap_t *winbitmap, FT_Face face, char *text, rect_t *rc, int color)
{
FT_UInt glyph_index;
FT_Bool use_kerning = 0;
FT_UInt previous;
int x, y, w;
char ch;
int err = 0;
 
use_kerning = FT_HAS_KERNING( face );
previous = 0;
 
x = rc->l << 6;
y = rc->b;
 
w = (rc->r - rc->l) << 6;
 
while( ch = *text++ )
{
glyph_index = FT_Get_Char_Index( face, ansi2utf32(ch) );
 
if ( use_kerning && previous && glyph_index )
{
FT_Vector delta;
FT_Get_Kerning( face, previous, glyph_index, FT_KERNING_DEFAULT, &delta );
x += delta.x ;
}
 
if( x + face->glyph->advance.x > w)
break;
 
err = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
if ( err )
continue;
 
err = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
if ( err )
continue;
 
my_draw_bitmap(winbitmap, &face->glyph->bitmap, (x >> 6) + face->glyph->bitmap_left,
y - face->glyph->bitmap_top, color);
 
x += face->glyph->advance.x;
previous = glyph_index;
};
 
return err;
};
 
 
int init_fontlib()
{
int err;
 
static FT_Library library;
FT_Face face = NULL;
 
err = FT_Init_FreeType( &library );
if ( err )
{
printf("an error occurred during FreeType initialization\n");
goto done;
}
 
// err = FT_New_Face( library, "/hd0/1/IstokWeb.ttf", 0, &face );
 
err = FT_New_Memory_Face( library, res_def_font, 277996, 0, &face );
printf("err %d\n", err);
if ( err == FT_Err_Unknown_File_Format )
{
printf("font format is unsupported\n");
goto done;
 
}
else if ( err )
{
printf("font file could not be read or broken\n");
goto done;
 
}
 
err = FT_Set_Char_Size( face, 0, 11*64, 96, 96 );
// err = FT_Set_Pixel_Sizes( face, 0, 100 );
 
done:
 
return (int)face;
};
 
// draw_text(face,"/hd0/1/demo", 10, 80, 0x00000000);
 
 
unsigned int ansi2utf32(unsigned char ch)
{
if(ch < 0x80)
return ch;
 
if(ch < 0xB0)
return 0x410-0x80 + ch;
 
if(ch < 0xE0)
return 0;
 
if(ch < 0xF0)
return 0x440-0xE0 + ch;
 
if(ch == 0xF0)
return 0x401;
else if(ch==0xF1)
return 0x451;
else return 0;
}
 
 
/contrib/media/fplay/winlib/frame.c
0,0 → 1,289
 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "winlib.h"
 
#define CAPTION_CORNER_W 8
#define FRAME_WIDTH 7
 
extern uint32_t main_cursor;
 
extern uint32_t cursor_ns;
extern uint32_t cursor_we;
extern uint32_t cursor_nwse;
extern uint32_t cursor_nesw;
 
extern ctrl_t *mouse_capture;
 
static int frame_proc(ctrl_t *ctrl, uint32_t msg,
uint32_t arg1, uint32_t arg2);
 
void adjust_frame(window_t *win)
{
frame_t *fr = &win->frame;
 
fr->left.l = 0;
fr->left.t = win->client.t;
fr->left.r = FRAME_WIDTH;
fr->left.b = win->h-FRAME_WIDTH;
 
fr->right.l = win->w - FRAME_WIDTH;
fr->right.t = win->client.t;
fr->right.r = win->w;
fr->right.b = win->h-FRAME_WIDTH;
 
fr->bottom.l = 0;
fr->bottom.t = win->h - FRAME_WIDTH;
fr->bottom.r = win->w;
fr->bottom.b = win->h;
 
win->client.l = FRAME_WIDTH;
win->client.r = win->w - FRAME_WIDTH;
// win->client.b = win->h - FRAME_WIDTH;
// printf("Left: l:%d t:%d r:%d b:%d\n",
// fr->left.l,fr->left.t,fr->left.r,fr->left.b);
// printf("Left: l:%d t:%d r:%d b:%d\n",
// fr->right.l,fr->right.t,fr->right.r,fr->right.b);
// printf("Left: l:%d t:%d r:%d b:%d\n",
// fr->bottom.l,fr->bottom.t,fr->bottom.r,fr->bottom.b);
 
};
 
void init_frame(window_t *win)
{
frame_t *fr = &win->frame;
 
link_initialize(&fr->link);
list_initialize(&fr->child);
 
fr->handler = frame_proc;
fr->parent = (ctrl_t*)win;
 
adjust_frame(win);
};
 
 
extern int res_border_left[];
extern int res_border_right[];
 
int draw_frame(window_t *win)
{
int *pixmap, *src;
int i, j;
 
int w;
 
frame_t *fr = &win->frame;
 
pixmap = (int*)win->ctx->pixmap->data;
pixmap+= CAPTION_HEIGHT*win->w;
src = res_border_left;
 
for(fr->left.t; i < fr->left.b; i++)
{
for(j = 0; j < FRAME_WIDTH; j++)
pixmap[j] = src[j];
 
pixmap+= win->ctx->pixmap->pitch/4;
};
 
 
pixmap = (int*)win->ctx->pixmap->data;
pixmap+= (CAPTION_HEIGHT+1)*win->w - FRAME_WIDTH;
src = res_border_right;
 
for(i=fr->right.t; i < fr->right.b; i++)
{
for(j = 0; j < FRAME_WIDTH; j++)
pixmap[j] = src[j];
 
pixmap+= win->ctx->pixmap->pitch/4;
};
 
pixmap = (int*)win->ctx->pixmap->data;
 
pixmap+= fr->bottom.t * win->w;
 
for(i=0; i < FRAME_WIDTH; i++)
{
for(j = 0; j < win->w; j++)
pixmap[j] = 0x808080;
 
pixmap+= win->ctx->pixmap->pitch/4;
};
 
ctrl_t *child;
child = (ctrl_t*)fr->child.next;
 
while( &child->link != &fr->child)
{
send_message(child, 1, 0, 0);
child = (ctrl_t*)child->link.next;
};
 
return 0;
};
 
int frame_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
static pos_t spos;
static track_mode;
 
uint32_t cursor;
ctrl_t *child;
 
frame_t *fr = (frame_t*)ctrl;
window_t *win = (window_t*)fr->parent;
rect_t *rc = NULL;
int x, y;
 
if(win->win_state == FULLSCREEN)
return 0;
x = ((pos_t)arg2).x;
y = ((pos_t)arg2).y;
 
 
// child = get_child(ctrl, x, y);
// if(child)
// {
// return send_message(child, msg, 0, arg2);
// };
 
if( (msg == MSG_LBTNDOWN) ||
(msg == MSG_MOUSEMOVE) )
{
x = ((pos_t)arg2).x;
y = ((pos_t)arg2).y;
 
if( pt_in_rect(&fr->left, x, y))
{
rc = &fr->left;
if( (y+24) > win->h)
cursor = cursor_nesw;
else
cursor = cursor_we;
set_cursor(cursor);
main_cursor = cursor;
}
else if( pt_in_rect(&fr->right, x, y))
{
// printf("pos x%d y%d\n", x, y);
 
rc = &fr->right;
if( (y+24) > win->h)
cursor = cursor_nwse;
else
cursor = cursor_we;
// printf("Set cursor %x\n", cursor);
set_cursor(cursor);
main_cursor = cursor;
}
else if( pt_in_rect(&fr->bottom, x, y))
{
rc = &fr->bottom;
cursor = cursor_ns;
if(x+24 > win->w)
cursor = cursor_nwse;
else if(x < rc->l+24)
cursor = cursor_nesw;
set_cursor(cursor);
main_cursor = cursor;
}
};
 
switch( msg )
{
case MSG_LBTNDOWN:
if( rc != NULL)
{
int relx, rely;
 
capture_mouse(ctrl);
spos = get_cursor_pos();
fr->track = rc;
 
relx = spos.x - win->rc.l;
rely = spos.y - win->rc.t;
// printf("relx %d rely %d\n", relx, rely);
 
if(fr->track == &fr->left ||
fr->track == &fr->right)
{
if(rely+24 > win->h)
track_mode = 1;
};
if(fr->track == &fr->bottom)
{
if(relx < 24)
track_mode = 2;
else if(relx+24 > win->w)
track_mode = 3;
}
 
break;
};
 
case MSG_LBTNUP:
release_mouse();
fr->track = NULL;
track_mode = 0;
break;
 
case MSG_MOUSEMOVE:
if(mouse_capture == ctrl)
{
pos_t npos;
npos = get_cursor_pos();
// printf("cursor pos %dx%d\n", npos.x, npos.y);
 
if( npos.val != spos.val)
{
int w, h;
 
rect_t nrc = win->rc;
spos = npos;
 
if(fr->track == &fr->left)
{
nrc.l = npos.x-2;
if(nrc.l < 0)
nrc.l = 0;
if(track_mode==1)
nrc.b = npos.y+2;
}
else if(fr->track == &fr->right)
{
nrc.r = npos.x+2;
if(track_mode==1)
nrc.b = npos.y+2;
}
else if(fr->track == &fr->bottom)
{
nrc.b = npos.y+2;
if(track_mode==2)
nrc.l = npos.x-2;
else if (track_mode==3)
nrc.r = npos.x+2;
};
 
w = nrc.r - nrc.l;
h = nrc.b - nrc.t;
 
if(w <310)
w = 310;
if(h < 120)
h = 120;
 
__asm__ __volatile__(
"int $0x40"
::"a"(67), "b"(nrc.l), "c"(nrc.t),
"d"(w-1),"S"(h-1) );
};
}
};
 
return 1;
}
 
/contrib/media/fplay/winlib/panel.c
0,0 → 1,314
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "winlib.h"
 
#define PANEL_CORNER_W 8
#define FRAME_WIDTH 7
 
#define ID_PLAY 100
#define ID_STOP 101
#define ID_PROGRESS 102
#define ID_VOL_LEVEL 103
#define ID_VOL_CTRL 104
 
extern uint32_t main_cursor;
 
extern int res_panel_left[];
extern int res_panel_right[];
extern int res_panel_body[];
 
extern int res_play_btn[];
extern int res_play_btn_pressed[];
 
extern int res_pause_btn[];
extern int res_pause_btn_pressed[];
 
extern int res_stop_btn[];
extern int res_stop_btn_pressed[];
 
//extern int res_minimize_btn[];
//extern int res_minimize_btn_hl[];
//extern int res_minimize_btn_pressed[];
 
void update_panel_size(window_t *win);
 
int panel_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2);
 
int init_panel(window_t *win)
{
button_t *btn;
progress_t *prg;
level_t *lvl;
slider_t *sld;
 
panel_t *panel = &win->panel;
ctx_t *ctx = &panel->ctx;
 
link_initialize(&panel->ctrl.link);
list_initialize(&panel->ctrl.child);
 
panel->ctrl.handler = panel_proc;
panel->ctrl.parent = (ctrl_t*)win;
 
panel->layout = 0;
panel->bitmap.width = 1920;
panel->bitmap.height = PANEL_HEIGHT;
panel->bitmap.flags = 0;
 
if( create_bitmap(&panel->bitmap) )
{
printf("not enough memory for panel bitmap\n");
return 0;
}
 
ctx->pixmap = &panel->bitmap;
ctx->offset_x = 0;
ctx->offset_y = 0;
 
panel->ctrl.ctx = ctx;
 
btn = create_button(NULL, ID_PLAY,0,19,32,32,&panel->ctrl);
panel->play_btn = btn;
 
btn->img_default = res_pause_btn;
btn->img_hilite = res_pause_btn;
btn->img_pressed = res_pause_btn_pressed;
 
btn = create_button(NULL, ID_STOP,0,19,24,24,&panel->ctrl);
panel->stop_btn = btn;
 
btn->img_default = res_stop_btn;
btn->img_hilite = res_stop_btn;
btn->img_pressed = res_stop_btn_pressed;
 
prg = create_progress(NULL,ID_PROGRESS,0,4,0,10,&panel->ctrl);
panel->prg = prg;
 
lvl = create_level(NULL, ID_VOL_LEVEL, 0, 20, 96, 10, &panel->ctrl);
lvl->vol = -1875;
panel->lvl = lvl;
sld = create_slider(NULL, ID_VOL_CTRL, 0, 20, 96+12, 12, &panel->ctrl);
panel->sld = sld;
// btn = create_button(NULL, ID_MINIMIZE,0,5,16,18,(ctrl_t*)cpt);
// cpt->minimize_btn = btn;
 
// btn->img_default = res_minimize_btn;
// btn->img_hilite = res_minimize_btn_hl;
// btn->img_pressed = res_minimize_btn_pressed;
 
 
 
update_panel_size(win);
 
return 1;
};
 
 
static void panel_update_layout(panel_t *panel)
{
progress_t *prg = panel->prg;
level_t *lvl = panel->lvl;
if(panel->layout == 0)
{
prg->ctrl.rc.l = panel->ctrl.rc.l;
prg->ctrl.rc.t = panel->ctrl.rc.t+7;
prg->ctrl.rc.r = panel->ctrl.rc.r;
prg->ctrl.rc.b = prg->ctrl.rc.t + prg->ctrl.h;
prg->ctrl.w = prg->ctrl.rc.r - prg->ctrl.rc.l;
 
lvl->ctrl.rc.l = panel->ctrl.rc.l;
lvl->ctrl.rc.t = panel->ctrl.rc.t+7;
lvl->ctrl.rc.r = panel->lvl->ctrl.rc.l + panel->lvl->ctrl.w;
lvl->ctrl.rc.b = panel->lvl->ctrl.rc.t + panel->lvl->ctrl.h;
}
else
{
lvl->ctrl.rc.l = panel->ctrl.rc.l;
lvl->ctrl.rc.t = panel->ctrl.rc.t+7;
lvl->ctrl.rc.r = lvl->ctrl.rc.l + lvl->ctrl.w;
lvl->ctrl.rc.b = lvl->ctrl.rc.t + lvl->ctrl.h;
prg->ctrl.rc.l = lvl->ctrl.rc.r;
prg->ctrl.rc.t = panel->ctrl.rc.t+7;
prg->ctrl.rc.r = panel->ctrl.rc.r;
prg->ctrl.rc.b = prg->ctrl.rc.t + prg->ctrl.h;
prg->ctrl.w = prg->ctrl.rc.r - prg->ctrl.rc.l;
};
};
 
void panel_set_layout(panel_t *panel, int layout)
{
panel->layout = layout;
panel->lvl->visible = layout;
panel_update_layout(panel);
send_message(&panel->prg->ctrl, MSG_PAINT, 0, 0);
if(layout)
send_message(&panel->lvl->ctrl, MSG_PAINT, 0, 0);
};
 
void update_panel_size(window_t *win)
{
panel_t *panel = &win->panel;
bitmap_t *bitmap = &panel->bitmap;
 
bitmap->width = win->w;
resize_bitmap(bitmap);
panel->ctx.offset_x = 0;
panel->ctx.offset_y = win->h-PANEL_HEIGHT;
 
panel->draw.l = 0;
panel->draw.t = win->h-PANEL_HEIGHT;
panel->draw.r = win->w;
panel->draw.b = win->h;
 
panel->ctrl.rc.l = FRAME_WIDTH;
panel->ctrl.rc.t = win->h-PANEL_HEIGHT;
panel->ctrl.rc.r = win->w-FRAME_WIDTH;
panel->ctrl.rc.b = win->h-FRAME_WIDTH;
 
panel->ctrl.w = win->w;
panel->ctrl.h = PANEL_HEIGHT;
win->client.b = win->h-PANEL_HEIGHT;
 
panel->play_btn->ctrl.rc.l = win->w/2 - 16;
panel->play_btn->ctrl.rc.t = panel->ctrl.rc.t+19;
panel->play_btn->ctrl.rc.r = panel->play_btn->ctrl.rc.l + panel->play_btn->ctrl.w;
panel->play_btn->ctrl.rc.b = panel->play_btn->ctrl.rc.t + panel->play_btn->ctrl.h;
 
panel->stop_btn->ctrl.rc.l = win->w/2 - 44;
panel->stop_btn->ctrl.rc.t = panel->ctrl.rc.t+23;
panel->stop_btn->ctrl.rc.r = panel->stop_btn->ctrl.rc.l + panel->stop_btn->ctrl.w;
panel->stop_btn->ctrl.rc.b = panel->stop_btn->ctrl.rc.t + panel->stop_btn->ctrl.h;
 
panel->sld->ctrl.rc.l = panel->ctrl.rc.l;
panel->sld->ctrl.rc.t = panel->ctrl.rc.t+28;
panel->sld->ctrl.rc.r = panel->sld->ctrl.rc.l + panel->sld->ctrl.w;
panel->sld->ctrl.rc.b = panel->sld->ctrl.rc.t + panel->sld->ctrl.h;
 
panel_update_layout(panel);
};
 
 
void draw_panel(panel_t *panel)
{
int *pixmap, *src;
int i, j, w;
 
lock_bitmap(&panel->bitmap);
blit_raw(&panel->ctx, res_panel_left, 0, 0,
PANEL_CORNER_W, PANEL_HEIGHT, PANEL_CORNER_W*4);
 
 
w = panel->ctrl.w - (2*PANEL_CORNER_W);
if( w > 0)
{
pixmap = (int*)panel->ctx.pixmap->data;
pixmap+= PANEL_CORNER_W;
src = res_panel_body;
 
for(i = 0; i < PANEL_HEIGHT; i++)
{
for(j = 0; j < w; j++)
pixmap[j] = src[i];
pixmap+= panel->ctx.pixmap->pitch/4;
}
};
 
blit_raw(&panel->ctx, res_panel_right, panel->ctrl.w - PANEL_CORNER_W, 0,
PANEL_CORNER_W, PANEL_HEIGHT, PANEL_CORNER_W*4);
 
 
ctrl_t *child;
child = (ctrl_t*)panel->ctrl.child.next;
 
while( &child->link != &panel->ctrl.child)
{
send_message(child, MSG_PAINT, 0, 0);
child = (ctrl_t*)child->link.next;
};
};
 
int panel_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
panel_t *panel = (panel_t*)ctrl;
window_t *win = get_parent_window(ctrl);
 
ctrl_t *child;
int x, y;
 
x = ((pos_t)arg2).x;
y = ((pos_t)arg2).y;
 
switch( msg )
{
case 1:
draw_panel((panel_t*)ctrl);
break;
 
case MSG_MOUSEMOVE:
child = get_child(ctrl, x, y);
if( win->child_over )
{
if(child == win->child_over)
send_message(child, msg, 0, arg2);
else
send_message(win->child_over, MSG_MOUSELEAVE, 0, arg2);
}
else if( child )
send_message(child, MSG_MOUSEENTER, 0, arg2);
 
win->child_over = child;
if( child )
send_message(child,msg,0,arg2);
else if(main_cursor != 0)
{
set_cursor(0);
main_cursor = 0;
}
break;
 
case MSG_COMMAND:
switch((short)arg1)
{
case ID_PLAY:
case ID_STOP:
case ID_PROGRESS:
case ID_VOL_CTRL:
win = get_parent_window(ctrl);
send_message(win, msg, arg1, arg2);
break;
 
default:
break;
};
 
default:
child = get_child(ctrl, x, y);
if(child)
return send_message(child, msg, 0, arg2);
}
return 1;
};
 
void blit_panel(panel_t *panel)
{
// printf("%s w:%d h:%d stride: %d\n",__FUNCTION__,
// cpt->ctrl.w, cpt->ctrl.h, cpt->ctx.stride);
 
lock_bitmap(&panel->bitmap);
 
Blit(panel->ctx.pixmap->data, panel->draw.l, panel->draw.t,
0, 0, panel->ctrl.w, panel->ctrl.h,
panel->ctrl.w, panel->ctrl.h, panel->ctx.pixmap->pitch);
};
 
/contrib/media/fplay/winlib/window.c
0,0 → 1,691
 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "winlib.h"
 
#define DBG(format,...)
 
int draw_frame(window_t *win);
static int draw_window(window_t *win);
 
uint32_t main_cursor;
uint32_t cursor_ns;
uint32_t cursor_we;
uint32_t cursor_nwse;
uint32_t cursor_nesw;
 
int win_font;
 
 
static pos_t old_pos;
 
ctrl_t *mouse_capture = NULL;
 
static link_t timers;
static uint32_t realtime;
static uint32_t wait_time;
static uint32_t exp_time;
 
static int need_update;
 
#define LOAD_FROM_MEM 1
 
 
void adjust_frame(window_t *win);
 
 
#include "control.inc"
//#include "io.inc"
#include "timer.inc"
 
//#include "button.inc"
//#include "scroller.inc"
 
static window_t Window;
 
 
 
void init_frame(window_t *win);
 
window_t *create_window(char *caption, int style, int x, int y,
int w, int h, handler_t handler)
{
char proc_info[1024];
int stride;
 
// __asm__ __volatile__("int3");
 
 
// ctx_t *ctx = &Window.client_ctx;
 
if(handler==0) return 0;
 
BeginDraw();
DrawWindow(x, y, w-1, h-1,
NULL,0,0x41);
EndDraw();
 
get_proc_info(proc_info);
 
x = *(uint32_t*)(proc_info+34);
y = *(uint32_t*)(proc_info+38);
w = *(uint32_t*)(proc_info+42)+1;
h = *(uint32_t*)(proc_info+46)+1;
 
Window.handler = handler;
// Window.ctx = ctx;
 
list_initialize(&Window.link);
list_initialize(&Window.child);
 
 
// Window.bitmap.width = 1920;
// Window.bitmap.height = 1080;
// Window.bitmap.flags = 0;
 
// if( create_bitmap(&Window.bitmap) )
// {
// printf("not enough memory for window bitmap\n");
// return 0;
// }
 
// ctx->pixmap = &Window.bitmap;
// ctx->offset_x = 0;
// ctx->offset_y = 0;
 
Window.rc.l = x;
Window.rc.t = y;
Window.rc.r = x + w;
Window.rc.b = y + h;
 
Window.w = w;
Window.h = h;
 
Window.caption_txt = caption;
Window.style = style;
 
Window.child_over = NULL;
Window.child_focus = NULL;
 
init_caption(&Window);
init_panel(&Window);
init_frame(&Window);
send_message((ctrl_t*)&Window, MSG_SIZE, 0, 0);
return &Window;
};
 
 
int def_window_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
ctrl_t *child;
 
window_t *win = (window_t*)ctrl;
 
switch(msg)
{
case MSG_PAINT:
draw_window(win);
break;
 
case 2:
child = (ctrl_t*)win->child.next;
while( &child->link != &win->child)
{
send_message(child, 2, arg1, arg2);
child = (ctrl_t*)child->link.next;
};
break;
 
case MSG_MOUSEMOVE:
child = win_get_child(win, arg2 & 0xFFFF, (arg2>>16));
if( win->child_over )
{
if(child == win->child_over)
send_message(child, msg, 0, arg2);
else
send_message(win->child_over, MSG_MOUSELEAVE, 0, arg2);
}
else if( child )
send_message(child, MSG_MOUSEENTER, 0, arg2);
 
win->child_over = child;
if( child )
send_message(child,msg,0,arg2);
else if(main_cursor != 0)
{
set_cursor(0);
main_cursor = 0;
}
break;
 
case MSG_SIZE:
break;
 
default:
child = win_get_child(win, arg2 & 0xFFFF, (arg2>>16));
win->child_over = child;
if(child) send_message(child, msg, 0, arg2);
};
 
return 0;
}
 
static int draw_window(window_t *win)
{
ctrl_t *child;
void *ctx;
rect_t *rc = &win->client;
 
draw_caption(&win->caption);
draw_panel(&win->panel);
send_message(win, MSG_DRAW_CLIENT,0,0);
 
// draw_frame(win);
 
// child = (ctrl_t*)win->child.next;
 
// while( &child->link != &win->child)
// {
// send_message(child, 1, 0, 0);
// child = (ctrl_t*)child->link.next;
// };
 
return 0;
};
 
void blit_client(window_t *win)
{
int w, h;
 
w = win->client.r - win->client.l;
h = win->client.b - win->client.t;
 
Blit(win->ctx->pixmap->data, win->client.l, win->client.t,
0, 0, w, h, w, h,win->ctx->pixmap->pitch);
};
 
 
int show_window(window_t *win, int state)
{
win->win_state = state;
 
draw_window(win);
 
BeginDraw();
DrawWindow(win->rc.l, win->rc.t, win->w-1, win->h-1,
NULL,0,0x41);
EndDraw();
 
blit_caption(&win->caption);
blit_panel(&win->panel);
// blit_client(win);
return 0;
}
 
void window_update_layout(window_t *win)
{
char proc_info[1024];
 
int new_w, new_h;
uint8_t state;
 
int winx, winy, winw, winh;
 
// __asm__ __volatile__("int3");
 
get_proc_info(proc_info);
 
winx = *(uint32_t*)(proc_info+34);
winy = *(uint32_t*)(proc_info+38);
winw = *(uint32_t*)(proc_info+42)+1;
winh = *(uint32_t*)(proc_info+46)+1;
 
state = *(uint8_t*)(proc_info+70);
 
if(state & 2)
{ win->win_state = MINIMIZED;
return;
}
if(state & 4)
{
win->win_state = ROLLED;
return;
};
 
if(state & 1)
state = MAXIMIZED;
else
state = NORMAL;
 
if( (winx != win->rc.l) || (winy != win->rc.t) )
{
win->rc.l = winx;
win->rc.t = winy;
win->rc.r = winx + win->w;
win->rc.b = winy + win->h;
};
 
// if( winw == win->w &&
// winh == win->h &&
// state == win->win_state)
// return;
 
if(win->win_state != FULLSCREEN)
win->win_state = state;
 
#if 0
int old_size;
int new_size;
int pitch;
 
 
old_size = win->bitmap.pitch * win->bitmap.height;
old_size = (old_size+4095) & ~4095;
 
pitch = ALIGN(win->w*4, 16);
 
new_size = pitch * win->h;
new_size = (new_size+4095) & ~4095;
 
if( new_size < old_size)
user_unmap(win->bitmap.data, new_size, old_size-new_size);
 
win->bitmap.width = win->w;
win->bitmap.pitch = pitch;
#endif
 
win->rc.r = winx + winw;
win->rc.b = winy + winh;
win->w = winw;
win->h = winh;
 
update_caption_size(win);
update_panel_size(win);
adjust_frame(win);
 
send_message((ctrl_t*)win, MSG_SIZE, 0, 0);
draw_window(win);
};
 
 
int send_mouse_message(window_t *win, uint32_t msg)
{
ctrl_t *child;
 
if(mouse_capture)
return send_message(mouse_capture, msg, 0, old_pos.val);
 
if(pt_in_rect(&win->client, old_pos.x, old_pos.y))
return send_message((ctrl_t*)win, msg, 0, old_pos.val);
 
if(win->win_state == FULLSCREEN)
return 0;
 
if(pt_in_rect(&win->caption.ctrl.rc, old_pos.x, old_pos.y))
{
return send_message(&win->caption.ctrl, msg, 0, old_pos.val);
}
 
if(pt_in_rect(&win->panel.ctrl.rc, old_pos.x, old_pos.y))
{
// old_pos.x-= win->panel.ctrl.rc.l;
// old_pos.y-= win->panel.ctrl.rc.t;
return send_message(&win->panel.ctrl, msg, 0, old_pos.val);
}
 
 
return send_message(&win->frame, msg, 0, old_pos .val);
 
// if( ( old_pos.x < win->rc.r) && ( old_pos.y < win->rc.b))
// send_message((ctrl_t*)win, msg, 0, old_pos.val);
};
 
void do_sys_draw(window_t *win)
{
// printf("%s win:%x\n", __FUNCTION__, win);
 
window_update_layout(win);
 
BeginDraw();
DrawWindow(0,0,0,0, NULL, 0x000000,0x41);
// DefineButton(15, 15, 0x00000001, 0);
EndDraw();
 
send_message((ctrl_t*)win, MSG_DRAW_CLIENT, 0, 0);
 
if(win->win_state == FULLSCREEN)
{
need_update=0;
return;
};
 
blit_caption(&win->caption);
blit_panel(&win->panel);
 
// blit_client(win);
need_update=0;
};
 
static void do_sys_mouse(window_t *win)
{
static uint32_t mouse_click_time;
static int mouse_action;
static int old_buttons;
int buttons;
uint32_t wheels;
uint32_t click_time;
int action;
 
pos_t pos;
 
mouse_action = 0;
pos = get_mouse_pos();
 
if(pos.val != old_pos.val)
{
mouse_action = 0x80000000;
old_pos = pos;
};
// printf("pos x%d y%d\n", pos.x, pos.y);
 
buttons = get_mouse_buttons();
wheels = get_mouse_wheels();
 
if( wheels & 0xFFFF){
wheels = (short)wheels>0 ? MSG_WHEELDOWN : MSG_WHEELUP;
send_mouse_message(win, wheels);
}
 
if((action = (buttons ^ old_buttons))!=0)
{
mouse_action|= action<<3;
mouse_action|= buttons & ~old_buttons;
}
old_buttons = buttons;
 
if(mouse_action & 0x80000000) {
DBG("mouse move \n\r");
send_mouse_message(win, MSG_MOUSEMOVE);
};
 
if(mouse_action & 0x09)
{
if((mouse_action & 0x09)==0x09)
{
// printf("left button down x= %d y= %d\n\r", old_x.x, old_x.y);
click_time = get_tick_count();
if(click_time < mouse_click_time+35) {
mouse_click_time = click_time;
send_mouse_message(win,MSG_LBTNDBLCLK);
}
else {
mouse_click_time = click_time;
send_mouse_message(win,MSG_LBTNDOWN);
};
}
else {
// printf("left button up \n\r");
send_mouse_message(win,MSG_LBTNUP);
}
};
 
if(mouse_action & 0x12)
{
if((mouse_action & 0x12)==0x12) {
DBG("right button down \n\r");
send_mouse_message(win,MSG_RBTNDOWN);
}
else {
DBG("right button up \n\r");
send_mouse_message(win,MSG_RBTNUP);
};
};
if(mouse_action & 0x24)
{
if((mouse_action & 0x24)==0x24){
DBG("middle button down \n\r");
send_mouse_message(win,MSG_MBTNDOWN);
}
else {
DBG("middle button up \n\r");
send_mouse_message(win,MSG_MBTNUP);
};
};
 
 
};
 
 
void run_window(window_t *win)
{
int ev;
oskey_t key;
 
// buttons = get_mouse_buttons();
// wheels = get_mouse_wheels();
realtime = get_tick_count();
exp_time = -1;
 
while(1)
{
wait_time = exp_time - realtime;
 
ev = wait_for_event(wait_time);
 
realtime = get_tick_count();
 
// if(exp_time < realtime)
// exp_time = update_timers(realtime);
 
switch(ev)
{
case MSG_PAINT:
do_sys_draw(win);
continue;
 
case 2:
printf("key pressed\n");
key = get_key();
if( key.state == 0)
send_message((ctrl_t*)win, ev, 0, key.code);
continue;
 
case 3:
printf("Button pressed\n");
continue;
 
case 6:
do_sys_mouse(win);
continue;
 
default:
printf("event %d\n", ev);
continue;
};
};
}
 
void render_time(void *render);
 
void run_render(window_t *win, void *render)
{
int ev;
oskey_t key;
int button;
 
realtime = get_tick_count();
exp_time = -1;
 
while(win->win_command != WIN_CLOSED)
{
wait_time = exp_time - realtime;
 
ev = check_os_event();
 
realtime = get_tick_count();
 
// if(exp_time < realtime)
// exp_time = update_timers(realtime);
 
switch(ev)
{
case MSG_PAINT:
do_sys_draw(win);
break;
 
case 2:
key = get_key();
if( key.state == 0)
send_message((ctrl_t*)win, ev, 0, key.code);
break;
 
case 3:
button = get_os_button();
if(button == 1)
win->win_command = WIN_CLOSED;
break;
 
case 6:
do_sys_mouse(win);
break;
 
default:
break;
};
 
render_time(render);
};
};
 
 
 
extern unsigned char res_cursor_ns[];
extern unsigned char res_cursor_we[];
extern unsigned char res_cursor_nwse[];
extern unsigned char res_cursor_nesw[];
 
int init_resources()
{
cursor_ns = load_cursor(res_cursor_ns, LOAD_FROM_MEM);
cursor_we = load_cursor(res_cursor_we, LOAD_FROM_MEM);
cursor_nwse = load_cursor(res_cursor_nwse, LOAD_FROM_MEM);
cursor_nesw = load_cursor(res_cursor_nesw, LOAD_FROM_MEM);
 
win_font = init_fontlib();
 
return 1;
}
 
int fini_winlib()
{
int ret;
 
ret = destroy_cursor(cursor_nesw);
ret |= destroy_cursor(cursor_nwse);
ret |= destroy_cursor(cursor_we);
ret |= destroy_cursor(cursor_ns);
 
return ret;
};
 
 
 
void init_winlib(void)
{
__asm__ __volatile__(
"int $0x40"
::"a"(40), "b"(0xC0000027));
__asm__ __volatile__(
"int $0x40"
::"a"(66), "b"(1),"c"(1));
 
init_resources();
list_initialize(&timers);
};
 
//ctx_t *get_window_ctx()
//{
// return &Window.client_ctx;
//};
 
void update_rect(ctrl_t *ctrl)
{
int ctx_w, ctx_h;
int src_x, src_y;
 
src_x = ctrl->rc.l - ctrl->ctx->offset_x;
src_y = ctrl->rc.t - ctrl->ctx->offset_y;
 
ctx_w = ctrl->parent->w;
ctx_h = ctrl->parent->h;
 
Blit(ctrl->ctx->pixmap->data, ctrl->rc.l, ctrl->rc.t, src_x, src_y,
ctrl->w, ctrl->h, ctx_w, ctx_h, ctrl->ctx->pixmap->pitch);
 
// need_update++;
};
 
 
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)
{
volatile struct blit_call bc;
 
bc.dstx = dst_x;
bc.dsty = dst_y;
bc.w = w;
bc.h = h;
bc.srcx = src_x;
bc.srcy = src_y;
bc.srcw = src_w;
bc.srch = src_h;
bc.stride = stride;
bc.bitmap = bitmap;
 
__asm__ __volatile__(
"int $0x40"
::"a"(73),"b"(0x20),"c"(&bc.dstx));
 
};
 
ctrl_t *get_child(ctrl_t *ctrl, int x, int y)
{
ctrl_t *child = NULL;
 
ctrl_t *tmp = (ctrl_t*)ctrl->child.next;
 
while( &tmp->link != &ctrl->child )
{
if(pt_in_rect(&tmp->rc, x, y))
{
child = get_child(tmp, x, y);
return child == NULL ? tmp : child;
};
tmp = (ctrl_t*)tmp->link.next;
};
return child;
};
 
ctrl_t *capture_mouse(ctrl_t *newm)
{
ctrl_t *old = mouse_capture;
 
mouse_capture = newm;
 
__asm__ __volatile__(
"int $0x40"
::"a"(40), "b"(0x80000027));
 
return old;
}
 
void release_mouse(void)
{
mouse_capture = NULL;
__asm__ __volatile__(
"int $0x40"
::"a"(40), "b"(0xC0000027));
}
/contrib/media/fplay/winlib/winlib.h
0,0 → 1,150
#ifndef __WINLIB_H__
#define __WINLIB_H__
 
#include <kos32sys.h>
 
#include "control.h"
 
#define CAPTION_HEIGHT 24
#define PANEL_HEIGHT 55
 
typedef struct
{
link_t link;
link_t child;
 
handler_t *handler;
ctrl_t *parent;
 
ctx_t *ctx;
uint32_t id;
uint32_t style;
 
rect_t rc;
int w;
int h;
 
rect_t left; /* left border */
rect_t right; /* right border */
rect_t bottom; /* bottom border */
 
button_t *close_btn;
rect_t *track;
}frame_t;
 
typedef struct
{
ctrl_t ctrl;
ctx_t ctx;
bitmap_t bitmap;
char *text;
ctrl_t *child_over;
 
button_t *full_btn;
button_t *minimize_btn;
button_t *close_btn;
 
}caption_t;
 
typedef struct
{
ctrl_t ctrl;
ctx_t ctx;
bitmap_t bitmap;
rect_t draw;
ctrl_t *child_over;
int layout;
progress_t *prg;
level_t *lvl;
slider_t *sld;
button_t *play_btn;
button_t *stop_btn;
}panel_t;
 
enum win_state{
NORMAL, MINIMIZED, ROLLED, MAXIMIZED, FULLSCREEN
};
 
typedef struct
{
link_t link;
link_t child;
 
handler_t *handler;
ctrl_t *parent;
 
ctx_t *ctx;
uint32_t id;
uint32_t style;
 
rect_t rc;
int w;
int h;
 
rect_t saved;
rect_t client;
 
// ctx_t client_ctx;
// bitmap_t bitmap;
bitmap_t bitmap;
 
char *caption_txt;
ctrl_t *child_over;
ctrl_t *child_focus;
 
caption_t caption;
panel_t panel;
frame_t frame;
 
enum win_state win_state;
enum win_state saved_state;
 
enum win_command{
WIN_CLOSED=1
}win_command;
 
}window_t;
 
#define get_parent_window(x) ((window_t*)((x)->parent))
 
ctrl_t *win_get_child(window_t *win, int x, int y);
 
void init_winlib(void);
 
void draw_caption(caption_t *cpt);
void draw_panel(panel_t *panel);
void blit_caption(caption_t *cpt);
int init_caption(window_t *win);
int init_panel(window_t *win);
 
 
 
window_t *create_window(char *caption, int style, int x, int y,
int w, int h, handler_t handler);
 
int show_window(window_t *win, int state);
 
int def_window_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2);
 
void frame_run(window_t *win);
 
button_t *create_button(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent);
progress_t *create_progress(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent);
level_t *create_level(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent);
scroller_t *create_scroller(uint32_t style, int id, int x, int y,
int w, int h, ctrl_t *parent);
slider_t *create_slider(char *caption, int id, int x, int y,
int w, int h, ctrl_t *parent);
 
 
//static uint32_t update_timers(uint32_t realtime);
 
int set_timer(ctrl_t *ctrl, ostimer_t *timer, uint32_t delay);
 
void update_rect(ctrl_t *ctrl);
 
 
#endif