2

Nvidia の npp ライブラリを使用して、3 チャネル パックされた rgb のフレームを nv12 に変換しようとしています。これが私がこれまでに持っているコードです:

//cpu buffer that will hold converted data
Npp8u* converted_data = (Npp8u*)malloc(frameToWrite.getWidth());
memset(converted_data, 0, frameToWrite.getSize());

//Begin - load data and convert rgb to yuv
{
    NppStatus ret = NPP_SUCCESS;
    int stepSource;
    Npp8u* frame = nppiMalloc_8u_C3(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepSource);
    cudaMemcpy2D(frame, stepSource, frameToWrite.getFrame(), frameToWrite.getSizePerRow(), frameToWrite.getWidth(), frameToWrite.getHeight(), cudaMemcpyHostToDevice);

    int stepDestP1, stepDestP2, stepDestP3;
    Npp8u* m_stYuvP1 = nppiMalloc_8u_C1(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepDestP1);
    Npp8u* m_stYuvP2 = nppiMalloc_8u_C1(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepDestP2);
            Npp8u* m_stYuvP3 = nppiMalloc_8u_C1(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepDestP3);
    int d_steps[3] = { stepDestP1, stepDestP2, stepDestP3 };
    Npp8u* d_ptrs[3] = { m_stYuvP1, m_stYuvP2, m_stYuvP3 };

    NppiSize ROI = { frameToWrite.getWidth(), frameToWrite.getHeight() };

    if ((ret = nppiRGBToYUV_8u_C3P3R(frame, stepSource, d_ptrs, stepDestP1, ROI)) != NPP_SUCCESS)
        return ERROR_CODE_NVENC_ERROR_UNKNOWN;

    cudaMemcpy2D(converted_data, frameToWrite.getWidth(), m_stYuvP1, stepDestP1, frameToWrite.getWidth(), frameToWrite.getHeight(), cudaMemcpyDeviceToHost);
}

主にこのスタックオーバーフローの質問に基づいていますが、ケースに合わせて調整しました。補足として、次のframeToWrite.getSize()ように計算されます。

mFrameSize = ((getBytesPerPixel() * mWidth) + mPaddingInBytes) * mHeight;

getBytesPerPixel()通常は を返します3

最終的に私の質問は次のとおりです。

  • 変換された画像データをデバイスのメモリから取得するにはどうすればよいですか?
  • 変換前の画像データを正しい方法でデバイスに渡しましたか?
4

1 に答える 1

0
Npp8u* converted_data = (Npp8u*)malloc(frameToWrite.getWidth());
memset(converted_data, 0, frameToWrite.getSize());

まず第一に、まだ気づいていないのであれば、おそらくここではほとんどメモリを割り当てておらず、さらに大きな領域で memset を使用しているため、望ましくない動作が発生する可能性があります。

あなたの質問について:
何をして何frameToWrite.getWidth()frameToWrite.getHeight()返すかを言うのは難しいです-それは画像次元ですか、それともバイト次元ですか?一般に、NPP バッファーを割り当てるときは、次のようなバイト次元を使用する必要があります。
nppiMalloc_8u_C1(pixelWidth*bytesPerPixel, pixelHeight, &stepSource);
さらに、ステップ サイズは、NPP ドキュメント ポイント 4.2.1 に従って、バイト単位の行の長さとパディングに等しい必要があります。
メモリから画像を取得する場合、私の個人的な経験から、cudaMemcpy元のデータがまだ整列している間、npp は仮想分割のみで 2D メモリを割り当てるため、単純に使用するのが最も簡単な方法cudaMemcpyです。

于 2015-07-29T07:33:04.150 に答える