1

SDL_Overlay(SDL 1.2.5)を使用して、圧縮されていない YUV 4:2:0 平面ビデオ データの特定のソースを再生するときに、問題と戦ってきました。

たとえば、640x480のビデオを問題なく再生できます。しかし、解像度854x480でビデオを再生しようとしたところ、奇妙な効果が得られました。ラインのラップが 1 ~ 2 ピクセル遅くなり (せん断のような変換が発生)、クロマが消えて、各ラインで R、G、または B が交互に置き換えられます。このスクリーンショットを参照してください

YUV データ自体は正しいので、ファイルに保存して別のプレーヤーで再生できます。この時点ではパディングされません。ピッチは行の長さと一致します。

私の疑いでは、解像度が 4 の倍数でない場合に何らかの問題が発生する可能性があります。おそらく、クロマ解像度が 2 の倍数であるとSDL_Surface予想されますか?SDL_Overlay

私の疑いに加えて、私が854*480SDL_Surfaceのサイズで作成した RGBのピッチは2564であり、私が期待する3*854 = 2562ではありません。

の幅に 1 または 2 ピクセルを追加するとSDL_Surface(ただし、オーバーレイと四角形は同じままにする)、右側に黒い境界線がありますが、正常に動作します。もちろん、これは 4 の倍数のビデオでは壊れます。

設定

screen = SDL_SetVideoMode(width, height, 24, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_ASYNCBLIT);
if ( screen == NULL ) {
  return 0;
}
YUVOverlay = SDL_CreateYUVOverlay(width, height, SDL_IYUV_OVERLAY, screen);
Ydata = new unsigned char[luma_size];
Udata = new unsigned char[chroma_size];
Vdata = new unsigned char[chroma_size];

YUVOverlay->pixels[0] = Ydata;
YUVOverlay->pixels[1] = Udata;
YUVOverlay->pixels[2] = Vdata;

SDL_DisplayYUVOverlay(YUVOverlay, dest);

レンダリング ループ:

SDL_LockYUVOverlay(YUVOverlay);
memcpy(Ydata, buffer, luma_size);
memcpy(Udata, buffer+luma_size, chroma_size);
memcpy(Vdata, buffer+luma_size+chroma_size, chroma_size);
int i = SDL_DisplayYUVOverlay(YUVOverlay, dest);
SDL_UnlockYUVOverlay(YUVOverlay);

私にとって最も簡単な修正はSDL_Surface、各次元で 4 の倍数になるように RGB サイズを大きくすることです。しかし、これにより黒い境界線が追加されます。

この問題を修正する正しい方法はありますか? YUV データでパディングを試してみるべきですか?

4

1 に答える 1

1

入力データの各プレーンは、8 で割り切れるアドレスで開始する必要があり、各行のストライドは 8 で割り切れる必要があります。明確にするために、クロマ プレーンもこれに従う必要があります。

この要件は、SDL ライブラリが x86 CPU で MMX マルチメディア命令を使用しているためと思われます。ディストリビューションの src/video/SDL_yuv_mmx.c のコメントを参照してください。

更新: 実際のアセンブリ コードを調べたところ、ソース コードのコメントに記載されていない追加の仮定があります。これは SDL 1.2.14 用です。上記のモジュロ 8 の仮定に加えて、コードは、入力輝度プレーンと入力クロマ プレーンの両方が完全にパックされている (つまり、幅 == ストライド) と仮定しています。

于 2013-03-23T16:41:58.630 に答える