私はlibvlcライブラリを使用してh264ストリームからビデオフレームを取得するソリューションを開発することに興味があります。私はlibvlc_video_set_format_callbacks
にコールバックを設定して、私のコールバック関数(format_callback
)パラメータから、以下の情報を受け取っている:クロマ:「J420」、幅:1088、高さ:1922正しくlibvlc(C++)を使ってh264ビデオストリームからフレームを取得するには?
私はそれをプリント
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に転送する予定です。
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;
};
Player.cppは以下の通りです::以下はPlayer.hファイルがある
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);
}
'バッファ'は初期化されていません。 format_callback関数で初期化する必要があります。 – seleciii44
'buffer'はImageDataの型であり、そのコンストラクタで初期化されます。もちろん、 'format_callback'関数で初期化するのは正しいでしょうが、それが問題の原因であってはいけません。バッファのサイズ変更メソッドを 'format_callback'に移動して試しました。同じエラー。申し訳ありませんが、それを認識していませんでした。 – psalong
J420クロマは、平面YUV形式のhttps://wiki.videolan.org/YUV/です。つまり、lock_frameに3つのイメージポインタを指定する必要があります。 RGB(RV24)画像が必要な場合は、この質問をご覧くださいhttps://stackoverflow.com/q/40365353/1632887 – seleciii44