Add support for memory pool management for vaapi surfaces and vaapi-hip interops (#17)

* Add support for memory pool management for vaapi surfaces

* reuse memories for each channel if the sizes remain unchanged

* rename hip_interop to hip_interop_dev_mem
This commit is contained in:
Aryan Salmanpour
2024-04-22 14:37:45 -04:00
committed by GitHub
orang tua 6aaca70cd9
melakukan 694a4bc07f
5 mengubah file dengan 324 tambahan dan 220 penghapusan
+22 -12
Melihat File
@@ -302,6 +302,7 @@ int main(int argc, char **argv) {
uint32_t widths[ROCJPEG_MAX_COMPONENT] = {};
uint32_t heights[ROCJPEG_MAX_COMPONENT] = {};
uint32_t channel_sizes[ROCJPEG_MAX_COMPONENT] = {};
uint32_t prior_channel_sizes[ROCJPEG_MAX_COMPONENT] = {};
uint32_t num_channels = 0;
int total_images = 0;
double time_per_image_all = 0;
@@ -459,9 +460,16 @@ int main(int argc, char **argv) {
std::cout << "Unknown output format!" << std::endl;
return EXIT_FAILURE;
}
// allocate memory for each channel
// allocate memory for each channel and reuse them if the sizes remain unchanged for a new image.
for (int i = 0; i < num_channels; i++) {
CHECK_HIP(hipMalloc(&output_image.channel[i], channel_sizes[i]));
if (prior_channel_sizes[i] != channel_sizes[i]) {
if (output_image.channel[i] != nullptr) {
CHECK_HIP(hipFree((void *)output_image.channel[i]));
output_image.channel[i] = nullptr;
}
CHECK_HIP(hipMalloc(&output_image.channel[i], channel_sizes[i]));
}
}
std::cout << "info: decoding started, please wait! ... " << std::endl;
@@ -503,14 +511,6 @@ int main(int argc, char **argv) {
SaveImage(image_save_path, &output_image, widths[0], heights[0], subsampling, output_format);
}
for (int i = 0; i < num_channels; i++) {
if (output_image.channel[i] != nullptr) {
CHECK_HIP(hipFree((void*)output_image.channel[i]));
output_image.channel[i] = nullptr;
output_image.pitch[i] = 0;
}
}
std::cout << "info: average processing time per image (ms): " << time_per_image_in_milli_sec << std::endl;
std::cout << "info: average images per sec: " << 1000 / time_per_image_in_milli_sec << std::endl;
@@ -521,6 +521,16 @@ int main(int argc, char **argv) {
mpixels_all += image_size_in_mpixels;
}
counter++;
for (int i = 0; i < ROCJPEG_MAX_COMPONENT; i++) {
prior_channel_sizes[i] = channel_sizes[i];
}
}
for (int i = 0; i < num_channels; i++) {
if (output_image.channel[i] != nullptr) {
CHECK_HIP(hipFree((void *)output_image.channel[i]));
output_image.channel[i] = nullptr;
}
}
if (is_dir) {
@@ -530,8 +540,8 @@ int main(int argc, char **argv) {
std::cout << "info: total decoded images: " << total_images << std::endl;
if (total_images) {
std::cout << "info: average processing time per image (ms): " << time_per_image_all << std::endl;
std::cout << "info: average decoded images per sec: " << images_per_sec << std::endl;
std::cout << "info: average decoded image_size_in_mpixels per sec: " << mpixels_per_sec << std::endl;
std::cout << "info: average decoded images per sec (Images/Sec): " << images_per_sec << std::endl;
std::cout << "info: average decoded images size (Mpixels/Sec): " << mpixels_per_sec << std::endl;
}
std::cout << std::endl;
}
+51 -96
Melihat File
@@ -23,7 +23,7 @@ THE SOFTWARE.
#include "rocjpeg_decoder.h"
ROCJpegDecoder::ROCJpegDecoder(RocJpegBackend backend, int device_id) :
num_devices_{0}, device_id_ {device_id}, hip_stream_ {0}, backend_{backend}, hip_interop_{} {}
num_devices_{0}, device_id_ {device_id}, hip_stream_ {0}, backend_{backend} {}
ROCJpegDecoder::~ROCJpegDecoder() {
if (hip_stream_) {
@@ -81,43 +81,42 @@ RocJpegStatus ROCJpegDecoder::Decode(const uint8_t *data, size_t length, RocJpeg
CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecode(jpeg_stream_params, current_surface_id, output_format));
if (destination != nullptr) {
VADRMPRIMESurfaceDescriptor va_drm_prime_surface_desc = {};
HipInteropDeviceMem hip_interop_dev_mem = {};
CHECK_ROCJPEG(jpeg_vaapi_decoder_.SyncSurface(current_surface_id));
CHECK_ROCJPEG(jpeg_vaapi_decoder_.ExportSurface(current_surface_id, va_drm_prime_surface_desc));
CHECK_ROCJPEG(GetHipInteropMem(va_drm_prime_surface_desc));
CHECK_ROCJPEG(jpeg_vaapi_decoder_.GetHipInteropMem(current_surface_id, hip_interop_dev_mem));
uint16_t chroma_height = 0;
switch (output_format) {
case ROCJPEG_OUTPUT_NATIVE:
// Copy the native decoded output buffers from interop memory directly to the destination buffers
CHECK_ROCJPEG(GetChromaHeight(jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height));
CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height));
// Copy Luma (first channel) for any surface format
CHECK_ROCJPEG(CopyChannel(destination, jpeg_stream_params->picture_parameter_buffer.picture_height, 0));
if (hip_interop_.surface_format == VA_FOURCC_NV12) {
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_height, 0, destination));
if (hip_interop_dev_mem.surface_format == VA_FOURCC_NV12) {
// Copy the second channel (UV interleaved) for NV12
CHECK_ROCJPEG(CopyChannel(destination, chroma_height, 1));
} else if (hip_interop_.surface_format == VA_FOURCC_444P) {
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, destination));
} else if (hip_interop_dev_mem.surface_format == VA_FOURCC_444P) {
// Copy the second and third channels for YUV444
CHECK_ROCJPEG(CopyChannel(destination, chroma_height, 1));
CHECK_ROCJPEG(CopyChannel(destination, chroma_height, 2));
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, destination));
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, destination));
}
break;
case ROCJPEG_OUTPUT_YUV_PLANAR:
CHECK_ROCJPEG(GetChromaHeight(jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height));
CHECK_ROCJPEG(GetPlanarYUVOutputFormat(jpeg_stream_params->picture_parameter_buffer.picture_width,
CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height));
CHECK_ROCJPEG(GetPlanarYUVOutputFormat(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width,
jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height, destination));
break;
case ROCJPEG_OUTPUT_Y:
CHECK_ROCJPEG(GetYOutputFormat(jpeg_stream_params->picture_parameter_buffer.picture_width,
CHECK_ROCJPEG(GetYOutputFormat(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width,
jpeg_stream_params->picture_parameter_buffer.picture_height, destination));
break;
case ROCJPEG_OUTPUT_RGB:
CHECK_ROCJPEG(ColorConvertToRGB(jpeg_stream_params->picture_parameter_buffer.picture_width,
CHECK_ROCJPEG(ColorConvertToRGB(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width,
jpeg_stream_params->picture_parameter_buffer.picture_height, destination));
break;
case ROCJPEG_OUTPUT_RGB_PLANAR:
CHECK_ROCJPEG(ColorConvertToRGBPlanar(jpeg_stream_params->picture_parameter_buffer.picture_width,
CHECK_ROCJPEG(ColorConvertToRGBPlanar(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width,
jpeg_stream_params->picture_parameter_buffer.picture_height, destination));
break;
default:
@@ -125,8 +124,6 @@ RocJpegStatus ROCJpegDecoder::Decode(const uint8_t *data, size_t length, RocJpeg
}
CHECK_HIP(hipStreamSynchronize(hip_stream_));
CHECK_ROCJPEG(ReleaseHipInteropMem(current_surface_id));
}
return ROCJPEG_STATUS_SUCCESS;
@@ -188,63 +185,21 @@ RocJpegStatus ROCJpegDecoder::GetImageInfo(const uint8_t *data, size_t length, u
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::GetHipInteropMem(VADRMPRIMESurfaceDescriptor &va_drm_prime_surface_desc) {
hipExternalMemoryHandleDesc external_mem_handle_desc = {};
hipExternalMemoryBufferDesc external_mem_buffer_desc = {};
external_mem_handle_desc.type = hipExternalMemoryHandleTypeOpaqueFd;
external_mem_handle_desc.handle.fd = va_drm_prime_surface_desc.objects[0].fd;
external_mem_handle_desc.size = va_drm_prime_surface_desc.objects[0].size;
CHECK_HIP(hipImportExternalMemory(&hip_interop_.hip_ext_mem, &external_mem_handle_desc));
external_mem_buffer_desc.size = va_drm_prime_surface_desc.objects[0].size;
CHECK_HIP(hipExternalMemoryGetMappedBuffer((void**)&hip_interop_.hip_mapped_device_mem, hip_interop_.hip_ext_mem, &external_mem_buffer_desc));
hip_interop_.surface_format = va_drm_prime_surface_desc.fourcc;
hip_interop_.width = va_drm_prime_surface_desc.width;
hip_interop_.height = va_drm_prime_surface_desc.height;
hip_interop_.offset[0] = va_drm_prime_surface_desc.layers[0].offset[0];
hip_interop_.offset[1] = va_drm_prime_surface_desc.layers[1].offset[0];
hip_interop_.offset[2] = va_drm_prime_surface_desc.layers[2].offset[0];
hip_interop_.pitch[0] = va_drm_prime_surface_desc.layers[0].pitch[0];
hip_interop_.pitch[1] = va_drm_prime_surface_desc.layers[1].pitch[0];
hip_interop_.pitch[2] = va_drm_prime_surface_desc.layers[2].pitch[0];
hip_interop_.num_layers = va_drm_prime_surface_desc.num_layers;
for (uint32_t i = 0; i < va_drm_prime_surface_desc.num_objects; ++i) {
close(va_drm_prime_surface_desc.objects[i].fd);
}
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::ReleaseHipInteropMem(VASurfaceID current_surface_id) {
if (hip_interop_.hip_mapped_device_mem != nullptr) {
CHECK_HIP(hipFree(hip_interop_.hip_mapped_device_mem));
}
if (hip_interop_.hip_ext_mem != nullptr) {
CHECK_HIP(hipDestroyExternalMemory(hip_interop_.hip_ext_mem));
}
memset((void*)&hip_interop_, 0, sizeof(hip_interop_));
CHECK_ROCJPEG(jpeg_vaapi_decoder_.ReleaseSurface(current_surface_id));
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::CopyChannel(RocJpegImage *destination, uint16_t channel_height, uint8_t channel_index) {
if (hip_interop_.pitch[channel_index] != 0 && destination->pitch[channel_index] != 0 && destination->channel[channel_index] != nullptr) {
if (destination->pitch[channel_index] == hip_interop_.pitch[channel_index]) {
RocJpegStatus ROCJpegDecoder::CopyChannel(HipInteropDeviceMem& hip_interop_dev_mem, uint16_t channel_height, uint8_t channel_index, RocJpegImage *destination) {
if (hip_interop_dev_mem.pitch[channel_index] != 0 && destination->pitch[channel_index] != 0 && destination->channel[channel_index] != nullptr) {
if (destination->pitch[channel_index] == hip_interop_dev_mem.pitch[channel_index]) {
uint32_t channel_size = destination->pitch[channel_index] * channel_height;
CHECK_HIP(hipMemcpyDtoDAsync(destination->channel[channel_index], hip_interop_.hip_mapped_device_mem + hip_interop_.offset[channel_index], channel_size, hip_stream_));
CHECK_HIP(hipMemcpyDtoDAsync(destination->channel[channel_index], hip_interop_dev_mem.hip_mapped_device_mem + hip_interop_dev_mem.offset[channel_index], channel_size, hip_stream_));
} else {
CHECK_HIP(hipMemcpy2DAsync(destination->channel[channel_index], destination->pitch[channel_index], hip_interop_.hip_mapped_device_mem + hip_interop_.offset[channel_index], hip_interop_.pitch[channel_index],
CHECK_HIP(hipMemcpy2DAsync(destination->channel[channel_index], destination->pitch[channel_index], hip_interop_dev_mem.hip_mapped_device_mem + hip_interop_dev_mem.offset[channel_index], hip_interop_dev_mem.pitch[channel_index],
destination->pitch[channel_index], channel_height, hipMemcpyDeviceToDevice, hip_stream_));
}
}
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::GetChromaHeight(uint16_t picture_height, uint16_t &chroma_height) {
switch (hip_interop_.surface_format) {
RocJpegStatus ROCJpegDecoder::GetChromaHeight(uint32_t surface_format, uint16_t picture_height, uint16_t &chroma_height) {
switch (surface_format) {
case VA_FOURCC_NV12: /*NV12: two-plane 8-bit YUV 4:2:0*/
chroma_height = picture_height >> 1;
break;
@@ -263,28 +218,28 @@ RocJpegStatus ROCJpegDecoder::GetChromaHeight(uint16_t picture_height, uint16_t
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::ColorConvertToRGB(uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination) {
switch (hip_interop_.surface_format) {
RocJpegStatus ROCJpegDecoder::ColorConvertToRGB(HipInteropDeviceMem& hip_interop_dev_mem, uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination) {
switch (hip_interop_dev_mem.surface_format) {
case VA_FOURCC_444P:
ColorConvertYUV444ToRGB(hip_stream_, picture_width, picture_height, destination->channel[0], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0], hip_interop_.offset[1]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0], hip_interop_dev_mem.offset[1]);
break;
case ROCJPEG_FOURCC_YUYV:
ColorConvertYUYVToRGB(hip_stream_, picture_width, picture_height, destination->channel[0], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
break;
case VA_FOURCC_NV12:
ColorConvertNV12ToRGB(hip_stream_, picture_width, picture_height, destination->channel[0], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0],
hip_interop_.hip_mapped_device_mem + hip_interop_.offset[1], hip_interop_.pitch[1]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0],
hip_interop_dev_mem.hip_mapped_device_mem + hip_interop_dev_mem.offset[1], hip_interop_dev_mem.pitch[1]);
break;
case VA_FOURCC_Y800:
ColorConvertYUV400ToRGB(hip_stream_, picture_width, picture_height, destination->channel[0], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
break;
case VA_FOURCC_RGBA:
ColorConvertRGBAToRGB(hip_stream_, picture_width, picture_height, destination->channel[0], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
break;
default:
ERR("ERROR! surface format is not supported!");
@@ -293,29 +248,29 @@ RocJpegStatus ROCJpegDecoder::ColorConvertToRGB(uint32_t picture_width, uint32_t
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::ColorConvertToRGBPlanar(uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination) {
switch (hip_interop_.surface_format) {
RocJpegStatus ROCJpegDecoder::ColorConvertToRGBPlanar(HipInteropDeviceMem& hip_interop_dev_mem, uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination) {
switch (hip_interop_dev_mem.surface_format) {
case VA_FOURCC_444P:
ColorConvertYUV444ToRGBPlanar(hip_stream_, picture_width, picture_height, destination->channel[0], destination->channel[1], destination->channel[2], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0], hip_interop_.offset[1]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0], hip_interop_dev_mem.offset[1]);
break;
case ROCJPEG_FOURCC_YUYV:
ColorConvertYUYVToRGBPlanar(hip_stream_, picture_width, picture_height, destination->channel[0], destination->channel[1], destination->channel[2], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
break;
case VA_FOURCC_NV12:
ColorConvertNV12ToRGBPlanar(hip_stream_, picture_width, picture_height, destination->channel[0], destination->channel[1], destination->channel[2], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0],
hip_interop_.hip_mapped_device_mem + hip_interop_.offset[1], hip_interop_.pitch[1]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0],
hip_interop_dev_mem.hip_mapped_device_mem + hip_interop_dev_mem.offset[1], hip_interop_dev_mem.pitch[1]);
break;
case VA_FOURCC_Y800:
ColorConvertYUV400ToRGBPlanar(hip_stream_, picture_width, picture_height, destination->channel[0], destination->channel[1], destination->channel[2], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
break;
case VA_FOURCC_RGBP:
// Copy red, green, and blue channels from the interop memory into the destination
for (uint8_t channel_index = 0; channel_index < 3; channel_index++) {
CHECK_ROCJPEG(CopyChannel(destination, picture_height, channel_index));
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, channel_index, destination));
}
break;
default:
@@ -325,33 +280,33 @@ RocJpegStatus ROCJpegDecoder::ColorConvertToRGBPlanar(uint32_t picture_width, ui
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::GetPlanarYUVOutputFormat(uint32_t picture_width, uint32_t picture_height, uint16_t chroma_height, RocJpegImage *destination) {
if (hip_interop_.surface_format == ROCJPEG_FOURCC_YUYV) {
RocJpegStatus ROCJpegDecoder::GetPlanarYUVOutputFormat(HipInteropDeviceMem& hip_interop_dev_mem, uint32_t picture_width, uint32_t picture_height, uint16_t chroma_height, RocJpegImage *destination) {
if (hip_interop_dev_mem.surface_format == ROCJPEG_FOURCC_YUYV) {
// Extract the packed YUYV and copy them into the first, second, and thrid channels of the destination.
ConvertPackedYUYVToPlanarYUV(hip_stream_, picture_width, picture_height, destination->channel[0], destination->channel[1], destination->channel[2],
destination->pitch[0], destination->pitch[1], hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
destination->pitch[0], destination->pitch[1], hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
} else {
// Copy Luma
CHECK_ROCJPEG(CopyChannel(destination, picture_height, 0));
if (hip_interop_.surface_format == VA_FOURCC_NV12) {
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, 0, destination));
if (hip_interop_dev_mem.surface_format == VA_FOURCC_NV12) {
// Extract the interleaved UV channels and copy them into the second and thrid channels of the destination.
ConvertInterleavedUVToPlanarUV(hip_stream_, picture_width >> 1, picture_height >> 1, destination->channel[1], destination->channel[2],
destination->pitch[1], hip_interop_.hip_mapped_device_mem + hip_interop_.offset[1] , hip_interop_.pitch[1]);
} else if (hip_interop_.surface_format == VA_FOURCC_444P) {
CHECK_ROCJPEG(CopyChannel(destination, chroma_height, 1));
CHECK_ROCJPEG(CopyChannel(destination, chroma_height, 2));
destination->pitch[1], hip_interop_dev_mem.hip_mapped_device_mem + hip_interop_dev_mem.offset[1] , hip_interop_dev_mem.pitch[1]);
} else if (hip_interop_dev_mem.surface_format == VA_FOURCC_444P) {
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, destination));
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, destination));
}
}
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus ROCJpegDecoder::GetYOutputFormat(uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination) {
if (hip_interop_.surface_format == ROCJPEG_FOURCC_YUYV) {
RocJpegStatus ROCJpegDecoder::GetYOutputFormat(HipInteropDeviceMem& hip_interop_dev_mem, uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination) {
if (hip_interop_dev_mem.surface_format == ROCJPEG_FOURCC_YUYV) {
ExtractYFromPackedYUYV(hip_stream_, picture_width, picture_height, destination->channel[0], destination->pitch[0],
hip_interop_.hip_mapped_device_mem, hip_interop_.pitch[0]);
hip_interop_dev_mem.hip_mapped_device_mem, hip_interop_dev_mem.pitch[0]);
} else {
// Copy Luma
CHECK_ROCJPEG(CopyChannel(destination, picture_height, 0));
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, 0, destination));
}
return ROCJPEG_STATUS_SUCCESS;
}
+6 -21
Melihat File
@@ -25,7 +25,6 @@ THE SOFTWARE.
#include <unistd.h>
#include <vector>
#include <hip/hip_runtime.h>
#include <mutex>
#include <queue>
#include "../api/rocjpeg.h"
@@ -34,17 +33,6 @@ THE SOFTWARE.
#include "rocjpeg_vaapi_decoder.h"
#include "rocjpeg_hip_kernels.h"
struct HipInteropDeviceMem {
hipExternalMemory_t hip_ext_mem; // Interface to the vaapi-hip interop
uint8_t* hip_mapped_device_mem; // Mapped device memory for the YUV plane
uint32_t surface_format; // Pixel format fourcc of the whole surface
uint32_t width; // Width of the surface in pixels.
uint32_t height; // Height of the surface in pixels.
uint32_t offset[3]; // Offset of each plane
uint32_t pitch[3]; // Pitch of each plane
uint32_t num_layers; // Number of layers making up the surface
};
class ROCJpegDecoder {
public:
ROCJpegDecoder(RocJpegBackend backend = ROCJPEG_BACKEND_HARDWARE, int device_id = 0);
@@ -54,14 +42,12 @@ class ROCJpegDecoder {
RocJpegStatus Decode(const uint8_t *data, size_t length, RocJpegOutputFormat output_format, RocJpegImage *destination);
private:
RocJpegStatus InitHIP(int device_id);
RocJpegStatus GetHipInteropMem(VADRMPRIMESurfaceDescriptor &va_drm_prime_surface_desc);
RocJpegStatus ReleaseHipInteropMem(VASurfaceID current_surface_id);
RocJpegStatus GetChromaHeight(uint16_t picture_height, uint16_t &chroma_height);
RocJpegStatus CopyChannel(RocJpegImage *destination, uint16_t channel_height, uint8_t channel_index);
RocJpegStatus ColorConvertToRGB(uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination);
RocJpegStatus ColorConvertToRGBPlanar(uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination);
RocJpegStatus GetPlanarYUVOutputFormat(uint32_t picture_width, uint32_t picture_height, uint16_t chroma_height, RocJpegImage *destination);
RocJpegStatus GetYOutputFormat(uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination);
RocJpegStatus GetChromaHeight(uint32_t surface_format, uint16_t picture_height, uint16_t &chroma_height);
RocJpegStatus CopyChannel(HipInteropDeviceMem& hip_interop, uint16_t channel_height, uint8_t channel_index, RocJpegImage *destination);
RocJpegStatus ColorConvertToRGB(HipInteropDeviceMem& hip_interop, uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination);
RocJpegStatus ColorConvertToRGBPlanar(HipInteropDeviceMem& hip_interop, uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination);
RocJpegStatus GetPlanarYUVOutputFormat(HipInteropDeviceMem& hip_interop, uint32_t picture_width, uint32_t picture_height, uint16_t chroma_height, RocJpegImage *destination);
RocJpegStatus GetYOutputFormat(HipInteropDeviceMem& hip_interop, uint32_t picture_width, uint32_t picture_height, RocJpegImage *destination);
int num_devices_;
int device_id_;
hipDeviceProp_t hip_dev_prop_;
@@ -70,7 +56,6 @@ class ROCJpegDecoder {
JpegParser jpeg_parser_;
RocJpegBackend backend_;
RocJpegVappiDecoder jpeg_vaapi_decoder_;
HipInteropDeviceMem hip_interop_;
};
#endif //ROC_JPEG_DECODER_H_
+207 -87
Melihat File
@@ -22,10 +22,182 @@ THE SOFTWARE.
#include "rocjpeg_vaapi_decoder.h"
RocJpegVappiMemoryPool::RocJpegVappiMemoryPool() {
std::vector<uint32_t> surface_formats = {VA_RT_FORMAT_RGB32, VA_RT_FORMAT_RGBP, VA_RT_FORMAT_YUV444,
VA_RT_FORMAT_YUV422, VA_RT_FORMAT_YUV420, VA_RT_FORMAT_YUV400};
for (auto surface_format : surface_formats) {
mem_pool_[surface_format] = std::vector<RocJpegVappiMemPoolEntry>();
}
}
void RocJpegVappiMemoryPool::ReleaseResources() {
VAStatus va_status;
hipError_t hip_status;
for (auto& pair : mem_pool_) {
for (auto& entry : pair.second) {
if (entry.va_context_id != 0) {
va_status = vaDestroyContext(va_display_, entry.va_context_id);
if (va_status != VA_STATUS_SUCCESS) {
ERR("ERROR: vaDestroyContext failed!");
}
}
if (entry.va_surface_id != 0) {
va_status = vaDestroySurfaces(va_display_, &entry.va_surface_id, 1);
if (va_status != VA_STATUS_SUCCESS) {
ERR("ERROR: vaDestroySurfaces failed!");
}
}
if (entry.hip_interop.hip_mapped_device_mem != nullptr) {
hip_status = hipFree(entry.hip_interop.hip_mapped_device_mem);
if (hip_status != hipSuccess) {
ERR("ERROR: hipFree failed!");
}
}
if (entry.hip_interop.hip_ext_mem != nullptr) {
hip_status = hipDestroyExternalMemory(entry.hip_interop.hip_ext_mem);
if (hip_status != hipSuccess) {
ERR("ERROR: hipDestroyExternalMemory failed!");
}
}
memset((void*)&entry.hip_interop, 0, sizeof(entry.hip_interop));
}
}
}
void RocJpegVappiMemoryPool::SetPoolSize(int32_t max_pool_size) {
for (auto& pair : mem_pool_) {
pair.second.reserve(max_pool_size);
}
}
void RocJpegVappiMemoryPool::SetVaapiDisplay(const VADisplay& va_display) {
va_display_ = va_display;
}
RocJpegStatus RocJpegVappiMemoryPool::AddPoolEntry(uint32_t surface_format, const RocJpegVappiMemPoolEntry& pool_entry) {
auto& entires = mem_pool_[surface_format];
if (entires.size() < entires.capacity()) {
entires.push_back(pool_entry);
} else {
if (entires.front().va_context_id != 0) {
CHECK_VAAPI(vaDestroyContext(va_display_, entires.front().va_context_id));
entires.front().va_context_id = 0;
}
if (entires.front().va_surface_id != 0) {
CHECK_VAAPI(vaDestroySurfaces(va_display_, &entires.front().va_surface_id, 1));
entires.front().va_surface_id = 0;
}
if (entires.front().hip_interop.hip_mapped_device_mem != nullptr) {
CHECK_HIP(hipFree(entires.front().hip_interop.hip_mapped_device_mem));
}
if (entires.front().hip_interop.hip_ext_mem != nullptr) {
CHECK_HIP(hipDestroyExternalMemory(entires.front().hip_interop.hip_ext_mem));
}
memset((void*)&entires.front().hip_interop, 0, sizeof(entires.front().hip_interop));
entires.erase(entires.begin());
entires.push_back(pool_entry);
}
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegVappiMemPoolEntry RocJpegVappiMemoryPool::GetEntry(uint32_t surface_format, uint32_t image_width, uint32_t image_height) {
for (const auto& entry : mem_pool_[surface_format]) {
if (entry.image_width == image_width && entry.image_height == image_height) {
return entry;
}
}
return {0, 0, 0 , 0, {0}};
}
bool RocJpegVappiMemoryPool::FindSurfaceId(VASurfaceID surface_id) {
for (auto& pair : mem_pool_) {
for (auto& entry : pair.second) {
if (entry.va_surface_id == surface_id) {
return true;
}
}
}
return false;
}
RocJpegStatus RocJpegVappiMemoryPool::DeleteSurfaceId(VASurfaceID surface_id) {
for (auto& pair : mem_pool_) {
auto& entries = pair.second;
auto it = std::find_if(entries.begin(), entries.end(),
[surface_id](const RocJpegVappiMemPoolEntry& entry) {return entry.va_surface_id == surface_id;});
if (it != entries.end()) {
if (it->va_context_id != 0) {
CHECK_VAAPI(vaDestroyContext(va_display_, it->va_context_id));
it->va_context_id = 0;
}
if (it->va_surface_id != 0) {
CHECK_VAAPI(vaDestroySurfaces(va_display_, &it->va_surface_id, 1));
it->va_surface_id = 0;
}
if (it->hip_interop.hip_mapped_device_mem != nullptr) {
CHECK_HIP(hipFree(it->hip_interop.hip_mapped_device_mem));
}
if (it->hip_interop.hip_ext_mem != nullptr) {
CHECK_HIP(hipDestroyExternalMemory(it->hip_interop.hip_ext_mem));
}
memset((void*)&it->hip_interop, 0, sizeof(it->hip_interop));
entries.erase(it);
break;
}
}
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus RocJpegVappiMemoryPool::GetHipInteropMem(VASurfaceID surface_id, HipInteropDeviceMem& hip_interop) {
for (auto& pair : mem_pool_) {
auto& entries = pair.second;
auto it = std::find_if(entries.begin(), entries.end(),
[surface_id](const RocJpegVappiMemPoolEntry& entry) {return entry.va_surface_id == surface_id;});
if (it != entries.end()) {
if (it->hip_interop.hip_mapped_device_mem == nullptr) {
VADRMPRIMESurfaceDescriptor va_drm_prime_surface_desc = {};
CHECK_VAAPI(vaExportSurfaceHandle(va_display_, surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
&va_drm_prime_surface_desc));
hipExternalMemoryHandleDesc external_mem_handle_desc = {};
hipExternalMemoryBufferDesc external_mem_buffer_desc = {};
external_mem_handle_desc.type = hipExternalMemoryHandleTypeOpaqueFd;
external_mem_handle_desc.handle.fd = va_drm_prime_surface_desc.objects[0].fd;
external_mem_handle_desc.size = va_drm_prime_surface_desc.objects[0].size;
CHECK_HIP(hipImportExternalMemory(&it->hip_interop.hip_ext_mem, &external_mem_handle_desc));
external_mem_buffer_desc.size = va_drm_prime_surface_desc.objects[0].size;
CHECK_HIP(hipExternalMemoryGetMappedBuffer((void**)&it->hip_interop.hip_mapped_device_mem, it->hip_interop.hip_ext_mem, &external_mem_buffer_desc));
it->hip_interop.surface_format = va_drm_prime_surface_desc.fourcc;
it->hip_interop.width = va_drm_prime_surface_desc.width;
it->hip_interop.height = va_drm_prime_surface_desc.height;
it->hip_interop.offset[0] = va_drm_prime_surface_desc.layers[0].offset[0];
it->hip_interop.offset[1] = va_drm_prime_surface_desc.layers[1].offset[0];
it->hip_interop.offset[2] = va_drm_prime_surface_desc.layers[2].offset[0];
it->hip_interop.pitch[0] = va_drm_prime_surface_desc.layers[0].pitch[0];
it->hip_interop.pitch[1] = va_drm_prime_surface_desc.layers[1].pitch[0];
it->hip_interop.pitch[2] = va_drm_prime_surface_desc.layers[2].pitch[0];
it->hip_interop.num_layers = va_drm_prime_surface_desc.num_layers;
for (uint32_t i = 0; i < va_drm_prime_surface_desc.num_objects; ++i) {
close(va_drm_prime_surface_desc.objects[i].fd);
}
}
hip_interop = it->hip_interop;
return ROCJPEG_STATUS_SUCCESS;
}
}
// it shouldn't reach here unless the requested surface_id is not in the memory pool.
ERR("the surface_id: " + TOSTR(surface_id) + " was not found in the memory pool!");
return ROCJPEG_STATUS_INVALID_PARAMETER;
}
RocJpegVappiDecoder::RocJpegVappiDecoder(int device_id) : device_id_{device_id}, drm_fd_{-1}, min_picture_width_{64}, min_picture_height_{64},
max_picture_width_{4096}, max_picture_height_{4096}, va_display_{0}, va_config_attrib_{{}}, va_config_id_{0}, va_profile_{VAProfileJPEGBaseline},
va_context_id_{0}, va_surface_ids_{}, va_picture_parameter_buf_id_{0}, va_quantization_matrix_buf_id_{0}, va_huffmantable_buf_id_{0},
va_slice_param_buf_id_{0}, va_slice_data_buf_id_{0}, current_vcn_jpeg_spec_{0} {
vaapi_mem_pool_(std::make_unique<RocJpegVappiMemoryPool>()), current_vcn_jpeg_spec_{0}, va_picture_parameter_buf_id_{0}, va_quantization_matrix_buf_id_{0}, va_huffmantable_buf_id_{0},
va_slice_param_buf_id_{0}, va_slice_data_buf_id_{0} {
vcn_jpeg_spec_ = {{"gfx908", {2, false, false}},
{"gfx90a", {2, false, false}},
{"gfx940", {24, true, true}},
@@ -44,23 +216,12 @@ RocJpegVappiDecoder::~RocJpegVappiDecoder() {
close(drm_fd_);
}
if (va_display_) {
vaapi_mem_pool_->ReleaseResources();
RocJpegStatus rocjpeg_status = DestroyDataBuffers();
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
ERR("Error: Failed to destroy VAAPI buffer");
}
VAStatus va_status;
if (va_surface_ids_.size() > 0) {
va_status = vaDestroySurfaces(va_display_, va_surface_ids_.data(), va_surface_ids_.size());
if (va_status != VA_STATUS_SUCCESS) {
ERR("ERROR: vaDestroySurfaces failed!");
}
}
if (va_context_id_) {
va_status = vaDestroyContext(va_display_, va_context_id_);
if (va_status != VA_STATUS_SUCCESS) {
ERR("ERROR: vaDestroyContext failed!");
}
}
if (va_config_id_) {
va_status = vaDestroyConfig(va_display_, va_config_id_);
if (va_status != VA_STATUS_SUCCESS) {
@@ -114,6 +275,9 @@ RocJpegStatus RocJpegVappiDecoder::InitializeDecoder(std::string device_name, st
CHECK_ROCJPEG(InitVAAPI(drm_node));
CHECK_ROCJPEG(CreateDecoderConfig());
vaapi_mem_pool_->SetVaapiDisplay(va_display_);
vaapi_mem_pool_->SetPoolSize(current_vcn_jpeg_spec_.num_jpeg_cores * 2);
return ROCJPEG_STATUS_SUCCESS;
}
@@ -257,71 +421,44 @@ RocJpegStatus RocJpegVappiDecoder::SubmitDecode(const JpegStreamParameters *jpeg
}
}
VASurfaceID va_surface_id;
CHECK_VAAPI(vaCreateSurfaces(va_display_, surface_format, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height, &va_surface_id, 1, &surface_attrib, 1));
va_surface_ids_.push_back(va_surface_id);
surface_id = va_surface_id;
if (va_context_id_) {
vaDestroyContext(va_display_, va_context_id_);
va_context_id_ = 0;
RocJpegVappiMemPoolEntry mem_pool_entry = vaapi_mem_pool_->GetEntry(surface_format, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height);
VAContextID va_context_id;
if (mem_pool_entry.va_context_id == 0 && mem_pool_entry.va_surface_id == 0) {
CHECK_VAAPI(vaCreateSurfaces(va_display_, surface_format, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height, &surface_id, 1, &surface_attrib, 1));
CHECK_VAAPI(vaCreateContext(va_display_, va_config_id_, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height, VA_PROGRESSIVE, &surface_id, 1, &va_context_id));
mem_pool_entry.image_width = jpeg_stream_params->picture_parameter_buffer.picture_width;
mem_pool_entry.image_height = jpeg_stream_params->picture_parameter_buffer.picture_height;
mem_pool_entry.va_surface_id = surface_id;
mem_pool_entry.va_context_id = va_context_id;
mem_pool_entry.hip_interop = {};
CHECK_ROCJPEG(vaapi_mem_pool_->AddPoolEntry(surface_format, mem_pool_entry));
} else {
surface_id = mem_pool_entry.va_surface_id;
va_context_id = mem_pool_entry.va_context_id;
}
CHECK_VAAPI(vaCreateContext(va_display_, va_config_id_, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height, VA_PROGRESSIVE, &va_surface_id, 1, &va_context_id_));
CHECK_ROCJPEG(DestroyDataBuffers());
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VAPictureParameterBufferType, sizeof(VAPictureParameterBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->picture_parameter_buffer, &va_picture_parameter_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VAIQMatrixBufferType, sizeof(VAIQMatrixBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->quantization_matrix_buffer, &va_quantization_matrix_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VAHuffmanTableBufferType, sizeof(VAHuffmanTableBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->huffman_table_buffer, &va_huffmantable_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VASliceParameterBufferType, sizeof(VASliceParameterBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->slice_parameter_buffer, &va_slice_param_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VASliceDataBufferType, jpeg_stream_params->slice_parameter_buffer.slice_data_size, 1, (void *)jpeg_stream_params->slice_data_buffer, &va_slice_data_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id, VAPictureParameterBufferType, sizeof(VAPictureParameterBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->picture_parameter_buffer, &va_picture_parameter_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id, VAIQMatrixBufferType, sizeof(VAIQMatrixBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->quantization_matrix_buffer, &va_quantization_matrix_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id, VAHuffmanTableBufferType, sizeof(VAHuffmanTableBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->huffman_table_buffer, &va_huffmantable_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id, VASliceParameterBufferType, sizeof(VASliceParameterBufferJPEGBaseline), 1, (void *)&jpeg_stream_params->slice_parameter_buffer, &va_slice_param_buf_id_));
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id, VASliceDataBufferType, jpeg_stream_params->slice_parameter_buffer.slice_data_size, 1, (void *)jpeg_stream_params->slice_data_buffer, &va_slice_data_buf_id_));
CHECK_VAAPI(vaBeginPicture(va_display_, va_context_id_, va_surface_id));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &va_picture_parameter_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &va_quantization_matrix_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &va_huffmantable_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &va_slice_param_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &va_slice_data_buf_id_, 1));
CHECK_VAAPI(vaEndPicture(va_display_, va_context_id_));
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus RocJpegVappiDecoder::ExportSurface(VASurfaceID surface_id, VADRMPRIMESurfaceDescriptor &va_drm_prime_surface_desc) {
bool is_surface_id_found = false;
int idx = 0;
for (idx = 0; idx < va_surface_ids_.size(); idx++) {
if (va_surface_ids_[idx] == surface_id) {
is_surface_id_found = true;
break;
}
}
if (!is_surface_id_found) {
return ROCJPEG_STATUS_INVALID_PARAMETER;
}
CHECK_VAAPI(vaExportSurfaceHandle(va_display_, surface_id,
VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
VA_EXPORT_SURFACE_READ_ONLY |
VA_EXPORT_SURFACE_SEPARATE_LAYERS,
&va_drm_prime_surface_desc));
CHECK_VAAPI(vaBeginPicture(va_display_, va_context_id, surface_id));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id, &va_picture_parameter_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id, &va_quantization_matrix_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id, &va_huffmantable_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id, &va_slice_param_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id, &va_slice_data_buf_id_, 1));
CHECK_VAAPI(vaEndPicture(va_display_, va_context_id));
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus RocJpegVappiDecoder::SyncSurface(VASurfaceID surface_id) {
VASurfaceStatus surface_status;
bool is_surface_id_found = false;
int idx = 0;
for (idx = 0; idx < va_surface_ids_.size(); idx++) {
if (va_surface_ids_[idx] == surface_id) {
is_surface_id_found = true;
break;
}
}
if (!is_surface_id_found) {
if (!vaapi_mem_pool_->FindSurfaceId(surface_id)) {
return ROCJPEG_STATUS_INVALID_PARAMETER;
}
@@ -343,25 +480,8 @@ RocJpegStatus RocJpegVappiDecoder::SyncSurface(VASurfaceID surface_id) {
return ROCJPEG_STATUS_SUCCESS;
}
RocJpegStatus RocJpegVappiDecoder::ReleaseSurface(VASurfaceID surface_id) {
bool is_surface_id_found = false;
int idx = 0;
for (idx = 0; idx < va_surface_ids_.size(); idx++) {
if (va_surface_ids_[idx] == surface_id) {
is_surface_id_found = true;
break;
}
}
if (!is_surface_id_found) {
return ROCJPEG_STATUS_INVALID_PARAMETER;
}
CHECK_VAAPI(vaDestroySurfaces(va_display_, &va_surface_ids_[idx], 1));
va_surface_ids_.erase(va_surface_ids_.begin() + idx);
return ROCJPEG_STATUS_SUCCESS;
RocJpegStatus RocJpegVappiDecoder::GetHipInteropMem(VASurfaceID surface_id, HipInteropDeviceMem& hip_interop) {
return vaapi_mem_pool_->GetHipInteropMem(surface_id, hip_interop);
}
void RocJpegVappiDecoder::GetVisibleDevices(std::vector<int>& visible_devices_vetor) {
+38 -4
Melihat File
@@ -33,6 +33,7 @@ THE SOFTWARE.
#include <unistd.h>
#include <filesystem>
#include <unordered_map>
#include <memory>
#include <va/va.h>
#include <va/va_drm.h>
#include <va/va_drmcommon.h>
@@ -57,15 +58,49 @@ typedef struct {
bool can_roi_decode;
} VcnJpegSpec;
struct HipInteropDeviceMem {
hipExternalMemory_t hip_ext_mem; // Interface to the vaapi-hip interop
uint8_t* hip_mapped_device_mem; // Mapped device memory for the YUV plane
uint32_t surface_format; // Pixel format fourcc of the whole surface
uint32_t width; // Width of the surface in pixels.
uint32_t height; // Height of the surface in pixels.
uint32_t offset[3]; // Offset of each plane
uint32_t pitch[3]; // Pitch of each plane
uint32_t num_layers; // Number of layers making up the surface
};
struct RocJpegVappiMemPoolEntry {
uint32_t image_width;
uint32_t image_height;
VASurfaceID va_surface_id;
VAContextID va_context_id;
HipInteropDeviceMem hip_interop;
};
class RocJpegVappiMemoryPool {
public:
RocJpegVappiMemoryPool();
void ReleaseResources();
void SetPoolSize(int32_t max_pool_size);
void SetVaapiDisplay(const VADisplay& va_display);
bool FindSurfaceId(VASurfaceID surface_id);
RocJpegVappiMemPoolEntry GetEntry(uint32_t surface_format, uint32_t image_width, uint32_t image_height);
RocJpegStatus AddPoolEntry(uint32_t surface_format, const RocJpegVappiMemPoolEntry& pool_entry);
RocJpegStatus DeleteSurfaceId(VASurfaceID surface_id);
RocJpegStatus GetHipInteropMem(VASurfaceID surface_id, HipInteropDeviceMem& hip_interop);
private:
VADisplay va_display_;
std::unordered_map<uint32_t, std::vector<RocJpegVappiMemPoolEntry>> mem_pool_;
};
class RocJpegVappiDecoder {
public:
RocJpegVappiDecoder(int device_id = 0);
~RocJpegVappiDecoder();
RocJpegStatus InitializeDecoder(std::string device_name, std::string gcn_arch_name, int device_id);
RocJpegStatus SubmitDecode(const JpegStreamParameters *jpeg_stream_params, uint32_t &surface_id, RocJpegOutputFormat output_format);
RocJpegStatus ExportSurface(VASurfaceID surface_id, VADRMPRIMESurfaceDescriptor &va_drm_prime_surface_desc);
RocJpegStatus SyncSurface(VASurfaceID surface_id);
RocJpegStatus ReleaseSurface(VASurfaceID surface_id);
RocJpegStatus GetHipInteropMem(VASurfaceID surface_id, HipInteropDeviceMem& hip_interop);
private:
int device_id_;
int drm_fd_;
@@ -77,9 +112,8 @@ private:
std::vector<VAConfigAttrib> va_config_attrib_;
VAConfigID va_config_id_;
VAProfile va_profile_;
VAContextID va_context_id_;
std::vector<VASurfaceID> va_surface_ids_;
std::unordered_map<std::string, VcnJpegSpec> vcn_jpeg_spec_;
std::unique_ptr<RocJpegVappiMemoryPool> vaapi_mem_pool_;
VcnJpegSpec current_vcn_jpeg_spec_;
VABufferID va_picture_parameter_buf_id_;
VABufferID va_quantization_matrix_buf_id_;