SHA256
Fix FFmpegNativeDecoder to Consider Color Range When Decoding Video
This commit is contained in:
3 files changed
+420
-10
No files matched your search
@@ -60,6 +60,9 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
/// <summary>비디오 원본 코덱의 픽셀 포맷.</summary>
|
||||
public AVPixelFormat PixelFormat => _pCodecContext != null ? _pCodecContext->pix_fmt : AVPixelFormat.AV_PIX_FMT_NONE;
|
||||
|
||||
/// <summary>비디오 원본 코덱의 색상 범위.</summary>
|
||||
public AVColorRange ColorRange => _pCodecContext != null ? _pCodecContext->color_range : AVColorRange.AVCOL_RANGE_UNSPECIFIED;
|
||||
|
||||
public FFmpegNativeDecoder(string videoPath)
|
||||
{
|
||||
Open(videoPath);
|
||||
@@ -255,7 +258,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
/// <param name="vflip">Unity 텍스처 시스템에 맞게 상하 flip을 적용할지 여부</param>
|
||||
/// <param name="timestamp">출력된 프레임의 타임스탬프 (초)</param>
|
||||
/// <returns>프레임을 성공적으로 디코딩하여 복사했으면 true, 재생이 끝났거나 실패했으면 false</returns>
|
||||
public bool TryReadFrame(byte* outBuffer, int outStride, bool vflip, out double timestamp)
|
||||
private bool TryReadFrame(byte* outBuffer, int outStride, bool vflip, out double timestamp)
|
||||
{
|
||||
timestamp = 0;
|
||||
lock (_lock)
|
||||
@@ -362,7 +365,8 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
/// 비디오 원본이 YUV420p 계열(YUV420P, YUVJ420P)이면 CPU 컬러 변환(sws_scale)을 우회하고 메모리를 다이렉트로 복사하여 속도가 매우 빠릅니다.
|
||||
/// 그 외 포맷일 경우 자동으로 YUV420p로 변환 후 복사합니다.
|
||||
/// </summary>
|
||||
public bool TryReadYUV420PFrame(
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private bool TryReadYUV420PFrame(
|
||||
byte* yBuffer, int yStride,
|
||||
byte* uBuffer, int uStride,
|
||||
byte* vBuffer, int vStride,
|
||||
@@ -373,7 +377,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
{
|
||||
if (!_isOpened || _disposed) return false;
|
||||
|
||||
AVFrame* frame = null;
|
||||
AVFrame* frame;
|
||||
|
||||
if (_hasCachedFrame)
|
||||
{
|
||||
@@ -477,6 +481,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public bool TryReadYUV420PFrame(
|
||||
NativeArray<byte> yBuffer,
|
||||
NativeArray<byte> uBuffer,
|
||||
@@ -506,7 +511,8 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
/// 비디오 원본이 NV12 계열이면 CPU 컬러 변환(sws_scale)을 우회하고 메모리를 다이렉트로 복사하여 속도가 매우 빠릅니다.
|
||||
/// 그 외 포맷일 경우 자동으로 NV12로 변환 후 복사합니다.
|
||||
/// </summary>
|
||||
public bool TryReadNV12Frame(
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private bool TryReadNV12Frame(
|
||||
byte* yBuffer, int yStride,
|
||||
byte* uvBuffer, int uvStride,
|
||||
out double timestamp)
|
||||
@@ -516,7 +522,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
{
|
||||
if (!_isOpened || _disposed) return false;
|
||||
|
||||
AVFrame* frame = null;
|
||||
AVFrame* frame;
|
||||
|
||||
if (_hasCachedFrame)
|
||||
{
|
||||
@@ -607,6 +613,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public bool TryReadNV12Frame(
|
||||
NativeArray<byte> yBuffer,
|
||||
NativeArray<byte> uvBuffer,
|
||||
@@ -633,12 +640,12 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
/// </summary>
|
||||
/// <param name="count">버릴 프레임 개수</param>
|
||||
/// <returns>실제로 건너뛴 프레임 개수</returns>
|
||||
public int SkipFrames(int count)
|
||||
private void SkipFrames(int count)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_isOpened || _disposed) return 0;
|
||||
if (count <= 0) return 0;
|
||||
if (!_isOpened || _disposed) return;
|
||||
if (count <= 0) return;
|
||||
|
||||
int skipped = 0;
|
||||
if (_hasCachedFrame)
|
||||
@@ -678,7 +685,6 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
throw new Exception($"프레임 건너뛰기 중 오류 발생: {GetFFmpegErrorString(ret)}");
|
||||
}
|
||||
}
|
||||
return skipped;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +702,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
||||
double targetFrameIndex = timeSeconds * FPS;
|
||||
|
||||
// 이미 해당 인덱스이고 매우 인접한 미래라면 seek 대신 skip 처리 (I-프레임 찾기 오버헤드 방지)
|
||||
bool useSkip = targetFrameIndex >= _currentFrameIndex && (targetFrameIndex - _currentFrameIndex) < 60;
|
||||
bool useSkip = targetFrameIndex >= _currentFrameIndex && targetFrameIndex - _currentFrameIndex < 60;
|
||||
if (useSkip)
|
||||
{
|
||||
SkipFrames((int)(targetFrameIndex - _currentFrameIndex));
|
||||
|
||||
Reference in new issue
Block a user