Advertisement
Guest User

remy

a guest
Sep 22nd, 2011
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.78 KB | None | 0 0
  1. #include "vlcslide.h"
  2.  
  3. #include <QDebug>
  4. #include <QMutexLocker>
  5. #include <GL/gl.h>
  6. #include <assert.h>
  7.  
  8. VlcSlide::VlcSlide(QString filename, int x, int y, int w, int h, double fadeTime, QGLContext *ctx, QObject *parent) :
  9.     Slideshowable(x, y, w, h, -1, fadeTime, parent),
  10.     pixels(NULL),
  11.     ctx(ctx),
  12.     in(new QMutex),
  13.     out(new QMutex),
  14.     lockin(in),
  15.     lockout(out)
  16. {
  17.     // Unlock the mutex
  18.     lockin.unlock();
  19.  
  20.     // VLC parameters
  21.     char const *vlc_argv[] = {
  22.         "--no-audio",
  23.         "--no-xlib"
  24.     };
  25.     int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
  26.  
  27.     // Init of VLC
  28.     vlc = libvlc_new(vlc_argc, vlc_argv);
  29.     m = libvlc_media_new_path(vlc, filename.toStdString().c_str());
  30.     libvlc_media_parse(m);
  31.  
  32.     mp = libvlc_media_player_new_from_media(m);
  33.  
  34.     libvlc_media_release(m);
  35.  
  36.     libvlc_video_set_callbacks(mp, &VlcSlide::lock_callback, &VlcSlide::unlock_callback, &VlcSlide::display_callback, this);
  37.  
  38.     video_size = VlcSlide::getVideoSize(m);
  39.  
  40.     // Prepare buffers, etc
  41.     glGenTextures(1, &texture);
  42.     resize(x, y, w, h);
  43.  
  44.     // Internal handling of signals
  45.     connect(this, SIGNAL(fadeInStart()), this, SLOT(rewind()));
  46.     connect(this, SIGNAL(fadeInStop()), this, SLOT(play()));
  47.     connect(this, SIGNAL(finished()), this, SLOT(fadeOut()), Qt::QueuedConnection);
  48.  
  49.     // Connect VLC events
  50.     libvlc_event_attach(libvlc_media_player_event_manager(mp), libvlc_MediaPlayerStopped, &VlcSlide::video_end_callback, this);
  51. }
  52.  
  53. VlcSlide::~VlcSlide() {
  54.     libvlc_media_player_stop(mp);
  55.     libvlc_media_player_release(mp);
  56.     libvlc_release(vlc);
  57.  
  58.     glDeleteTextures(1, &texture);
  59. }
  60.  
  61. void VlcSlide::update() {
  62.     double alpha = getAlpha();
  63.     if(alpha == 0.0) {
  64.         return;
  65.     }
  66.  
  67.     // Update the texture
  68.     if(!in->tryLock()) {
  69.         ctx->doneCurrent();
  70.  
  71.         // If the lock isn't locked, there is a frame coming in
  72.         lockout.unlock();
  73.         lockin.relock();
  74.         lockout.relock();
  75.         lockin.unlock();
  76.  
  77.         ctx->makeCurrent();
  78.     } else {
  79.         // Else, just continue
  80.         in->unlock();
  81.     }
  82.  
  83.     // Draw the texture
  84.     glBindTexture(GL_TEXTURE_RECTANGLE, texture);
  85.     glEnable(GL_TEXTURE_RECTANGLE);
  86.  
  87.     glBegin(GL_QUADS);
  88.         glColor4f(1.0, 1.0, 1.0, alpha);
  89.         glTexCoord2i(0, nh); glVertex2i(nx, ny);
  90.         glTexCoord2i(nw, nh); glVertex2i(nx + nw, ny);
  91.         glTexCoord2i(nw, 0); glVertex2i(nx + nw, ny + nh);
  92.         glTexCoord2i(0, 0); glVertex2i(nx, ny + nh);
  93.     glEnd();
  94.  
  95.     glDisable(GL_TEXTURE_RECTANGLE);
  96. }
  97.  
  98. void VlcSlide::resize(int x, int y, int w, int h) {
  99.     this->x = x;
  100.     this->y = y;
  101.     this->w = w;
  102.     this->h = h;
  103.  
  104.     qDebug() << "Video resize";
  105.  
  106.     double fiw, fih, fbw, fbh, ri, rb, scale;
  107.  
  108.     // Calculate scaled image size and crop coordinates
  109.     fiw = (double) video_size.width();
  110.     fih = (double) video_size.height();
  111.     fbw = (double) w;
  112.     fbh = (double) h;
  113.  
  114.     ri = fiw / fih;
  115.     rb = fbw / fbh;
  116.  
  117.     if(ri > rb) {
  118.         scale = fbw / fiw;
  119.         nw = w;
  120.         nh = (int)(scale * fih);
  121.         nx = 0;
  122.         ny = (h - nh) / 2;
  123.     } else {
  124.         scale = fbh / fih;
  125.         nw = (int)(scale * fiw);
  126.         nh = h;
  127.         nx = (w - nw) / 2;
  128.         ny = 0;
  129.     }
  130.  
  131.     // Resize target buffer
  132.     pixels = realloc(pixels, nw * nh * 4);
  133.  
  134.     // Resize the video
  135.     libvlc_video_set_format(mp, "RV32", nw, nh, nw * 4);
  136. }
  137.  
  138. void VlcSlide::play() {
  139.     libvlc_media_player_play(mp);
  140. }
  141.  
  142. void VlcSlide::stop() {
  143.     libvlc_media_player_stop(mp);
  144. }
  145.  
  146. void VlcSlide::rewind() {
  147.     libvlc_media_player_set_time(mp, 0);
  148.     libvlc_media_player_next_frame(mp);
  149. }
  150.  
  151. void *VlcSlide::lock(void **p_pixels) {
  152.     // Prepare for trouble
  153.     in->lock();
  154.  
  155.     // Make it double
  156.     out->lock();
  157.  
  158.     *p_pixels = this->pixels;
  159.  
  160.     // This should be the picture id, but we don't need it
  161.     return NULL;
  162. }
  163.  
  164. void VlcSlide::unlock(void *id, void *const *) {
  165.     // Unlock mutexes
  166.     in->unlock();
  167.     out->unlock();
  168.  
  169.     assert(id == NULL);
  170. }
  171.  
  172. void VlcSlide::display(void *id) const {
  173.     assert(id == NULL);
  174.  
  175.     ctx->makeCurrent();
  176.  
  177.     // Replace the texture
  178.     glBindTexture(GL_TEXTURE_RECTANGLE, texture);
  179.     glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, nw, nh, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
  180.  
  181.     ctx->doneCurrent();
  182. }
  183.  
  184. void VlcSlide::video_end() {
  185.     emit finished();
  186. }
  187.  
  188. QSize VlcSlide::getVideoSize(libvlc_media_t *m) {
  189.     int n;
  190.     libvlc_media_track_info_t *info;
  191.  
  192.     n = libvlc_media_get_tracks_info(m, &info);
  193.  
  194.     for(int i = 0; i < n; i++) {
  195.         if(info[i].i_type == libvlc_track_video) {
  196.             return QSize(info[i].u.video.i_width, info[i].u.video.i_height);
  197.         }
  198.     }
  199.  
  200.     return QSize(400, 400);
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement