|
|
|
|
@ -180,9 +180,22 @@ void Worker::run() {
|
|
|
|
|
frame = av_frame_alloc(); |
|
|
|
|
pkt = av_packet_alloc(); |
|
|
|
|
if (!frame || !pkt) { worker_fail(this, "alloc failed"); cleanup(); return; } |
|
|
|
|
sws = sws_getContext(vw, vh, vdec->pix_fmt, vw, vh, AV_PIX_FMT_RGB24, |
|
|
|
|
/* YUVJ* (deprecated full-range) → обычный формат + явный range, чтобы
|
|
|
|
|
* не ловить warning swscaler и не искажать цвета */ |
|
|
|
|
AVPixelFormat srcFmt = vdec->pix_fmt; |
|
|
|
|
int srcRange = 0; |
|
|
|
|
switch (srcFmt) { |
|
|
|
|
case AV_PIX_FMT_YUVJ420P: srcFmt = AV_PIX_FMT_YUV420P; srcRange = 1; break; |
|
|
|
|
case AV_PIX_FMT_YUVJ422P: srcFmt = AV_PIX_FMT_YUV422P; srcRange = 1; break; |
|
|
|
|
case AV_PIX_FMT_YUVJ444P: srcFmt = AV_PIX_FMT_YUV444P; srcRange = 1; break; |
|
|
|
|
default: break; |
|
|
|
|
} |
|
|
|
|
sws = sws_getContext(vw, vh, srcFmt, vw, vh, AV_PIX_FMT_RGB24, |
|
|
|
|
SWS_BILINEAR, nullptr, nullptr, nullptr); |
|
|
|
|
if (!sws) { worker_fail(this, "sws init failed"); cleanup(); return; } |
|
|
|
|
int *invTbl = nullptr, *tbl = nullptr, sr = 0, dr = 0, br = 0, ct = 0, st = 0; |
|
|
|
|
if (sws_getColorspaceDetails(sws, &invTbl, &sr, &tbl, &dr, &br, &ct, &st) >= 0) |
|
|
|
|
sws_setColorspaceDetails(sws, invTbl, srcRange, tbl, 1 /* RGB full-range */, br, ct, st); |
|
|
|
|
|
|
|
|
|
int gen = epoch->loadRelaxed(); |
|
|
|
|
auto emitFrame = [&](AVFrame* fr) { |
|
|
|
|
@ -248,7 +261,7 @@ void Worker::run() {
|
|
|
|
|
|
|
|
|
|
VideoPlayerEngine::VideoPlayerEngine(QObject* parent) : QObject(parent) { |
|
|
|
|
qRegisterMetaType<QImage>("QImage"); |
|
|
|
|
qRegisterMetaType<std::shared_ptr<std::vector<int16_t>>>("SharedPcmPtr"); |
|
|
|
|
qRegisterMetaType<std::shared_ptr<std::vector<int16_t>>>(); |
|
|
|
|
m_presentTimer.setInterval(16); |
|
|
|
|
connect(&m_presentTimer, &QTimer::timeout, this, &VideoPlayerEngine::presentTick); |
|
|
|
|
} |
|
|
|
|
|