参ったぁ でっかいでっかい IMAGを FFMPEGで encorde するの遅い
日本語で説明してるけど もし英語の説明ほしいなら メッセージください。
I'm explaining in Japanese, but if you would like an explanation in English, please send me a message.
おおおおおおおおお 豪快に遅い
マルチスレッドだ
現場で ノイズ対策してたおっちゃんの僕には 結構きついしごとだ。
わけわかんねぇ スレッドセーフでないとこまるので独立したポインタに
ものを置いて くるくるまわすしかない。
void QtPixeMpegStreamer::encodeFrame(QList<QPixmap*> updatedPixmapsSubset)
{
if (av_frame_make_writable(frame) < 0) {
throw std::runtime_error("Frame not writable");
}
std::vector<std::thread*> threads(updatedPixmapsSubset.size());
for (int thread_id = 0; thread_id <updatedPixmapsSubset.size(); thread_id++)
{
threads[thread_id] =new std::thread([this, thread_id,updatedPixmapsSubset]()
{
QImage image;// 元のQPixmapのサイズをチェック
QPixmap *pixmap=updatedPixmapsSubset.at(thread_id);
QSize originalSize = pixmap->size();
if (originalSize.width() != c->width || originalSize.height() != c->height) // サイズが異なる場合のみスケーリング
{image = pixmap->toImage().convertToFormat(QImage::Format_RGB32).scaled(c->width, c->height, Qt::IgnoreAspectRatio);}
else {image = pixmap->toImage().convertToFormat(QImage::Format_RGB32);}// サイズが同じ場合、変換なしでそのまま使用
AVFrame* localFrame = frames[thread_id];
QRgb rgb;
int r, g, b, yLuminance, u, v;
for (int y = 0; y < c->height; y++) {
for (int x = 0; x < c->width; x++) {
rgb = image.pixel(x, y);
r = qRed(rgb); g = qGreen(rgb); b = qBlue(rgb);
yLuminance = (0.257 * r) + (0.504 * g) + (0.098 * b) + 16;// Convert RGB to YUV
u = -(0.148 * r) - (0.291 * g) + (0.439 * b) + 128;
v = (0.439 * r) - (0.368 * g) - (0.071 * b) + 128;
localFrame->data[0][y * localFrame->linesize[0] + x] = (uint8_t)(yLuminance);// Assign to frame
if (x % 2 == 0 && y % 2 == 0) {
localFrame->data[1][y/2 * localFrame->linesize[1] + x/2] = (uint8_t)(u);
localFrame->data[2][y/2 * localFrame->linesize[2] + x/2] = (uint8_t)(v);
}
}
}
});
}
for (auto& t : threads) { t->join(); delete t; }
for (int i=0;i<updatedPixmapsSubset.size();i++)// エンコード処理
{
AVFrame* frame=frames[i];
frame->pts = frame_count++; // フレームのptsを設定
encode(frame); // フレームをエンコード
}
}