如何正确使用 libvlc (C++) 从 h264 视频流中获取帧
How correctly use libvlc (C++) to get frames from h264 videostream?
我有兴趣使用libvlc库从h264流中获取视频帧的解决方案。我已将回调设置为 libvlc_video_set_format_callbacks
,并从我的回调函数 ( format_callback
( 参数中收到以下信息: 色度: "J420", 宽度: 1088 , 高度: 1922
当我打电话给主
Player p;
p.play("rtsp://path/to/camera?videocodec=h264");
它打印出以下错误
chroma "J420" width: 1088 , height: 1922
[00007fddfc001268] core vout display error: Failed to change zoom
[00007fddfc001268] core vout display error: Failed to set on top
[00007fddfc001268] core vout display error: Failed to change source AR
[h264 @ 0x7fde1c06cea0] error while decoding MB 24 111, bytestream -15
[swscaler @ 0x7fddfc002ca0] bad dst image pointers
[swscaler @ 0x7fddfc002ca0] bad dst image pointers
我的猜测是缓冲区及其大小存在问题。在哪里、使用哪种类型和多大的缓冲区来逐帧获取视频?稍后我计划将帧数据转发给 QImage。下面是 Player.h 文件:
const int ResoHeight = 1922;
const int ResoWidth = 1088;
const int BytesPerPixel = 3; // not sure about this
struct ImageData
{
QVector<unsigned char> raw;
QVector<unsigned char> picture;
ImageData()
{
raw.resize(BytesPerPixel * ResoHeight * ResoWidth);
picture.resize(BytesPerPixel * ResoHeight * ResoWidth);
}
};
class Player : public QObject
{
Q_OBJECT
public:
explicit Player(QObject *parent = nullptr);
~Player();
void play(const std::string& path);
signals:
void newImage(const QImage& image);
private:
libvlc_instance_t* vlcInstance;
libvlc_media_player_t* player;
libvlc_media_t* media;
ImageData buffer;
};
播放器.cpp如下:
namespace {
void* lock_frame(void *opaque, void **planes)
{
ImageData* buf = (ImageData*)(opaque);
*planes = buf->raw.data();
return buf->picture.data();
}
void unlock_frame(void *opaque, void *picture, void *const *planes)
{
// will be logic to announce new image
}
unsigned format_callback(void** opaque, char* chroma, unsigned *width, unsigned *height, unsigned *pitches, unsigned *lines)
{
qDebug() << "chroma:" << QString(chroma) << "width:" << *width << ", height:" << *height;
*pitches= (*width) * BytesPerPixel;
*lines= *height;
return 1;
}
} // namespace
Player::Player(QObject* parent)
: QObject(parent)
, vlcInstance(libvlc_new(0, nullptr))
, player(libvlc_media_player_new(vlcInstance))
, media(nullptr)
{
}
Player::~Player()
{
libvlc_media_player_stop(player);
libvlc_media_player_release(player);
libvlc_release(vlcInstance);
}
void Player::play(const std::string& path)
{
media = libvlc_media_new_location(vlcInstance, path.c_str());
libvlc_media_player_set_media(player, media);
libvlc_media_release(media);
libvlc_video_set_callbacks(player, lock_frame, unlock_frame, nullptr, &buffer);
libvlc_video_set_format_callbacks(player, format_callback, nullptr);
libvlc_media_player_play(player);
}
J420色度是一种平面YUV格式。这意味着您必须在format_callback
中提供三维pitches
和lines
,并在lock_frame
函数中提供 3 个不同的planes
指针(针对每个平面(。如果您只需要RGB(RV24(图像,请参阅此问题。
相关文章:
- 如何在c++中录制具有精确帧时间戳的视频
- 如何在QT中的自定义视频小工具t上绘制矩形
- 如何使用OpenCV-C++编写*.mp4视频?
- 开放 CV 中的动态内存分配,用于视频处理
- 错误:(-210:不支持的格式或格式组合)功能'create'中的硬件视频解码器不支持视频源
- OpenCV QT,显示视频的帧(不使用while循环)
- FFmpeg——使用硬件加速进行视频解码
- 在 openCV 中手动停止视频
- 强制Qt相机视频格式
- 在macOS Mojave上尝试OpenCV视频捕获时"Abort Trap: 6"
- 应用程序在打开的简历中捕获视频后没有响应
- 使用源读取器从网络摄像头源获取 H264 样本
- 使用 IMFSinkWriter 编码的视频的播放速度会根据宽度而变化
- 如何在 c++ 中通过 http 发送大型视频文件?
- 在 QLabel 中显示视频
- OpenGL 调试上下文警告 -"将使用视频内存作为缓冲区异议的来源
- 寻求使用 FFmpeg 在 mp4 容器中 h264 编解码器的视频帧.数据包 pts 始终为 0
- 使用 Live555 从连接到 H264 编码器的 IP 摄像机流式传输实时视频
- H264视频中的编码图像被跳过和/或丢失
- 视频编解码器的H264与opencv