1/*
2 * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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#include "codec_dyna_buffer.h"
16#include <buffer_handle_utils.h>
17#include <hdf_base.h>
18#include <securec.h>
19#include <unistd.h>
20#include "codec_log_wrapper.h"
21#include "v3_0/codec_types.h"
22using namespace OHOS::HDI::Codec::V3_0;
23namespace OHOS {
24namespace Codec {
25namespace Omx {
26CodecDynaBuffer::CodecDynaBuffer(struct OmxCodecBuffer &codecBuffer)
27    : ICodecBuffer(codecBuffer)
28{
29}
30
31CodecDynaBuffer::~CodecDynaBuffer()
32{
33}
34
35sptr<ICodecBuffer> CodecDynaBuffer::Create(struct OmxCodecBuffer &codecBuffer)
36{
37    codecBuffer.bufferhandle = nullptr;
38    codecBuffer.allocLen = sizeof(DynamicBuffer);
39    CodecDynaBuffer *buffer = new CodecDynaBuffer(codecBuffer);
40    return sptr<ICodecBuffer>(buffer);
41}
42
43int32_t CodecDynaBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer)
44{
45    if (!CheckInvalid(codecBuffer)) {
46        CODEC_LOGE("CheckInvalid return false");
47        return HDF_ERR_INVALID_PARAM;
48    }
49
50    if (buffer_ == nullptr && codecBuffer.bufferhandle != nullptr) {
51        BufferHandle* handle = codecBuffer.bufferhandle->GetBufferHandle();
52        if (handle != nullptr) {
53            buffer_ = codecBuffer.bufferhandle;
54            dynaBuffer_.bufferHandle = handle;
55        }
56    }
57
58    int fenceFd = codecBuffer.fenceFd;
59    if (fenceFd >= 0) {
60        auto ret = SyncWait(fenceFd, TIME_WAIT_MS);
61        if (ret != EOK) {
62            CODEC_LOGW("SyncWait ret err");
63        }
64        close(codecBuffer.fenceFd);
65        codecBuffer.fenceFd = -1;
66    }
67    return ICodecBuffer::FillOmxBuffer(codecBuffer, omxBuffer);
68}
69
70int32_t CodecDynaBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer)
71{
72    if (!CheckInvalid(codecBuffer)) {
73        CODEC_LOGE("CheckInvalid return false");
74        return HDF_ERR_INVALID_PARAM;
75    }
76    if (codecBuffer.bufferhandle != nullptr) {
77        BufferHandle* handle = codecBuffer.bufferhandle->GetBufferHandle();
78        if (handle != nullptr) {
79            buffer_ = codecBuffer.bufferhandle;
80            dynaBuffer_.bufferHandle = handle;
81            codecBuffer.filledLen = sizeof(DynamicBuffer);
82        }
83    }
84
85    int fence = codecBuffer.fenceFd;
86    if (fence >= 0) {
87        auto ret = SyncWait(fence, TIME_WAIT_MS);
88        if (ret != EOK) {
89            CODEC_LOGW("SyncWait ret err");
90        }
91        close(codecBuffer.fenceFd);
92        codecBuffer.fenceFd = -1;
93    }
94
95    return ICodecBuffer::EmptyOmxBuffer(codecBuffer, omxBuffer);
96}
97
98int32_t CodecDynaBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer)
99{
100    if (!CheckInvalid(codecBuffer)) {
101        CODEC_LOGE("shMem_ is null or CheckInvalid return false");
102        return HDF_ERR_INVALID_PARAM;
103    }
104
105    buffer_ = nullptr;
106    return HDF_SUCCESS;
107}
108
109int32_t CodecDynaBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer)
110{
111    return ICodecBuffer::EmptyOmxBufferDone(omxBuffer);
112}
113
114int32_t CodecDynaBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer)
115{
116    return ICodecBuffer::FillOmxBufferDone(omxBuffer);
117}
118
119uint8_t *CodecDynaBuffer::GetBuffer()
120{
121    return reinterpret_cast<uint8_t *>(&dynaBuffer_);
122}
123
124}  // namespace Omx
125}  // namespace Codec
126}  // namespace OHOS