2 2004/09/10 - Joseph Fenton, added calculation of
8 static SDL_Surface
*screen
;
9 static SDL_Overlay
*yuv
;
12 int silence
, bytes_in_buffer
= 0;
14 static unsigned char *audioport_buffer
= NULL
;
15 static volatile unsigned long samples_played
= 0;
17 extern int use_audio
, audio_sample_rate
, audio_channels
, frame_width
, frame_height
;
20 #define min(a,b) ((a) > (b) ? (b) : (a))
23 void os_delay(int msec
)
28 static unsigned long starttick
= 0;
30 unsigned long get_elapsed_samples(void)
33 return samples_played
;
35 return (SDL_GetTicks() - starttick
);
38 void start_audio(void)
50 int write_audio(char *buffer
, int len
)
52 if( (bytes_in_buffer
+len
) <= AUDIOPORT_BUFFERSIZE
) {
55 memcpy(audioport_buffer
+bytes_in_buffer
, buffer
, len
);
57 bytes_in_buffer
+= len
;
63 else if (bytes_in_buffer
< AUDIOPORT_BUFFERSIZE
) {
64 // XXX controllare questo codice, non mi convince
65 fprintf(stderr
, "Written in buffer %d bytes, trashed remaining %d bytes\n",
66 AUDIOPORT_BUFFERSIZE
- bytes_in_buffer
,
67 len
- (AUDIOPORT_BUFFERSIZE
- bytes_in_buffer
) );
70 memcpy(audioport_buffer
+bytes_in_buffer
,
71 buffer
, AUDIOPORT_BUFFERSIZE
- bytes_in_buffer
);
73 bytes_in_buffer
= AUDIOPORT_BUFFERSIZE
;
76 return AUDIOPORT_BUFFERSIZE
- bytes_in_buffer
;
79 fprintf(stderr
, "Audio port BUFFER full!!!!\n");
84 void my_audio_callback(void *userdata
, Uint8
*stream
, int len
)
88 if (bytes_in_buffer
> 0) {
90 if(bytes_in_buffer
>len
)
93 amount
= bytes_in_buffer
;
95 SDL_MixAudio(stream
, audioport_buffer
, amount
,
98 samples_played
+= ((amount
/audio_channels
)/2);
100 // memcpy(stream, audioport_buffer, amount);
102 if(amount
< bytes_in_buffer
) {
103 bytes_in_buffer
-= amount
;
104 memcpy(audioport_buffer
, audioport_buffer
+ amount
, bytes_in_buffer
);
107 memset(stream
+amount
, silence
, len
- amount
);
113 memset(stream
, silence
, len
);
118 void init_system(char *title
)
120 int sdlflags
= SDL_INIT_VIDEO
| SDL_INIT_NOPARACHUTE
;
123 sdlflags
|= SDL_INIT_AUDIO
;
126 fprintf(stderr
, "SDL initialization...\n");
131 if(SDL_Init(sdlflags
) < 0) {
132 fprintf(stderr
, "Unable to open SDL.");
139 fprintf(stderr
, " Open the window %d,%d\n", frame_width
, frame_height
);
144 if(!(screen
= SDL_SetVideoMode(frame_width
, frame_height
, 0, SDL_RESIZABLE
))) {
145 fprintf(stderr
, "Unable to open SDL window: %s.\n", SDL_GetError());
150 fprintf(stderr
, " Overlay creation....");
155 if ( !(yuv
= SDL_CreateYUVOverlay(frame_width
, frame_height
,
156 SDL_YV12_OVERLAY
, screen
)) ) {
157 fprintf(stderr
, "Couldn't create overlay: %s\n", SDL_GetError());
161 printf(" Created %dx%dx%d %s %s overlay\n",yuv
->w
,yuv
->h
,yuv
->planes
,
162 yuv
->hw_overlay
?"hardware":"software",
163 yuv
->format
==SDL_YV12_OVERLAY
?"YV12":
164 yuv
->format
==SDL_IYUV_OVERLAY
?"IYUV":
165 yuv
->format
==SDL_YUY2_OVERLAY
?"YUY2":
166 yuv
->format
==SDL_UYVY_OVERLAY
?"UYVY":
167 yuv
->format
==SDL_YVYU_OVERLAY
?"YVYU":
174 SDL_AudioSpec desired
;
175 unsigned long samples_per_frame
;
178 fprintf(stderr
, " Opening audio...\n");
183 samples_per_frame
= (unsigned long) ((double)audio_sample_rate
/ frame_rate
+ 0.5);
184 desired
.freq
= audio_sample_rate
;
185 desired
.channels
= audio_channels
;
186 desired
.samples
= samples_per_frame
;
188 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
189 desired
.format
= AUDIO_S16LSB
;
191 desired
.format
= AUDIO_S16MSB
;
194 desired
.callback
= my_audio_callback
;
196 if(SDL_OpenAudio(&desired
, NULL
) < 0) {
197 fprintf(stderr
, "Unable to open audio: %s.\n", SDL_GetError());
204 if(!(audioport_buffer
= malloc(AUDIOPORT_BUFFERSIZE
))) {
205 fprintf(stderr
, "No memory for the audio buffer!\n");
212 silence
= desired
.silence
;
217 starttick
= SDL_GetTicks();
219 SDL_WM_SetCaption(title
, NULL
);
230 fprintf(stderr
, "SDL initialized.\n");
236 void handle_events(void)
239 static int fullscreen
= 0;
240 static int paused
= 0;
246 while (SDL_PollEvent(&event
)) {
247 switch (event
.type
) {
249 // per qualche strano motivo win genera questo evento quasi a raffica...
253 case SDL_MOUSEBUTTONUP
:
254 case SDL_MOUSEBUTTONDOWN
:
257 case SDL_MOUSEMOTION
:
260 switch(event
.key
.keysym
.sym
) {
264 print_benchmark_result();
266 fprintf(stderr
, "\nTerminated by user request.\n");
273 fprintf(stderr
, "\nEntering pause mode.\n");
278 fprintf(stderr
, "\nExiting pause mode.\n");
282 sample_frame
= get_elapsed_samples();
286 SDL_FreeYUVOverlay(yuv
);
292 fprintf(stderr
, "\nEntering windowed mode...\n");
294 screen
= SDL_SetVideoMode(frame_width
, frame_height
,
303 fprintf(stderr
, "\nEntering fullscreen mode..\n");
305 screen
= SDL_SetVideoMode(800, 600,
306 32 , SDL_FULLSCREEN
|SDL_SWSURFACE
);
310 rect
.h
= min(screen
->h
, (screen
->w
* frame_height
)/frame_width
);
312 if(rect
.h
< screen
->h
) {
313 rect
.y
= (screen
->h
- rect
.h
) / 2;
320 fprintf(stderr
, "Impossible to switch to %s mode.\n",
321 fullscreen
? "fullscreen" : "windowed");
325 if(!(yuv
= SDL_CreateYUVOverlay(frame_width
, frame_height
,
326 SDL_YV12_OVERLAY
, screen
))) {
327 fprintf(stderr
, "Impossible to recreate video overlay!\n");
332 fprintf(stderr
, "Setting rectangle to (%d,%d) %dx%d\n",
333 rect
.x
, rect
.y
, rect
.w
, rect
.h
);
340 case SDL_VIDEORESIZE
:
341 SDL_FreeYUVOverlay(yuv
);
343 screen
=SDL_SetVideoMode(event
.resize
.w
, event
.resize
.h
,
347 fprintf(stderr
, "Non riesco a ridimensionare la finestra!\n");
351 if(!(yuv
= SDL_CreateYUVOverlay(frame_width
, frame_height
,
352 SDL_YV12_OVERLAY
, screen
))) {
353 fprintf(stderr
, "Errore nell'inizializzazione dell'overlay!\n");
357 rect
.w
=event
.resize
.w
;
358 rect
.h
=event
.resize
.h
;
367 void display_picture(AVPicture
*picture
)
369 if(yuv
&& !SDL_LockYUVOverlay(yuv
) ) {
371 if(yuv
->pitches
[0] == picture
->linesize
[0]) {
372 int size
= yuv
->pitches
[0] * yuv
->h
;
374 memcpy(yuv
->pixels
[0], picture
->data
[0], size
);
376 memcpy(yuv
->pixels
[2], picture
->data
[1], size
);
377 memcpy(yuv
->pixels
[1], picture
->data
[2], size
);
380 register unsigned char *y1
,*y2
,*y3
,*i1
,*i2
,*i3
;
383 y3
= yuv
->pixels
[1]; // invertiti xche' avevo i colori sballati!
390 for (i
= 0; i
<(yuv
->h
/2); i
++) {
391 memcpy(y1
,i1
,yuv
->pitches
[0]);
392 i1
+=picture
->linesize
[0];
394 memcpy(y1
,i1
,yuv
->pitches
[0]);
396 memcpy(y2
,i2
,yuv
->pitches
[1]);
397 memcpy(y3
,i3
,yuv
->pitches
[2]);
402 i1
+=picture
->linesize
[0];
403 i2
+=picture
->linesize
[1];
404 i3
+=picture
->linesize
[2];
407 SDL_UnlockYUVOverlay(yuv
);
410 SDL_DisplayYUVOverlay(yuv
, &rect
);