Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
enm10k committed Oct 4, 2023
1 parent 6a1ea0b commit c8afe75
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 46 deletions.
60 changes: 34 additions & 26 deletions src/hwenc_jetson/jetson_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,18 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> JetsonBuffer::ToI420() {
input_params.params.colorFormat = NVBUF_COLOR_FORMAT_YUV420;
input_params.memtag = NvBufSurfaceTag_NONE;

NvBufSurface* surface = new NvBufSurface;
surface->memType = NVBUF_MEM_SURFACE_ARRAY;
NvBufSurface* dst_surface = new NvBufSurface;
dst_surface->memType = NVBUF_MEM_SURFACE_ARRAY;

// int batch_size = 1;
// NvBufSurface* surfaces[batch_size];
//surfaces[0] = surface;
NvBufSurface* surfaces[] = {surface};
int batch_size = sizeof(surfaces) / sizeof(surfaces[0]);
NvBufSurface* dst_surfaces[] = {dst_surface};
int batch_size = sizeof(dst_surfaces) / sizeof(dst_surfaces[0]);

// int dmabuf_fd;
if (NvBufSurfaceAllocate(surfaces, batch_size, &input_params) == -1) {
if (NvBufSurfaceAllocate(dst_surfaces, batch_size, &input_params) == -1) {
RTC_LOG(LS_ERROR) << __FUNCTION__ << " Failed to NvBufferCreateEx";
return scaled_buffer;
}
int dmabuf_fd = surface->gpuId;
NvBufSurfaceParams params = surfaces[0]->surfaceList[0];
int dmabuf_fd = dst_surface->gpuId;
NvBufSurfaceParams params = dst_surfaces[0]->surfaceList[0];

// NvBufferParams params = {0};
// if (NvBufferGetParams(fd_, &params) == -1) {
Expand All @@ -111,27 +107,38 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> JetsonBuffer::ToI420() {
trans_params.src_rect = &src_rect;
trans_params.dst_rect = &dest_rect;

// TODO: fd_ の型を NvBufSurface に変える
NvBufSurfTransform_Error error;
if (NvBufSurfTransform(fd_, dmabuf_fd, &trans_params) !=
NvBufSurfTransformError_Success) {
RTC_LOG(LS_ERROR) << __FUNCTION__ << " Failed to NvBufferTransform";
// NvBufSurfaceFromFd で fd_ を NvBufSurface に変換する
// 参照:_install/ubuntu-20.04_armv8_jetson/release/rootfs/usr/src/jetson_multimedia_api/samples/12_v4l2_camera_cuda/camera_v4l2_cuda.cpp
// NOTE: NvBufSurfaceFromFd のコストが高い場合、コンストラクタで変換する必要があるかもしれない?
NvBufSurface* src_surface = NULL;
if (-1 == NvBufSurfaceFromFd(fd_, (void**)(&src_surface))) {
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Failed to get NvBufSurface from FD";
return scaled_buffer;
}

NvBufferParams dmabuf_params = {0};
if (NvBufferGetParams(dmabuf_fd, &dmabuf_params) == -1) {
RTC_LOG(LS_ERROR) << __FUNCTION__ << " Failed to NvBufferGetParams";
// TODO: memcpy を使わなくても dst からデータを取得できそうなので調べる
if (NvBufSurfTransform(src_surface, dst_surface, &trans_params) !=
NvBufSurfTransformError_Success) {
RTC_LOG(LS_ERROR) << __FUNCTION__ << " Failed to NvBufferTransform";
return scaled_buffer;
}

// NvBufferParams dmabuf_params = {0};
// if (NvBufferGetParams(dmabuf_fd, &dmabuf_params) == -1) {
// RTC_LOG(LS_ERROR) << __FUNCTION__ << " Failed to NvBufferGetParams";
// return scaled_buffer;
// }

int ret;
void* data_addr;
uint8_t* dest_addr;
for (int plane = 0; plane < dmabuf_params.num_planes; plane++) {
ret = NvBufferMemMap(dmabuf_fd, plane, NvBufferMem_Read, &data_addr);
int num_planes = dst_surface->surfaceList[0].planeParams.num_planes;
int index = 0;
for (int plane = 0; plane < num_planes; plane++) {
ret = NvBufSurfaceMap(dst_surface, index, plane, NVBUF_MAP_READ);
if (ret == 0) {
NvBufferMemSyncForCpu(dmabuf_fd, plane, &data_addr);
NvBufSurfaceSyncForCpu(dst_surface, index, plane);
data_addr = dst_surface->surfaceList->mappedAddr.addr;
int height, width;
if (plane == 0) {
dest_addr = scaled_buffer.get()->MutableDataY();
Expand All @@ -148,18 +155,19 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> JetsonBuffer::ToI420() {
}
for (int i = 0; i < height; i++) {
memcpy(dest_addr + width * i,
(uint8_t*)data_addr + dmabuf_params.pitch[plane] * i, width);
(uint8_t*)data_addr + dst_surface->surfaceList->pitch * i,
width);
}
}
NvBufferMemUnMap(dmabuf_fd, plane, &data_addr);
NvBufSurfaceUnMap(dst_surface, 0, plane);
if (ret == -1) {
RTC_LOG(LS_ERROR) << __FUNCTION__
<< " Failed to NvBufferMemMap plane=" << plane;
<< " Failed to NvBufSurfaceMap plane=" << plane;
return scaled_buffer;
}
}

NvBufferDestroy(dmabuf_fd);
NvBufSurfaceDestroy(dst_surface);

return scaled_buffer;
} else {
Expand Down
77 changes: 57 additions & 20 deletions src/hwenc_jetson/jetson_video_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

// L4T Multimedia API
#include <nvbufsurface.h>
#include <nvbufsurftransform.h>

// Jetson Linux Multimedia API
#include <NvVideoDecoder.h>
Expand Down Expand Up @@ -218,8 +219,9 @@ bool JetsonVideoDecoder::JetsonRelease() {
decoder_ = nullptr;
}
if (dst_dma_fd_ != -1) {
NvBufferDestroy(dst_dma_fd_);
dst_dma_fd_ = -1;
// TODO: NvBufSurface にへんかんしてから破棄する?
// NvBufferDestroy(dst_dma_fd_);
// dst_dma_fd_ = -1;
}
return true;
}
Expand Down Expand Up @@ -282,6 +284,14 @@ void JetsonVideoDecoder::CaptureLoop() {
}

NvBuffer* buffer;

NvBufSurface* dst_surface = NULL;
if (-1 == NvBufSurfaceFromFd(dst_dma_fd_, (void**)(&dst_surface))) {
RTC_LOG(LS_ERROR) << __FUNCTION__
<< "Failed to get NvBufSurface from destination FD";
got_error_ = true;
break;
}
while (1) {
struct v4l2_buffer v4l2_buf;
struct v4l2_plane planes[MAX_PLANES];
Expand All @@ -305,7 +315,7 @@ void JetsonVideoDecoder::CaptureLoop() {
uint64_t pts = v4l2_buf.timestamp.tv_sec * rtc::kNumMicrosecsPerSec +
v4l2_buf.timestamp.tv_usec;

NvBufferRect src_rect, dest_rect;
NvBufSurfTransformRect src_rect, dest_rect;
src_rect.top = capture_crop_->c.top;
src_rect.left = capture_crop_->c.left;
src_rect.width = capture_crop_->c.width;
Expand All @@ -315,16 +325,35 @@ void JetsonVideoDecoder::CaptureLoop() {
dest_rect.width = capture_crop_->c.width;
dest_rect.height = capture_crop_->c.height;

NvBufferTransformParams transform_params;
NvBufSurfTransformParams transform_params;
memset(&transform_params, 0, sizeof(transform_params));
transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER;
transform_params.transform_flip = NvBufferTransform_None;
transform_params.transform_filter = NvBufferTransform_Filter_Smart;
transform_params.src_rect = src_rect;
transform_params.dst_rect = dest_rect;
transform_params.transform_flag = NVBUFSURF_TRANSFORM_FILTER;
transform_params.transform_flip = NvBufSurfTransform_None;
transform_params.transform_filter = NvBufSurfTransformInter_Algo3;
transform_params.src_rect = &src_rect;
transform_params.dst_rect = &dest_rect;

// dst_dma_fd_ と buffer の fd を それぞれ NvBufSurface に変換する
// NvBufSurface* dst = NULL;
// if (-1 == NvBufSurfaceFromFd(dst_dma_fd_, (void**)(&dst))) {
// RTC_LOG(LS_ERROR) << __FUNCTION__
// << "Failed to get NvBufSurface from destination FD";
// got_error_ = true;
// break;
// }

NvBufSurface* src_surface = NULL;
if (-1 ==
NvBufSurfaceFromFd(buffer->planes[0].fd, (void**)(&src_surface))) {
RTC_LOG(LS_ERROR) << __FUNCTION__
<< "Failed to get NvBufSurface from source FD";
got_error_ = true;
break;
}

// 何が来ても YUV420 に変換する
ret = NvBufferTransform(buffer->planes[0].fd, dst_dma_fd_,
&transform_params);
// TODO: memcpy を使わなくても dst からデータを取得できそうなので調べる
ret = NvBufSurfTransform(src_surface, dst_surface, &transform_params);
if (ret == -1) {
RTC_LOG(LS_ERROR) << __FUNCTION__ << " Transform failed";
break;
Expand All @@ -341,8 +370,8 @@ void JetsonVideoDecoder::CaptureLoop() {
break;
}

NvBufferParams parm;
ret = NvBufferGetParams(dst_dma_fd_, &parm);
// NvBufferParams parm;
// ret = NvBufferGetParams(dst_dma_fd_, &parm);

void* src_data;
uint8_t* dst_data;
Expand All @@ -360,11 +389,18 @@ void JetsonVideoDecoder::CaptureLoop() {
} else {
break;
}
ret = NvBufferMemMap(dst_dma_fd_, i, NvBufferMem_Read, &src_data);
NvBufferMemSyncForCpu(dst_dma_fd_, i, &src_data);
for (uint32_t j = 0; j < parm.height[i]; j++) {
memcpy(dst_data + j * dst_stride, (char*)src_data + j * parm.pitch[i],
parm.width[i]);

// TODO: index と plne の値を確認する
ret = NvBufSurfaceMap(dst_surface, 0, i, NVBUF_MAP_READ);
NvBufSurfaceSyncForCpu(dst_surface, 0, i);

// TODO: plane 毎の height を計算する方法を調べる
NvBufSurfaceParams params = dst_surface->surfaceList[0];
int height = params.height;
for (uint32_t j = 0; j < height; j++) {
// TODO: 要確認
memcpy(dst_data + j * dst_stride, (char*)src_data + j * params.pitch,
params.width);
}
NvBufferMemUnMap(dst_dma_fd_, i, &src_data);
}
Expand Down Expand Up @@ -407,8 +443,9 @@ int JetsonVideoDecoder::SetCapture() {
<< "x" << format.fmt.pix_mp.height;

if (dst_dma_fd_ != -1) {
NvBufferDestroy(dst_dma_fd_);
dst_dma_fd_ = -1;
// TODO: NvBufSurface にへんかんしてから破棄する?
// NvBufferDestroy(dst_dma_fd_);
// dst_dma_fd_ = -1;
}

NvBufferCreateParams input_params = {0};
Expand Down

0 comments on commit c8afe75

Please sign in to comment.