Allocate padded RGB frames for FFmpeg video conversion
This commit is contained in:
1 parent
88e3e27145
commit
f81b93ad0d
3 files changed
+39
-4
No files matched your search
@@ -1,4 +1,5 @@
|
||||
#include "call_video_decoder.h"
|
||||
#include "video_frame_image.h"
|
||||
#include "debug_config.h"
|
||||
#include "../../../src/call/call_video_bitstream.h"
|
||||
#include <QTransform>
|
||||
@@ -88,7 +89,7 @@ bool CallVideoDecoder::decode(const call_video_frame& f, QImage& image) {
|
||||
valid = valid && (m->codec->profile == profile || (f.format.codec == CALL_VIDEO_H264
|
||||
&& f.format.profile == CALL_VIDEO_BASELINE && m->codec->profile == AV_PROFILE_H264_BASELINE));
|
||||
if (valid) {
|
||||
QImage output(decoded->width, decoded->height, QImage::Format_RGB888);
|
||||
QImage output = video_frame_image(decoded->width, decoded->height);
|
||||
m->scale = sws_getCachedContext(m->scale, decoded->width, decoded->height, AV_PIX_FMT_YUV420P,
|
||||
decoded->width, decoded->height, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
|
||||
if (!m->scale || output.isNull()) valid = false;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "streamplayer_window.h"
|
||||
#include "videoplayer_window.h"
|
||||
#include "video_frame_image.h"
|
||||
#include "sound_manager.h"
|
||||
#include "../transport/stream_bridge.h"
|
||||
#include <QVBoxLayout>
|
||||
@@ -178,8 +179,8 @@ void StreamPlayerWindow::tick() {
|
||||
}
|
||||
if (!image.isNull()) {
|
||||
m_render->setFrame(image); m_status->setText(text("Live"));
|
||||
if (first) DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop first frame id=%llu %dx%d", (unsigned long long)p.id,
|
||||
image.width(), image.height());
|
||||
if (first) DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop first frame id=%llu %dx%d RGB_stride=%lld",
|
||||
(unsigned long long)p.id, image.width(), image.height(), (long long)image.bytesPerLine());
|
||||
emit framePresented();
|
||||
}
|
||||
if (finished) { m_status->setText(text("Stream ended")); m_audio.close(); m_timer.stop(); }
|
||||
@@ -284,7 +285,7 @@ void StreamPlayerWindow::decode() {
|
||||
if (pts < p.clock(nowUs()) - 100000) { discarded++; continue; } }
|
||||
converter = sws_getCachedContext(converter, frame->width, frame->height, (AVPixelFormat)frame->format,
|
||||
frame->width, frame->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr);
|
||||
QImage image(frame->width, frame->height, QImage::Format_RGB888);
|
||||
QImage image = video_frame_image(frame->width, frame->height);
|
||||
if (!converter || image.isNull()) { fail(text("Stream video conversion failed")); p.running = false; return; }
|
||||
uint8_t* destination[] = {image.bits(), nullptr, nullptr, nullptr};
|
||||
int strides[] = {(int)image.bytesPerLine(), 0, 0, 0};
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/* RGB888 для sws_scale: FFmpeg выделяет выровненные строки и запас для SIMD.
|
||||
* QImage разделяет буфер без копирования; последний владелец освобождает AVFrame. */
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_FFMPEG
|
||||
#include <QImage>
|
||||
#include "debug_config.h"
|
||||
extern "C" {
|
||||
#include <libavutil/frame.h>
|
||||
}
|
||||
|
||||
inline QImage video_frame_image(int width, int height) {
|
||||
AVFrame* frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "video RGB frame allocation failed size=%dx%d", width, height); return {};
|
||||
}
|
||||
frame->format = AV_PIX_FMT_RGB24; frame->width = width; frame->height = height;
|
||||
int result = av_frame_get_buffer(frame, 32);
|
||||
if (result < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "video RGB buffer allocation failed size=%dx%d result=%d", width, height, result);
|
||||
av_frame_free(&frame); return {};
|
||||
}
|
||||
QImage image(frame->data[0], width, height, frame->linesize[0], QImage::Format_RGB888, [](void* owner) {
|
||||
auto* frame = static_cast<AVFrame*>(owner); av_frame_free(&frame);
|
||||
}, frame);
|
||||
if (image.isNull()) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "video RGB image initialization failed size=%dx%d stride=%d", width, height, frame->linesize[0]);
|
||||
av_frame_free(&frame); return {};
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_VIDEO, "video RGB buffer allocated size=%dx%d stride=%d alignment=32", width, height, frame->linesize[0]);
|
||||
return image;
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user