vtest2.c

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2007 Krzysztof Kosciuszkiewicz
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 */
00018 #include "race.h"
00019 #include "utils.h"
00020 #include "mmfile.h"
00021 #include "int_types.h"
00022 #include <assert.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <stdarg.h>
00026 #include <unistd.h>
00027 #include <limits.h>
00028 #include <time.h>
00029 #include <math.h>
00030 #include <SDL.h>
00031 
00032 #ifndef min
00033 #   define min(a, b) ((a) <= (b) ? (a) : (b))
00034 #endif
00035 
00036 void
00037 eperror(const char *str)
00038 {
00039     perror(str);
00040     exit(EXIT_FAILURE);
00041 }
00042 
00043 void
00044 eprintf(const char *fmt, ...)
00045 {
00046     va_list ap;
00047 
00048     va_start(ap, fmt);
00049     vfprintf(stderr, fmt, ap);
00050     va_end(ap);
00051     exit(EXIT_FAILURE);
00052 }
00053 
00054 void
00055 usage(const char *progname)
00056 {
00057     if (strrchr(progname, '/') != NULL)
00058         progname = strrchr(progname, '/') + 1;
00059     fprintf(stderr, "usage: %s file.ogg\n", progname);
00060     exit(EXIT_SUCCESS);
00061 }
00062 
00063 struct audiobuf
00064 {
00065     char *buf;
00066     int off, bytes, size;
00067 };
00068 
00069 static void
00070 audio_cb(void *userdata, Uint8 * stream, int len)
00071 {
00072     struct audiobuf *abuf = userdata;
00073     int to_copy = min(len, abuf->bytes);
00074 
00075     memcpy(stream, abuf->buf + abuf->off, to_copy);
00076     abuf->bytes -= to_copy;
00077     abuf->off += to_copy;
00078 }
00079 
00080 int
00081 main(int argc, char **argv)
00082 {
00083     char *file = NULL;
00084     int have_video = 0, have_audio = 0;
00085     unsigned h = 0, w = 0;
00086     float fps = 0.0;
00087     unsigned ch = 0, hz = 0;
00088     struct audiobuf abuf;
00089     int end = 0;
00090     SDL_Surface *display = NULL;
00091     SDL_Overlay *ovl = NULL;
00092     SDL_Event event;
00093     mm_file media;
00094 
00095     if (argc > 1)
00096         file = argv[1];
00097     else
00098         usage(argv[0]);
00099 
00100     if (mm_open(&media, file) <= 0)
00101         eprintf("No audio or video in `%s'\n", file);
00102 
00103     if (mm_video_info(&media, &w, &h, &fps) >= 0)
00104     {
00105         printf("Video data: %dx%d, %gfps\n", w, h, fps);
00106         have_video = 1;
00107     }
00108 
00109     if (mm_audio_info(&media, &ch, &hz) >= 0)
00110     {
00111         printf("Audio data: %s, %dHz\n", (ch == 1) ? "mono" : "stereo", hz);
00112         have_audio = 1;
00113     }
00114 
00115     if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0)
00116         eprintf("Sdl init failed: %s\n", SDL_GetError());
00117 
00118     if (have_video)
00119     {
00120         if ((display = SDL_SetVideoMode(w, h, 24,
00121                     SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
00122             eprintf("SDL_SetVideoMode: %s\n", SDL_GetError());
00123 
00124         if ((ovl = SDL_CreateYUVOverlay(w, h,
00125                     SDL_YV12_OVERLAY, display)) == NULL)
00126             eprintf("SDL_CreateYUVOverlay: %s\n", SDL_GetError());
00127     }
00128 
00129     if (have_audio)
00130     {
00131         int bytes;
00132         int bps;
00133         double tdiff;
00134         SDL_AudioSpec desired;
00135 
00136         desired.channels = ch;
00137         desired.freq = hz;
00138         desired.format = AUDIO_U8;
00139         bps = ch * 1;
00140         desired.samples = 4096;
00141         desired.callback = audio_cb;
00142         desired.userdata = &abuf;
00143         if (SDL_OpenAudio(&desired, NULL) < 0)
00144             eprintf("SDL_OpenAudio: %s\n", SDL_GetError());
00145 
00146         abuf.size = 4 * 4096;
00147         abuf.off = 0;
00148         abuf.bytes = 0;
00149         abuf.buf = xmalloc(abuf.size);
00150 
00151         tdiff = get_time();
00152         while ((bytes = mm_decode_audio(&media,
00153                     abuf.buf + abuf.bytes, abuf.size - abuf.bytes)) > 0)
00154         {
00155             abuf.bytes += bytes;
00156             if (abuf.size - abuf.bytes <= 4096)
00157                 abuf.buf = xrealloc(abuf.buf, abuf.size *= 2);
00158         };
00159         if (bytes < 0)
00160             eperror("convert_audio");
00161 
00162         printf("Decoding: %.3f seconds\n", get_time() - tdiff);
00163         printf("Audio: %d samples, %.2f seconds\n", abuf.bytes / bps,
00164             (double) (abuf.bytes) / bps / desired.freq);
00165 
00166         SDL_PauseAudio(0);
00167     }
00168 
00169     while (!end)
00170     {
00171         while (SDL_PollEvent(&event))
00172             switch (event.type)
00173             {
00174                 case SDL_QUIT:
00175                     end = 1;
00176                     break;
00177                 case SDL_KEYDOWN:
00178                     if (event.key.keysym.sym == SDLK_q
00179                         || event.key.keysym.sym == SDLK_ESCAPE)
00180                         end = 1;
00181                     break;
00182                 default:
00183                     break;
00184             }
00185 
00186         if (have_video && !end)
00187         {
00188             static double oldt, newt;
00189 
00190             if (mm_decode_video(&media, ovl) > 0)
00191             {
00192                 SDL_Rect r = { 0, 0, w, h };
00193                 newt = 1 / fps + oldt - get_time();
00194                 if (newt > 0)
00195                     SDL_Delay(newt * 1000);
00196                 SDL_DisplayYUVOverlay(ovl, &r);
00197                 oldt = get_time();
00198             }
00199             else
00200                 end = 1;
00201         }
00202 
00203         if (have_audio && abuf.bytes <= 0)
00204             end = 1;
00205 
00206         if (!have_video)
00207             SDL_Delay(100);
00208     }
00209 
00210     if (have_audio)
00211     {
00212         SDL_PauseAudio(1);
00213         free(abuf.buf);
00214     }
00215 
00216     if (have_video)
00217     {
00218         SDL_FreeYUVOverlay(ovl);
00219     }
00220 
00221     SDL_Quit();
00222     mm_close(&media);
00223 
00224     return EXIT_SUCCESS;
00225 }
00226 
00227 /* vim: set noet ts=4 sw=4 tw=77: */

Generated on Fri Sep 28 00:35:46 2007 for raceintospace by  doxygen 1.5.3