1 /*
2 * Copyright (c) 2025-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "sample_info.h"
17 #include "camera_log.h"
18
19 namespace OHOS {
20 namespace CameraStandard {
21
CodecAVBufferInfo(uint32_t argBufferIndex,OH_AVBuffer * argBuffer)22 CodecAVBufferInfo::CodecAVBufferInfo(uint32_t argBufferIndex, OH_AVBuffer* argBuffer)
23 : bufferIndex(argBufferIndex), buffer(argBuffer)
24 {
25 // get output buffer attr
26 OH_AVBuffer_GetBufferAttr(argBuffer, &attr);
27 }
28
GetCopyAVBuffer()29 OH_AVBuffer* CodecAVBufferInfo::GetCopyAVBuffer()
30 {
31 MEDIA_INFO_LOG("CodecBufferInfo OH_AVBuffer_Create with size: %{public}d", attr.size);
32 OH_AVBuffer* destBuffer = OH_AVBuffer_Create(attr.size);
33 CHECK_ERROR_RETURN_RET_LOG(destBuffer == nullptr, nullptr, "destBuffer is null");
34 auto sourceAddr = OH_AVBuffer_GetAddr(buffer);
35 auto destAddr = OH_AVBuffer_GetAddr(destBuffer);
36 errno_t cpyRet = memcpy_s(reinterpret_cast<void *>(destAddr), attr.size,
37 reinterpret_cast<void *>(sourceAddr), attr.size);
38 CHECK_ERROR_PRINT_LOG(cpyRet != 0, "CodecBufferInfo memcpy_s failed. %{public}d", cpyRet);
39
40 OH_AVErrCode errorCode = OH_AVBuffer_SetBufferAttr(destBuffer, &attr);
41 CHECK_ERROR_PRINT_LOG(errorCode != 0, "CodecBufferInfo OH_AVBuffer_SetBufferAttr failed. %{public}d", errorCode);
42 return destBuffer;
43 }
44
AddCopyAVBuffer(OH_AVBuffer * IDRBuffer)45 OH_AVBuffer* CodecAVBufferInfo::AddCopyAVBuffer(OH_AVBuffer* IDRBuffer)
46 {
47 CHECK_ERROR_RETURN_RET_LOG(nullptr == IDRBuffer, IDRBuffer, "AddCopyAVBuffer without IDRBuffer!");
48 OH_AVCodecBufferAttr IDRAttr = {0, 0, 0, AVCODEC_BUFFER_FLAGS_NONE};
49 OH_AVCodecBufferAttr destAttr = {0, 0, 0, AVCODEC_BUFFER_FLAGS_NONE};
50 OH_AVBuffer_GetBufferAttr(IDRBuffer, &IDRAttr);
51 int32_t destBufferSize = IDRAttr.size + attr.size;
52 OH_AVBuffer* destBuffer = OH_AVBuffer_Create(destBufferSize);
53 CHECK_ERROR_RETURN_RET_LOG(destBuffer == nullptr, nullptr, "destBuffer is null");
54 auto destAddr = OH_AVBuffer_GetAddr(destBuffer);
55 auto sourceIDRAddr = OH_AVBuffer_GetAddr(IDRBuffer);
56
57 errno_t cpyRet = memcpy_s(reinterpret_cast<void *>(destAddr), destBufferSize,
58 reinterpret_cast<void *>(sourceIDRAddr), IDRAttr.size);
59 CHECK_ERROR_PRINT_LOG(0 != cpyRet, "CodecBufferInfo memcpy_s IDR frame failed. %{public}d", cpyRet);
60 destAddr = destAddr + IDRAttr.size;
61 auto sourceAddr = OH_AVBuffer_GetAddr(buffer);
62 cpyRet = memcpy_s(reinterpret_cast<void *>(destAddr), attr.size, reinterpret_cast<void *>(sourceAddr), attr.size);
63 CHECK_ERROR_PRINT_LOG(0 != cpyRet, "CodecBufferInfo memcpy_s I frame failed. %{public}d", cpyRet);
64 OH_AVBuffer_Destroy(IDRBuffer);
65 destAttr.size = destBufferSize;
66 destAttr.flags = IDRAttr.flags | attr.flags;
67 MEDIA_INFO_LOG("CodecBufferInfo deep copy with size: %{public}d, %{public}d", destBufferSize, destAttr.flags);
68 OH_AVBuffer_SetBufferAttr(destBuffer, &destAttr);
69 return destBuffer;
70 }
71
Release()72 void CodecUserData::Release()
73 {
74 {
75 std::lock_guard<std::mutex> lock(inputMutex_);
76 while (!inputBufferInfoQueue_.empty()) {
77 inputBufferInfoQueue_.pop();
78 }
79 }
80 {
81 std::lock_guard<std::mutex> lock(outputMutex_);
82 while (!outputBufferInfoQueue_.empty()) {
83 outputBufferInfoQueue_.pop();
84 }
85 }
86 }
87
~CodecUserData()88 CodecUserData::~CodecUserData()
89 {
90 Release();
91 }
92
VideoCodecAVBufferInfo(uint32_t argBufferIndex,std::shared_ptr<OHOS::Media::AVBuffer> argBuffer)93 VideoCodecAVBufferInfo::VideoCodecAVBufferInfo(uint32_t argBufferIndex,
94 std::shared_ptr<OHOS::Media::AVBuffer> argBuffer)
95 : bufferIndex(argBufferIndex), buffer(argBuffer)
96 {
97 }
98
GetCopyAVBuffer()99 std::shared_ptr<OHOS::Media::AVBuffer> VideoCodecAVBufferInfo::GetCopyAVBuffer()
100 {
101 MEDIA_INFO_LOG("CodecBufferInfo OH_AVBuffer_Create with size: %{public}d", buffer->memory_->GetSize());
102 auto allocator = Media::AVAllocatorFactory::CreateSharedAllocator(Media::MemoryFlag::MEMORY_READ_WRITE);
103 CHECK_ERROR_RETURN_RET_LOG(allocator == nullptr, nullptr, "create allocator failed");
104 std::shared_ptr<Media::AVBuffer> destBuffer = Media::AVBuffer::CreateAVBuffer(allocator,
105 buffer->memory_->GetCapacity());
106 CHECK_ERROR_RETURN_RET_LOG(destBuffer == nullptr, nullptr, "destBuffer is null");
107 auto sourceAddr = buffer->memory_->GetAddr();
108 auto destAddr = destBuffer->memory_->GetAddr();
109 errno_t cpyRet = memcpy_s(reinterpret_cast<void *>(destAddr), buffer->memory_->GetSize(),
110 reinterpret_cast<void *>(sourceAddr), buffer->memory_->GetSize());
111 CHECK_ERROR_PRINT_LOG(0 != cpyRet, "CodecBufferInfo memcpy_s failed. %{public}d", cpyRet);
112 destBuffer->pts_ = buffer->pts_;
113 destBuffer->flag_ = buffer->flag_;
114 destBuffer->memory_->SetSize(buffer->memory_->GetSize());
115 return destBuffer;
116 }
117
AddCopyAVBuffer(std::shared_ptr<OHOS::Media::AVBuffer> IDRBuffer)118 std::shared_ptr<OHOS::Media::AVBuffer> VideoCodecAVBufferInfo::AddCopyAVBuffer(
119 std::shared_ptr<OHOS::Media::AVBuffer> IDRBuffer)
120 {
121 CHECK_ERROR_RETURN_RET_LOG(nullptr == IDRBuffer, IDRBuffer, "AddCopyAVBuffer without IDRBuffer!");
122 int32_t destBufferSize = IDRBuffer->memory_->GetSize() + buffer->memory_->GetSize();
123 auto allocator = Media::AVAllocatorFactory::CreateSharedAllocator(Media::MemoryFlag::MEMORY_READ_WRITE);
124 CHECK_ERROR_RETURN_RET_LOG(allocator == nullptr, nullptr, "create allocator failed");
125 std::shared_ptr<Media::AVBuffer> destBuffer = Media::AVBuffer::CreateAVBuffer(allocator, destBufferSize);
126 CHECK_ERROR_RETURN_RET_LOG(destBuffer == nullptr, nullptr, "destBuffer is null");
127 auto destAddr = destBuffer->memory_->GetAddr();
128 auto sourceIDRAddr = IDRBuffer->memory_->GetAddr();
129 errno_t cpyRet = memcpy_s(reinterpret_cast<void *>(destAddr), destBufferSize,
130 reinterpret_cast<void *>(sourceIDRAddr), IDRBuffer->memory_->GetSize());
131 CHECK_ERROR_PRINT_LOG(0 != cpyRet, "CodecBufferInfo memcpy_s IDR frame failed. %{public}d", cpyRet);
132 destAddr = destAddr + IDRBuffer->memory_->GetSize();
133 auto sourceAddr = buffer->memory_->GetAddr();
134 cpyRet = memcpy_s(reinterpret_cast<void *>(destAddr), buffer->memory_->GetSize(),
135 reinterpret_cast<void *>(sourceAddr), buffer->memory_->GetSize());
136 CHECK_ERROR_PRINT_LOG(0 != cpyRet, "CodecBufferInfo memcpy_s I frame failed. %{public}d", cpyRet);
137 destBuffer->memory_->SetSize(destBufferSize);
138 destBuffer->flag_ = IDRBuffer->flag_ | buffer->flag_;
139 MEDIA_INFO_LOG("CodecBufferInfo copy with size: %{public}d, %{public}d", destBufferSize, destBuffer->flag_);
140 return destBuffer;
141 }
142
Release()143 void VideoCodecUserData::Release()
144 {
145 {
146 std::lock_guard<std::mutex> lock(inputMutex_);
147 while (!inputBufferInfoQueue_.empty()) {
148 inputBufferInfoQueue_.pop();
149 }
150 }
151 {
152 std::lock_guard<std::mutex> lock(outputMutex_);
153 while (!outputBufferInfoQueue_.empty()) {
154 outputBufferInfoQueue_.pop();
155 }
156 }
157 }
158
~VideoCodecUserData()159 VideoCodecUserData::~VideoCodecUserData()
160 {
161 Release();
162 }
163
164 } // CameraStandard
165 } // OHOS
166