I am using libvlc to play video on my GUI Application using QT 4. When I seek forward the video it works fine, but when I seek back the video, it gets stuck I mean frame doesn't change and my callback function which is videopostrender doesn't get any call.
void videoPrerender(void *p_video_data,
uint8_t **pp_pixel_buffer,
int size)
{
// Locking
//printf("cbVideoPrerender %i\n",size);
//printf("vtest: %lld\n",(long long int)p_video_data);
VLCPlayer* player = reinterpret_cast<VLCPlayer*>(p_video_data);
player->m_mutex.lock();
if ((size > player->m_videoBufferSize) || !player->m_videoBuffer)
{
printf("Reallocate raw video buffer\n");
if(player->m_videoBuffer) free(player->m_videoBuffer);
player->m_videoBuffer = (uint8_t *)malloc(size);
player->m_videoBufferSize = size;
}
*pp_pixel_buffer = player->m_videoBuffer;
}
void videoPostrender(void *p_video_data,
uint8_t *p_pixel_buffer,
int width,
int height,
int pixel_pitch,
int size,
int64_t pts)
{
Q_UNUSED(p_pixel_buffer)
Q_UNUSED(size)
//printf("cbVideoPostrender %i\n",size);
// Unlocking
VLCPlayer* player = reinterpret_cast<VLCPlayer*>(p_video_data);
player->m_mutex.unlock();
player->m_frameWidth = width;
player->m_frameHeight = height;
player->m_framePixelPitch = pixel_pitch;
player->m_framePts = pts;
if(player)
{
player->m_frameImage = QImage((uchar*)player->m_videoBuffer,
width, height,
QImage::Format_ARGB32_Premultiplied);
if(player->isLocalFile())
{
// Need not use timer based playing mechanism for local files.
int interval = 100 / player->videoFPS();
while(!player->m_elapsedTimer.hasExpired(interval))
qApp->processEvents();
player->m_elapsedTimer.restart();
}
if(player->record_state() == VLCPlayer::Playing)
{
player->emitRecorderTimeChanged();
}
qDebug()<<player->m_framePts;
emit player->frameReady(player->m_frameImage);
}
}
EDIT 1 - Adding more code for better understanding
VLCPlayer::VLCPlayer(const QStringList &args, QObject *parent)
: QObject(parent),
m_frameWidth(0),
m_frameHeight(0),
m_framePixelPitch(0),
m_framePts(0),
m_videoBuffer(0),
m_audioBuffer(0),
m_videoBufferSize(0),
m_audioBufferSize(0)
{
d = new VLCPlayerData;
qRegisterMetaType<VLCPlayer::VLCPlayerState>("VLCPlayer::VLCPlayerState");
char **argv = (char **)malloc(sizeof(char **) * args.count());
for (int i = 0; i < args.count(); ++i)
argv[i] = (char *)qstrdup(args.at(i).toUtf8().data());
// VLC options
char smem_options[1000];
sprintf_s(smem_options
, "#transcode{vcodec=RV32,acodec=s16l}:smem{"
"video-prerender-callback=%lld,"
"video-postrender-callback=%lld,"
"audio-prerender-callback=%lld,"
"audio-postrender-callback=%lld,"
"audio-data=%lld,"
"video-data=%lld},"
, (long long int)(intptr_t)(void*)&videoPrerender
, (long long int)(intptr_t)(void*)&videoPostrender
, (long long int)(intptr_t)(void*)&audioPrerender
, (long long int)(intptr_t)(void*)&audioPostrender
, (long long int)(intptr_t)(void*)this //This would normally be useful data, 100 is just test data
, (long long int)(intptr_t)(void*)this); //Test data
const char * const vlc_args[] = {
"-I", "dummy", // Don't use any interface
"--sout-x264-preset=ultrafast",
"--file-caching=100",
"--disc-caching=100",
"--live-caching=100",
"--network-caching=300",
"ffmpeg-hw",
// "--ignore-config", // Don't use VLC's config
// "--extraintf=logger", // Log anything
// "--verbose=1", // Be verbose
// argv,
"--sout", smem_options // Stream to memory
};
d->libvlcInstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
d->libvlcMediaPlayer = libvlc_media_player_new(d->libvlcInstance);
d->libvlcEventManager = libvlc_media_player_event_manager(d->libvlcMediaPlayer);
void VLCPlayer::setPosition(float position)
{
if(!d->libvlcMediaPlayer)
return;
libvlc_media_player_set_position(d->libvlcMediaPlayer, position);
}
void VLCPlayer::updatePlayingState()
{
qDebug()<<"updatePlayingState";
this->setState(VLCPlayer::Playing);
QMetaObject::invokeMethod(this, "updateStateTimer", Qt::QueuedConnection);
}
void VLCPlayer::emitPositionChanged()
{
if(!d->libvlcMediaPlayer)
return;
qDebug()<<"emitPositionChanged";
emit positionChanged(libvlc_media_player_get_position(d->libvlcMediaPlayer));
}
void VLCPlayer::libvlc_callback(const libvlc_event_t *event,
void *data)
{
VLCPlayer* player = (VLCPlayer*) data;
if(!player)
return;
switch(event->type)
{
case libvlc_MediaPlayerMediaChanged:
break;
case libvlc_MediaPlayerNothingSpecial:
break;
case libvlc_MediaPlayerOpening:
player->setState(VLCPlayer::Opening);
break;
case libvlc_MediaPlayerBuffering:
player->setState(VLCPlayer::Buffering);
break;
case libvlc_MediaPlayerPlaying:
player->updatePlayingState();
break;
case libvlc_MediaPlayerPaused:
player->setState(VLCPlayer::Paused);
break;
case libvlc_MediaPlayerStopped:
player->setState(VLCPlayer::Stopped);
break;
case libvlc_MediaPlayerForward:
break;
case libvlc_MediaPlayerBackward:
break;
case libvlc_MediaPlayerEndReached:
player->setState(VLCPlayer::EndReached);
break;
case libvlc_MediaPlayerEncounteredError:
player->setState(VLCPlayer::Stopped);
break;
case libvlc_MediaPlayerTimeChanged:
player->updatePlayingState();
player->emitTimeChanged();
break;
case libvlc_MediaPlayerPositionChanged:
player->updatePlayingState();
player->emitPositionChanged();
break;
case libvlc_MediaPlayerSeekableChanged:
break;
case libvlc_MediaPlayerPausableChanged:
break;
case libvlc_MediaPlayerTitleChanged:
break;
case libvlc_MediaPlayerSnapshotTaken:
break;
case libvlc_MediaPlayerLengthChanged:
player->emitLengthChanged();
break;
case libvlc_MediaPlayerVout:
break;
default:
player->setState(VLCPlayer::Unknown);
break;
}
}