qtffplay.cpp

00001 #include "qtffplay.h"
00002 //#include "qtffutil.h"
00003 
00004 #include <iostream>
00005 //testing
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         //setAttribute(Qt::WA_PaintOnScreen);
00019         //input_filename="example.avi";
00020     /* register all codecs, demux and protocols */
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         //myscreen = SDL_SetVideoMode(640,480, 32, flags);
00036  
00037 }
00038 
00039 void QtFFPlay::paintEvent(QPaintEvent *)
00040 {
00041         //if (alreadyInit)
00042                 //grabWindow(); 
00043                 //SDL_UpdateRect(myscreen, 0, 0, this->width(), this->height());
00044 }
00045 
00046 void QtFFPlay::togglePause()
00047 {
00048         mythread.togglePause();
00049 }
00050 void QtFFPlay::resizeEvent(QResizeEvent *)
00051 {
00052         // Set the new video mode with the new window size
00053     //
00054     //if (alreadyInit)
00055         //      grabWindow();
00056                         
00057     //char variable[64];
00058     //sprintf(variable, "SDL_WINDOWID=0x%lx", winId());
00059     //snprintf(variable, sizeof(variable), "SDL_WINDOWID=0x%lx", winId());
00060     //snprintf(variable, sizeof("SDL_WINDOWID=0x0000000"), "SDL_WINDOWID=0x%lx", winId());
00061     //putenv(variable);
00062     //std::cout << variable << std::endl;
00063 }    
00064     
00065 int QtFFPlay::init()
00066 {
00067     // To be called after at least a filename is chosen
00068     //parse_options(argc, argv, options);
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; /* Not supported on win32 or darwin */
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         /* save the screen resolution... SDL should allow full screen
00085            by resizing the window */
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         /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
00110         //myscreen = SDL_SetVideoMode(this->width(),this->height(), 24, flags);
00111         mythread.myscreen = SDL_SetVideoMode(w,h, 32, flags);
00112         //myscreen = SDL_SetVideoMode(640,480, 32, flags);
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         //grabWindow();
00126     cur_stream = stream_open(&input_filename, &*file_iformat);
00127 
00128      mythread.EXIT_INPUT_THREAD=0;
00129      mythread.start();
00130      alreadyInit = 1;
00131      //mythread.togglePause();
00132         return 0;
00133     
00134     
00135 }
00136 
00137 QImage* QtFFPlay::grabFrame()
00138 {
00139         
00140         if ( !this->buffer_init )
00141                 {
00142                         //av_free(buffer_rgb);
00143                                 
00144                         buffer_rgb = (Uint32*)calloc( globLine0 * globHeight , 4 );
00145                         //std::cout << "Allocating buffer." << std::endl;
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                 // Now find the correct v and u pixels!
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         //std::cout << "Grabbed a frame." << std::endl;
00175         
00176         QImage *img1 = new QImage( (unsigned char*)buffer_rgb, globLine0, globHeight, QImage::Format_RGB32);
00177         //QPixmap pm = QPixmap::fromImage( *img1 );
00178         //pm.save("test1.png", "png");
00179         //char *filnm = "testpgmR.pgm";    
00180         //save_pgm( (unsigned char*)dataR, globLine0, globWidth, globHeight, filnm);
00181         return img1;    
00182         
00183 }
00184 
00185 void QtFFPlay::save_pgm(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
00186 {
00187         /* Test write to pgm format!*/
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         /*// take YUV and convert to RGB
00201         float r,g,b;
00202         float Y = yy;
00203         float U = uu;
00204         float V = vv;   
00205 //      r = (float)Y + 1.403 * (float)V;
00206 //      g = (float)Y - 0.344*(float)U - 0.714 * (float)V;
00207 //      b = (float)Y + 1.770*(float)U;
00208 
00209         b = 1.164 *(Y - 16)                   + 2.018*(U - 128);
00210         g = 1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128);
00211         r = 1.164*(Y - 16) + 1.596*(V - 128);
00212 
00213         if (b > 255) b = 255;
00214         if (r > 255) r = 255;
00215         if (g > 255) g = 255;
00216         if (b < 0 ) b = 0;
00217         if (r < 0 ) r = 0;
00218         if (g < 0 ) g = 0;
00219         
00220         Uint32 rgb = 0;
00221         Uint8 tmpint;
00222         tmpint = r;
00223         rgb = rgb | ( tmpint << 16);
00224         tmpint = g;
00225         rgb = rgb | ( tmpint << 8);
00226         rgb = rgb + (int)b;
00227         rgb = rgb | 0xff000000;
00228         return rgb;
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    // Even with proper conversion, some values still need clipping.
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         // The original videostate that is used is created here.
00256     
00257     is = (VideoState*)av_mallocz(sizeof(VideoState));
00258     if (!is)
00259         return NULL;
00260    //const char *buffer = filename->data();
00261    
00262         QByteArray foo = filename->toAscii();
00263         const char* buffer = foo.data();
00264    
00265     //const char buffer[1024]=filename->data();
00266     //is->filename = (const char*)filename->data()->toAscii();
00267     //is->filename = 
00268     //is->filename = filename->toLatin1();
00269     pstrcpy(is->filename, sizeof(is->filename), buffer);
00270     
00271     //
00272     //is->filename[0] = buffer[0];//(char)input_filename.data();
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     /* start video display */
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     /* add the refresh timer to draw the picture */
00294     mythread.schedule_refresh(is, 40);
00295 
00296     is->av_sync_type = av_sync_type;
00297     mythread.init(is);
00298     /*is->parse_tid = SDL_CreateThread(decode_thread, is);
00299     if (!is->parse_tid) {
00300         av_free(is);
00301         return NULL;
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 //#ifdef CONFIG_NETWORK
00345 //void QtFFPlay::opt_rtp_tcp(void)
00346 //{
00347     /* only tcp protocol */
00348     //rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
00349 //}
00350 //#endif
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 

Generated on Thu Aug 17 12:14:56 2006 for VisualODF by  doxygen 1.4.7