00001 #include "qtffplay.h"
00002
00003
00004 #include <iostream>
00005
00006 #include <QLabel>
00007 #include <QPixmap>
00008
00009 Uint8 *dataR, *dataG, *dataB, *dataA;
00010 int globWidth, globHeight;
00011 int globLine0, globLine1, globLine2;
00012
00013 QtFFPlay::QtFFPlay(QWidget *parent, Qt::WFlags flags) : QWidget(parent, flags)
00014 {
00015
00016 alreadyInit = 0;
00017 buffer_init = 0;
00018
00019
00020
00021 av_register_all();
00022
00023 }
00024
00025
00026 void QtFFPlay::grabWindow()
00027 {
00028 SDL_QuitSubSystem(SDL_INIT_VIDEO);
00029 char variable[64];
00030 snprintf(variable, sizeof("SDL_WINDOWID=0x0000000"), "SDL_WINDOWID=0x%lx", winId());
00031 putenv(variable);
00032 std::cout << "in grabwindow " << variable << std::endl;
00033 SDL_InitSubSystem(SDL_INIT_VIDEO);
00034 mythread.myscreen = SDL_SetVideoMode(this->width(),this->height(), 32, flags);
00035
00036
00037 }
00038
00039 void QtFFPlay::paintEvent(QPaintEvent *)
00040 {
00041
00042
00043
00044 }
00045
00046 void QtFFPlay::togglePause()
00047 {
00048 mythread.togglePause();
00049 }
00050 void QtFFPlay::resizeEvent(QResizeEvent *)
00051 {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 }
00064
00065 int QtFFPlay::init()
00066 {
00067
00068
00069 if (input_filename.isEmpty())
00070 show_help();
00071 if (display_disable) {
00072 video_disable = 1;
00073 }
00074 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
00075 #if !defined(CONFIG_WIN32) && !defined(CONFIG_DARWIN)
00076 flags |= SDL_INIT_EVENTTHREAD;
00077 #endif
00078 if (SDL_Init (flags)) {
00079 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
00080 return 1;
00081 }
00082 if (!display_disable) {
00083 #ifdef HAVE_X11
00084
00085
00086 {
00087 Display *dpy;
00088 dpy = XOpenDisplay(NULL);
00089 if (dpy) {
00090 fs_screen_width = DisplayWidth(dpy, DefaultScreen(dpy));
00091 fs_screen_height = DisplayHeight(dpy, DefaultScreen(dpy));
00092 XCloseDisplay(dpy);
00093 }
00094 }
00095 #endif
00096 flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
00097 if (is_full_screen && fs_screen_width) {
00098 w = fs_screen_width;
00099 h = fs_screen_height;
00100 flags |= SDL_FULLSCREEN;
00101 } else {
00102 w = screen_width;
00103 h = screen_height;
00104 flags |= SDL_RESIZABLE;
00105 }
00106 #ifndef CONFIG_DARWIN
00107 mythread.myscreen = SDL_SetVideoMode(w, h, 0, flags);
00108 #else
00109
00110
00111 mythread.myscreen = SDL_SetVideoMode(w,h, 32, flags);
00112
00113 #endif
00114 if (!mythread.myscreen) {
00115 fprintf(stderr, "SDL: could not set video mode\n");
00116 return 1 ;
00117 }
00118 SDL_WM_SetCaption("VisualODF", "VisualODF");
00119 }
00120
00121 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
00122 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
00123 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
00124 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
00125
00126 cur_stream = stream_open(&input_filename, &*file_iformat);
00127
00128 mythread.EXIT_INPUT_THREAD=0;
00129 mythread.start();
00130 alreadyInit = 1;
00131
00132 return 0;
00133
00134
00135 }
00136
00137 QImage* QtFFPlay::grabFrame()
00138 {
00139
00140 if ( !this->buffer_init )
00141 {
00142
00143
00144 buffer_rgb = (Uint32*)calloc( globLine0 * globHeight , 4 );
00145
00146 this->buffer_init = 1;
00147 }
00148
00149
00150 Uint8 y,u,v;
00151 Uint32 rgbval = 0;
00152 int xLoc, yLoc, newX, newY, newIdx;
00153
00154
00155 for (int i = 0; i < globLine0 * globHeight; i++)
00156 {
00157 y = dataR[i];
00158
00159
00160 xLoc = (int) ((double)i/(double)globWidth);
00161 yLoc = (i % globWidth);
00162 newX = xLoc/2;
00163 newY = yLoc/2;
00164 newIdx = (newX*globWidth/2+ newY);
00165
00166 v = dataG[newIdx];
00167 u = dataB[newIdx];
00168
00169 rgbval = convert_yuv_rgb(y,u,v);
00170
00171 buffer_rgb[i] = rgbval;
00172
00173 }
00174
00175
00176 QImage *img1 = new QImage( (unsigned char*)buffer_rgb, globLine0, globHeight, QImage::Format_RGB32);
00177
00178
00179
00180
00181 return img1;
00182
00183 }
00184
00185 void QtFFPlay::save_pgm(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
00186 {
00187
00188 FILE *f;
00189 int i;
00190 std::cout << "Writing pgm: " << wrap << " " << xsize << " " << ysize << " " << filename << std::endl;
00191 f=fopen(filename,"w");
00192 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
00193 for(i=0;i<ysize;i++)
00194 fwrite(buf + i * wrap,1,xsize,f);
00195 fclose(f);
00196 }
00197
00198 Uint32 QtFFPlay::convert_yuv_rgb(Uint8 y, Uint8 u, Uint8 v)
00199 {
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 unsigned int pixel32;
00231 unsigned char *pixel = (unsigned char *)&pixel32;
00232 int r, g, b;
00233 r = y + (1.370705 * (v-128));
00234 g = y - (0.698001 * (v-128)) - (0.337633 * (u-128));
00235 b = y + (1.732446 * (u-128));
00236
00237 if (r > 255) r = 255;
00238 if (g > 255) g = 255;
00239 if (b > 255) b = 255;
00240 if (r < 0) r = 0;
00241 if (g < 0) g = 0;
00242 if (b < 0) b = 0;
00243
00244 pixel[0] = r * 220 / 256;
00245 pixel[1] = g * 220 / 256;
00246 pixel[2] = b * 220 / 256;
00247
00248 pixel[3] = 0;
00249 return pixel32;
00250 }
00251
00252
00253 VideoState* QtFFPlay::stream_open(QString *filename, AVInputFormat *iformat)
00254 {
00255
00256
00257 is = (VideoState*)av_mallocz(sizeof(VideoState));
00258 if (!is)
00259 return NULL;
00260
00261
00262 QByteArray foo = filename->toAscii();
00263 const char* buffer = foo.data();
00264
00265
00266
00267
00268
00269 pstrcpy(is->filename, sizeof(is->filename), buffer);
00270
00271
00272
00273 std::cout << "Playing " << is->filename << std::endl;
00274 is->iformat = iformat;
00275 if (mythread.myscreen) {
00276 is->width = mythread.myscreen->w;
00277 is->height = mythread.myscreen->h;
00278 }
00279 is->ytop = 0;
00280 is->xleft = 0;
00281
00282
00283 is->pictq_mutex = SDL_CreateMutex();
00284 is->pictq_cond = SDL_CreateCond();
00285
00286 is->subpq_mutex = SDL_CreateMutex();
00287 is->subpq_cond = SDL_CreateCond();
00288
00289 is->subtitle_decoder_mutex = SDL_CreateMutex();
00290 is->audio_decoder_mutex = SDL_CreateMutex();
00291 is->video_decoder_mutex = SDL_CreateMutex();
00292
00293
00294 mythread.schedule_refresh(is, 40);
00295
00296 is->av_sync_type = av_sync_type;
00297 mythread.init(is);
00298
00299
00300
00301
00302
00303
00304
00305 return is;
00306 }
00307
00308
00309
00310 void QtFFPlay::opt_width(const char *arg)
00311 {
00312 screen_width = atoi(arg);
00313 }
00314
00315 void QtFFPlay::opt_height(const char *arg)
00316 {
00317 screen_height = atoi(arg);
00318 }
00319
00320 void QtFFPlay::opt_format(const char *arg)
00321 {
00322 file_iformat = av_find_input_format(arg);
00323 if (!file_iformat) {
00324 fprintf(stderr, "Unknown input format: %s\n", arg);
00325 exit(1);
00326 }
00327 }
00328
00329 void QtFFPlay::opt_image_format(const char *arg)
00330 {
00331 AVImageFormat *f;
00332
00333 for(f = first_image_format; f != NULL; f = f->next) {
00334 if (!strcmp(arg, f->name))
00335 break;
00336 }
00337 if (!f) {
00338 fprintf(stderr, "Unknown image format: '%s'\n", arg);
00339 exit(1);
00340 }
00341 image_format = f;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 void QtFFPlay::opt_sync(const char *arg)
00353 {
00354 if (!strcmp(arg, "audio"))
00355 av_sync_type = AV_SYNC_AUDIO_MASTER;
00356 else if (!strcmp(arg, "video"))
00357 av_sync_type = AV_SYNC_VIDEO_MASTER;
00358 else if (!strcmp(arg, "ext"))
00359 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
00360 else
00361 show_help();
00362 }
00363
00364 void QtFFPlay::opt_seek(const char *arg)
00365 {
00366 start_time = parse_date(arg, 1);
00367 }
00368
00369 void QtFFPlay::opt_debug(const char *arg)
00370 {
00371 debug = atoi(arg);
00372 }
00373
00374 void QtFFPlay::opt_vismv(const char *arg)
00375 {
00376 debug_mv = atoi(arg);
00377 }
00378
00379 void QtFFPlay::opt_thread_count(const char *arg)
00380 {
00381 thread_count= atoi(arg);
00382 #if !defined(HAVE_THREADS)
00383 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
00384 #endif
00385 }
00386
00387 void QtFFPlay::show_help(void)
00388 {
00389 }
00390
00391 void QtFFPlay::parse_arg_file(const char *filename)
00392 {
00393 if (!strcmp(filename, "-"))
00394 filename = "pipe:";
00395 input_filename = filename;
00396 }
00397