Skip to content

Commit

Permalink
[Encode] Fix AVC unaligned padding issue
Browse files Browse the repository at this point in the history
add fill_pad_with_value function for softlet path and legacy path of AVC
  • Loading branch information
SenlinGe authored and intel-mediadev committed Jul 8, 2024
1 parent b3e54f0 commit 3fc5823
Show file tree
Hide file tree
Showing 12 changed files with 730 additions and 0 deletions.
134 changes: 134 additions & 0 deletions media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3533,6 +3533,139 @@ MOS_STATUS CodechalEncodeAvcBase::StoreNumPasses(
return MOS_STATUS_SUCCESS;
}

void CodechalEncodeAvcBase::fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height)
{
CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(psSurface);

// unaligned surfaces only
if (aligned_height <= real_height || aligned_height > psSurface->dwHeight)
{
return;
}

if (psSurface->OsResource.TileType == MOS_TILE_INVALID)
{
return;
}

if (psSurface->Format == Format_NV12 || psSurface->Format == Format_P010)
{
uint32_t pitch = psSurface->dwPitch;
uint32_t UVPlaneOffset = psSurface->UPlaneOffset.iSurfaceOffset;
uint32_t YPlaneOffset = psSurface->dwOffset;
uint32_t pad_rows = aligned_height - real_height;
uint32_t y_plane_size = pitch * real_height;
uint32_t uv_plane_size = pitch * real_height / 2;

MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;

// padding for the linear format buffer.
if (psSurface->OsResource.TileType == MOS_TILE_LINEAR)
{
uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(src_data);

uint8_t *src_data_y = src_data + YPlaneOffset;
uint8_t *src_data_y_end = src_data_y + y_plane_size;
for (uint32_t i = 0; i < pad_rows; i++)
{
MOS_SecureMemcpy(src_data_y_end + i * pitch, pitch, src_data_y_end - pitch, pitch);
}

uint8_t *src_data_uv = src_data + UVPlaneOffset;
uint8_t *src_data_uv_end = src_data_uv + uv_plane_size;
for (uint32_t i = 0; i < pad_rows / 2; i++)
{
MOS_SecureMemcpy(src_data_uv_end + i * pitch, pitch, src_data_uv_end - pitch, pitch);
}

m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
}
else
{
// we don't copy out the whole tiled buffer to linear and padding on the tiled buffer directly.
lockFlags.TiledAsTiled = 1;

uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(src_data);

uint8_t *padding_data = (uint8_t *)MOS_AllocMemory(pitch * pad_rows);
CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(padding_data);

// Copy last Y row data to linear padding data.
GMM_RES_COPY_BLT gmmResCopyBlt = {0};
gmmResCopyBlt.Gpu.pData = src_data;
gmmResCopyBlt.Gpu.OffsetX = 0;
gmmResCopyBlt.Gpu.OffsetY = (YPlaneOffset + y_plane_size - pitch) / pitch;
gmmResCopyBlt.Sys.pData = padding_data;
gmmResCopyBlt.Sys.RowPitch = pitch;
gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
gmmResCopyBlt.Sys.SlicePitch = pitch;
gmmResCopyBlt.Blt.Slices = 1;
gmmResCopyBlt.Blt.Upload = false;
gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
gmmResCopyBlt.Blt.Height = 1;
psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
// Fill the remain padding lines with last Y row data.
for (uint32_t i = 1; i < pad_rows; i++)
{
MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
}
// Filling the padding for Y.
gmmResCopyBlt.Gpu.pData = src_data;
gmmResCopyBlt.Gpu.OffsetX = 0;
gmmResCopyBlt.Gpu.OffsetY = (YPlaneOffset + y_plane_size) / pitch;
gmmResCopyBlt.Sys.pData = padding_data;
gmmResCopyBlt.Sys.RowPitch = pitch;
gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
gmmResCopyBlt.Sys.SlicePitch = pitch;
gmmResCopyBlt.Blt.Slices = 1;
gmmResCopyBlt.Blt.Upload = true;
gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
gmmResCopyBlt.Blt.Height = pad_rows;
psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);

// Copy last UV row data to linear padding data.
gmmResCopyBlt.Gpu.pData = src_data;
gmmResCopyBlt.Gpu.OffsetX = 0;
gmmResCopyBlt.Gpu.OffsetY = (UVPlaneOffset + uv_plane_size - pitch) / pitch;
gmmResCopyBlt.Sys.pData = padding_data;
gmmResCopyBlt.Sys.RowPitch = pitch;
gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
gmmResCopyBlt.Sys.SlicePitch = pitch;
gmmResCopyBlt.Blt.Slices = 1;
gmmResCopyBlt.Blt.Upload = false;
gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
gmmResCopyBlt.Blt.Height = 1;
psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
// Fill the remain padding lines with last UV row data.
for (uint32_t i = 1; i < pad_rows / 2; i++)
{
MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
}
// Filling the padding for UV.
gmmResCopyBlt.Gpu.pData = src_data;
gmmResCopyBlt.Gpu.OffsetX = 0;
gmmResCopyBlt.Gpu.OffsetY = (UVPlaneOffset + uv_plane_size) / pitch;
gmmResCopyBlt.Sys.pData = padding_data;
gmmResCopyBlt.Sys.RowPitch = pitch;
gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
gmmResCopyBlt.Sys.SlicePitch = pitch;
gmmResCopyBlt.Blt.Slices = 1;
gmmResCopyBlt.Blt.Upload = true;
gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
gmmResCopyBlt.Blt.Height = pad_rows / 2;
psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);

MOS_FreeMemory(padding_data);
padding_data = nullptr;
m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
}
}
}

#if USE_CODECHAL_DEBUG_TOOL
static MOS_STATUS DumpEncodePicReorder(
std::ostringstream &oss,
Expand Down Expand Up @@ -3926,6 +4059,7 @@ MOS_STATUS CodechalEncodeAvcBase::DumpPicParams(
return MOS_STATUS_SUCCESS;
}


MOS_STATUS CodechalEncodeAvcBase::DumpFeiPicParams(
CodecEncodeAvcFeiPicParams *feiPicParams)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1921,5 +1921,7 @@ class CodechalEncodeAvcBase : public CodechalEncoderState
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS SetFrameStoreIds(uint8_t frameIdx);

void fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height);
};
#endif // __CODECHAL_ENCODE_AVC_BASE_H__
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,8 @@ class CodechalEncoderState : public Codechal
uint32_t m_frameHeight = 0; //!< Frame height in luma samples
uint32_t m_frameFieldHeight = 0; //!< Frame height in luma samples
uint32_t m_oriFrameHeight = 0; //!< Original frame height
uint16_t m_frame_crop_bottom_offset = 0; //!< frame_crop_bottom_offset
uint16_t m_frame_mbs_only_flag = 0; //!< frame_mbs_only_flag
uint32_t m_oriFrameWidth = 0; //!< Original frame width
uint32_t m_createWidth = 0; //!< Max Frame Width for resolution reset
uint32_t m_createHeight = 0; //!< Max Frame Height for resolution reset
Expand Down
Loading

0 comments on commit 3fc5823

Please sign in to comment.