続・基礎MPEG 遅encorde FFMPEGでImageを MPEGにするのつづき  | Qt5、KiCadとモジュールで遊ぶ電子工作の初心

Qt5、KiCadとモジュールで遊ぶ電子工作の初心

このブログでは、Qt5とKiCadを用いた電子工作に焦点を当て、Linux上でのプロジェクト開発を探究します。初心者にも分かりやすい基板設計の指南や、多様なモジュールの活用法を紹介。Qt5のGUIを駆使したインタラクティブな制作過程を体験できます。

参ったぁ  でっかいでっかい 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);               // フレームをエンコード
        }

}