Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "vlcslide.h"
- #include <QDebug>
- #include <QMutexLocker>
- #include <GL/gl.h>
- #include <assert.h>
- VlcSlide::VlcSlide(QString filename, int x, int y, int w, int h, double fadeTime, QGLContext *ctx, QObject *parent) :
- Slideshowable(x, y, w, h, -1, fadeTime, parent),
- pixels(NULL),
- ctx(ctx),
- in(new QMutex),
- out(new QMutex),
- lockin(in),
- lockout(out)
- {
- // Unlock the mutex
- lockin.unlock();
- // VLC parameters
- char const *vlc_argv[] = {
- "--no-audio",
- "--no-xlib"
- };
- int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
- // Init of VLC
- vlc = libvlc_new(vlc_argc, vlc_argv);
- m = libvlc_media_new_path(vlc, filename.toStdString().c_str());
- libvlc_media_parse(m);
- mp = libvlc_media_player_new_from_media(m);
- libvlc_media_release(m);
- libvlc_video_set_callbacks(mp, &VlcSlide::lock_callback, &VlcSlide::unlock_callback, &VlcSlide::display_callback, this);
- video_size = VlcSlide::getVideoSize(m);
- // Prepare buffers, etc
- glGenTextures(1, &texture);
- resize(x, y, w, h);
- // Internal handling of signals
- connect(this, SIGNAL(fadeInStart()), this, SLOT(rewind()));
- connect(this, SIGNAL(fadeInStop()), this, SLOT(play()));
- connect(this, SIGNAL(finished()), this, SLOT(fadeOut()), Qt::QueuedConnection);
- // Connect VLC events
- libvlc_event_attach(libvlc_media_player_event_manager(mp), libvlc_MediaPlayerStopped, &VlcSlide::video_end_callback, this);
- }
- VlcSlide::~VlcSlide() {
- libvlc_media_player_stop(mp);
- libvlc_media_player_release(mp);
- libvlc_release(vlc);
- glDeleteTextures(1, &texture);
- }
- void VlcSlide::update() {
- double alpha = getAlpha();
- if(alpha == 0.0) {
- return;
- }
- // Update the texture
- if(!in->tryLock()) {
- ctx->doneCurrent();
- // If the lock isn't locked, there is a frame coming in
- lockout.unlock();
- lockin.relock();
- lockout.relock();
- lockin.unlock();
- ctx->makeCurrent();
- } else {
- // Else, just continue
- in->unlock();
- }
- // Draw the texture
- glBindTexture(GL_TEXTURE_RECTANGLE, texture);
- glEnable(GL_TEXTURE_RECTANGLE);
- glBegin(GL_QUADS);
- glColor4f(1.0, 1.0, 1.0, alpha);
- glTexCoord2i(0, nh); glVertex2i(nx, ny);
- glTexCoord2i(nw, nh); glVertex2i(nx + nw, ny);
- glTexCoord2i(nw, 0); glVertex2i(nx + nw, ny + nh);
- glTexCoord2i(0, 0); glVertex2i(nx, ny + nh);
- glEnd();
- glDisable(GL_TEXTURE_RECTANGLE);
- }
- void VlcSlide::resize(int x, int y, int w, int h) {
- this->x = x;
- this->y = y;
- this->w = w;
- this->h = h;
- qDebug() << "Video resize";
- double fiw, fih, fbw, fbh, ri, rb, scale;
- // Calculate scaled image size and crop coordinates
- fiw = (double) video_size.width();
- fih = (double) video_size.height();
- fbw = (double) w;
- fbh = (double) h;
- ri = fiw / fih;
- rb = fbw / fbh;
- if(ri > rb) {
- scale = fbw / fiw;
- nw = w;
- nh = (int)(scale * fih);
- nx = 0;
- ny = (h - nh) / 2;
- } else {
- scale = fbh / fih;
- nw = (int)(scale * fiw);
- nh = h;
- nx = (w - nw) / 2;
- ny = 0;
- }
- // Resize target buffer
- pixels = realloc(pixels, nw * nh * 4);
- // Resize the video
- libvlc_video_set_format(mp, "RV32", nw, nh, nw * 4);
- }
- void VlcSlide::play() {
- libvlc_media_player_play(mp);
- }
- void VlcSlide::stop() {
- libvlc_media_player_stop(mp);
- }
- void VlcSlide::rewind() {
- libvlc_media_player_set_time(mp, 0);
- libvlc_media_player_next_frame(mp);
- }
- void *VlcSlide::lock(void **p_pixels) {
- // Prepare for trouble
- in->lock();
- // Make it double
- out->lock();
- *p_pixels = this->pixels;
- // This should be the picture id, but we don't need it
- return NULL;
- }
- void VlcSlide::unlock(void *id, void *const *) {
- // Unlock mutexes
- in->unlock();
- out->unlock();
- assert(id == NULL);
- }
- void VlcSlide::display(void *id) const {
- assert(id == NULL);
- ctx->makeCurrent();
- // Replace the texture
- glBindTexture(GL_TEXTURE_RECTANGLE, texture);
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, nw, nh, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
- ctx->doneCurrent();
- }
- void VlcSlide::video_end() {
- emit finished();
- }
- QSize VlcSlide::getVideoSize(libvlc_media_t *m) {
- int n;
- libvlc_media_track_info_t *info;
- n = libvlc_media_get_tracks_info(m, &info);
- for(int i = 0; i < n; i++) {
- if(info[i].i_type == libvlc_track_video) {
- return QSize(info[i].u.video.i_width, info[i].u.video.i_height);
- }
- }
- return QSize(400, 400);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement