#include "qtvlcwidget.h"
#include <QMouseEvent>
#include <QOpenGLShaderProgram>
#include <QCoreApplication>
#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
#include <QOffscreenSurface>
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <cmath>
#include <vlc/vlc.h>
class VLCVideo
{
public:
VLCVideo(QtVLCWidget *widget)
:mWidget(widget)
{
/* Use default format for context. */
mContext = new QOpenGLContext(widget);
/* Use offscreen surface to render the buffers */
mSurface = new QOffscreenSurface(nullptr, widget);
/* Widget doesn't have an OpenGL context right now, we'll get it later. */
QObject::connect(widget, &QtVLCWidget::contextReady, [this](QOpenGLContext *render_context) {
/* Video view is now ready, we can start */
mSurface->setFormat(mWidget->format());
mSurface->create();
mContext->setFormat(mWidget->format());
mContext->setShareContext(render_context);
mContext->create();
videoReady.release();
});
}
~VLCVideo()
{
cleanup(this);
}
/// return whether we are using OpenGLES or OpenGL, which is needed to know
/// whether we use the libvlc OpenGLES2 engine or the OpenGL one
bool isOpenGLES()
{
return mContext->isOpenGLES();
}
/// return the texture to be displayed
QOpenGLFramebufferObject *getVideoFrame()
{
QMutexLocker locker(&m_text_lock);
if (m_updated) {
std::swap(m_idx_swap, m_idx_display);
m_updated = false;
}
return mBuffers[m_idx_display].get();
}
/// this callback will create the surfaces and FBO used by VLC to perform its rendering
static bool resizeRenderTextures(void* data, const libvlc_video_render_cfg_t *cfg,
libvlc_video_output_cfg_t *render_cfg)
{
VLCVideo* that = static_cast<VLCVideo*>(data);
if (cfg->width != that->m_width || cfg->height != that->m_height)
cleanup(data);
for (auto &buffer : that->mBuffers)
buffer = std::make_unique<QOpenGLFramebufferObject>(cfg->width, cfg->height);
that->m_width = cfg->width;
that->m_height = cfg->height;
that->mBuffers[that->m_idx_render]->bind();
render_cfg->opengl_format = GL_RGBA;
render_cfg->full_range = true;
render_cfg->colorspace = libvlc_video_colorspace_BT709;
render_cfg->primaries = libvlc_video_primaries_BT709;
render_cfg->transfer = libvlc_video_transfer_func_SRGB;
render_cfg->orientation = libvlc_video_orient_top_left;
return true;
}
// This callback is called during initialisation.
static bool setup(void** data, const libvlc_video_setup_device_cfg_t *cfg,
libvlc_video_setup_device_info_t *out)
{
Q_UNUSED(cfg);
Q_UNUSED(out);
if (!QOpenGLContext::supportsThreadedOpenGL())
return false;
VLCVideo* that = static_cast<VLCVideo*>(*data);
/* Wait for rendering view to be ready. */
that->videoReady.acquire();
that->m_width = 0;
that->m_height = 0;
return true;
}
// This callback is called to release the texture and FBO created in resize
static void cleanup(void* data)
{
VLCVideo* that = static_cast<VLCVideo*>(data);
that->videoReady.release();
if (that->m_width == 0 && that->m_height == 0)
return;
for (auto &buffer : that->mBuffers)
buffer.reset(nullptr);
}
//This callback is called after VLC performs drawing calls
static void swap(void* data)
{
VLCVideo* that = static_cast<VLCVideo*>(data);
QMutexLocker locker(&that->m_text_lock);
that->m_updated = true;
that->mWidget->update();
std::swap(that->m_idx_swap, that->m_idx_render);
that->mBuffers[that->m_idx_render]->bind();
}
// This callback is called to set the OpenGL context
static bool make_current(void* data, bool current)
{
VLCVideo* that = static_cast<VLCVideo*>(data);
if (current)
that->mContext->makeCurrent(that->mSurface);
else
that->mContext->doneCurrent();
return true;
}
// This callback is called by VLC to get OpenGL functions.
static void* get_proc_address(void* data, const char* current)
{
VLCVideo* that = static_cast<VLCVideo*>(data);
/* Qt usual expects core symbols to be queryable, even though it's not
* mentioned in the API. Cf QPlatformOpenGLContext::getProcAddress.
* Thus, we don't need to wrap the function symbols here, but it might
* fail to work (not crash though) on exotic platforms since Qt doesn't
* commit to this behaviour. A way to handle this in a more stable way
* would be to store the mContext->functions() table in a thread local
* variable, and wrap every call to OpenGL in a function using this
* thread local state to call the correct variant. */
return reinterpret_cast<void*>(that->mContext->getProcAddress(current));
}
private:
QtVLCWidget *mWidget;
QOpenGLContext *mContext;
QOffscreenSurface *mSurface;
QSemaphore videoReady;
//FBO data
unsigned m_width = 0;
unsigned m_height = 0;
QMutex m_text_lock;
std::unique_ptr<QOpenGLFramebufferObject> mBuffers[3];
size_t m_idx_render = 0;
size_t m_idx_swap = 1;
size_t m_idx_display = 2;
bool m_updated = false;
};
QtVLCWidget::QtVLCWidget(QWidget *parent)
: QOpenGLWidget(parent),
vertexBuffer(QOpenGLBuffer::VertexBuffer),
vertexIndexBuffer(QOpenGLBuffer::IndexBuffer)
{
// --transparent causes the clear color to be transparent. Therefore, on systems that
// support it, the widget will become transparent apart from the logo.
const char *args[] = {
"--verbose=2"
};
m_vlc = libvlc_new(sizeof(args) / sizeof(*args), args);
mVLC = std::make_unique<VLCVideo>(this);
}
bool QtVLCWidget::playMedia(const char* url)
{
m_media = libvlc_media_new_location(url);
if (m_media == nullptr) {
fprintf(stderr, "unable to create media %s", url);
return false;
}
m_mp = libvlc_media_player_new_from_media (m_vlc, m_media);
if (m_mp == nullptr) {
fprintf(stderr, "unable to create media player");
libvlc_media_release(m_media);
return false;
}
// Define the opengl rendering callbacks
libvlc_video_set_output_callbacks(m_mp,
mVLC->isOpenGLES() ? libvlc_video_engine_gles2 : libvlc_video_engine_opengl,
VLCVideo::setup, VLCVideo::cleanup, nullptr, VLCVideo::resizeRenderTextures, VLCVideo::swap,
VLCVideo::make_current, VLCVideo::get_proc_address, nullptr, nullptr,
mVLC.get());
// Play the video
libvlc_media_player_play (m_mp);
return true;
}
QtVLCWidget::~QtVLCWidget()
{
cleanup();
}
QSize QtVLCWidget::minimumSizeHint() const
{
return QSize(50, 50);
}
QSize QtVLCWidget::sizeHint() const
{
return QSize(400, 400);
}
void QtVLCWidget::cleanup()
{
stop();
if (m_vlc)
libvlc_release(m_vlc);
m_vlc = nullptr;
if (m_program == nullptr)
return;
makeCurrent();
vertexBuffer.destroy();
vertexIndexBuffer.destroy();
m_program.reset(nullptr);
doneCurrent();
}
void QtVLCWidget::stop()
{
if (m_mp) {
libvlc_media_player_release(m_mp);
m_mp = nullptr;
}
if (m_media) {
libvlc_media_release(m_media);
没有合适的资源?快使用搜索试试~ 我知道了~
最新VLC4.0+Qt设计的视频播放器(基于官方例子修改).zip
共2000个文件
dll:1566个
h:454个
a:8个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 172 浏览量
2022-12-27
16:02:03
上传
评论
收藏 281.18MB ZIP 举报
温馨提示
目前VLC已经推出了全新的4.0版本,解决了很多3.0里一直存在的问题。并且4.0的VLC支持提供了渲染接口,支持opengl、D3D渲染,二次开发非常方便。 这份资料包里包含了2份Qt例子,采用最新VLC4.0+Qt设计的视频播放器(基于官方例子修改),下载下来可以直接运行,QtCreate直接打开构建运行。编译器选择MSVC。 2分Qt例子分别是:OpenGL方式渲染,窗口句柄嵌入方式渲染。 源码里配置好了SDK路径,打开就能编译运行。
资源推荐
资源详情
资源评论
收起资源包目录
最新VLC4.0+Qt设计的视频播放器(基于官方例子修改).zip (2000个子文件)
libvlccore.dll.a 882KB
libvlccore.dll.a 882KB
libvlccore.dll.a 880KB
libvlccore.dll.a 880KB
libvlc.dll.a 266KB
libvlc.dll.a 266KB
libvlc.dll.a 266KB
libvlc.dll.a 266KB
qtvlcwidget.cpp 12KB
player.cpp 7KB
main.cpp 1KB
main.cpp 613B
libqt_plugin.dll 42.61MB
libqt_plugin.dll 42.61MB
libqt_plugin.dll 40.27MB
libqt_plugin.dll 40.27MB
libaom_plugin.dll 18.64MB
libaom_plugin.dll 18.64MB
libaom_plugin.dll 18.36MB
libaom_plugin.dll 18.36MB
libavcodec_plugin.dll 14.29MB
libavcodec_plugin.dll 14.29MB
libavcodec_plugin.dll 13.68MB
libavcodec_plugin.dll 13.68MB
libx265_plugin.dll 5.57MB
libx265_plugin.dll 5.57MB
libmedialibrary_plugin.dll 5.48MB
libmedialibrary_plugin.dll 5.48MB
libmedialibrary_plugin.dll 4.93MB
libmedialibrary_plugin.dll 4.93MB
libplacebo_vk_plugin.dll 4.82MB
libplacebo_vk_plugin.dll 4.82MB
libaccess_output_srt_plugin.dll 4.75MB
libaccess_output_srt_plugin.dll 4.75MB
libaccess_srt_plugin.dll 4.74MB
libaccess_srt_plugin.dll 4.74MB
liblibass_plugin.dll 4.69MB
liblibass_plugin.dll 4.69MB
libfreetype_plugin.dll 4.67MB
libfreetype_plugin.dll 4.67MB
libaccess_output_srt_plugin.dll 4.32MB
libaccess_output_srt_plugin.dll 4.32MB
libaccess_srt_plugin.dll 4.32MB
libaccess_srt_plugin.dll 4.32MB
libvnc_plugin.dll 4.02MB
libvnc_plugin.dll 4.02MB
libplacebo_vk_plugin.dll 4MB
libplacebo_vk_plugin.dll 4MB
liblibass_plugin.dll 3.86MB
liblibass_plugin.dll 3.86MB
libfreetype_plugin.dll 3.8MB
libfreetype_plugin.dll 3.8MB
libvpx_plugin.dll 3.8MB
libvpx_plugin.dll 3.8MB
libx264_plugin.dll 3.67MB
libx26410b_plugin.dll 3.67MB
libx264_plugin.dll 3.67MB
libx26410b_plugin.dll 3.67MB
libvnc_plugin.dll 3.6MB
libvnc_plugin.dll 3.6MB
libvpx_plugin.dll 3.54MB
libvpx_plugin.dll 3.54MB
libx265_plugin.dll 3.49MB
libx265_plugin.dll 3.49MB
libx264_plugin.dll 3.33MB
libx26410b_plugin.dll 3.33MB
libx264_plugin.dll 3.33MB
libx26410b_plugin.dll 3.33MB
libvlccore.dll 3.24MB
libvlccore.dll 3.24MB
libdcp_plugin.dll 3.13MB
libdcp_plugin.dll 3.13MB
libdcp_plugin.dll 3.09MB
libdcp_plugin.dll 3.09MB
libvlccore.dll 3.03MB
libvlccore.dll 3.03MB
librav1e_plugin.dll 2.89MB
librav1e_plugin.dll 2.89MB
libgnutls_plugin.dll 2.74MB
libgnutls_plugin.dll 2.74MB
libadaptive_plugin.dll 2.73MB
libadaptive_plugin.dll 2.73MB
libadaptive_plugin.dll 2.54MB
libadaptive_plugin.dll 2.54MB
libskins2_plugin.dll 2.51MB
libskins2_plugin.dll 2.51MB
libgnutls_plugin.dll 2.36MB
libgnutls_plugin.dll 2.36MB
libskins2_plugin.dll 2.33MB
libskins2_plugin.dll 2.33MB
librav1e_plugin.dll 2.18MB
librav1e_plugin.dll 2.18MB
libmkv_plugin.dll 2.09MB
libmkv_plugin.dll 2.09MB
libprojectm_plugin.dll 1.97MB
libprojectm_plugin.dll 1.97MB
libdav1d_plugin.dll 1.92MB
libdav1d_plugin.dll 1.92MB
liblibbluray_plugin.dll 1.9MB
liblibbluray_plugin.dll 1.9MB
共 2000 条
- 1
- 2
- 3
- 4
- 5
- 6
- 20
资源评论
DS小龙哥
- 粉丝: 4w+
- 资源: 523
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功