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 "icodec_buffer.h"
16#include <hdf_base.h>
17#include <poll.h>
18#include <securec.h>
19#include "codec_dyna_buffer.h"
20#include "codec_handle_buffer.h"
21#include "codec_dma_buffer.h"
22#include "codec_log_wrapper.h"
23#include "codec_share_buffer.h"
24#include "v3_0/codec_types.h"
25using namespace OHOS::HDI::Codec::V3_0;
26namespace OHOS {
27namespace Codec {
28namespace Omx {
29ICodecBuffer::ICodecBuffer(struct OmxCodecBuffer &codecBuffer)
30{
31    codecBuffer_ = codecBuffer;
32}
33ICodecBuffer::~ICodecBuffer()
34{}
35
36sptr<ICodecBuffer> ICodecBuffer::CreateCodeBuffer(struct OmxCodecBuffer &codecBuffer)
37{
38    sptr<ICodecBuffer> buffer = nullptr;
39    switch (codecBuffer.bufferType) {
40        case CODEC_BUFFER_TYPE_AVSHARE_MEM_FD:
41            buffer = CodecShareBuffer::Create(codecBuffer);
42            break;
43        case CODEC_BUFFER_TYPE_HANDLE:
44            buffer = CodecHandleBuffer::Create(codecBuffer);
45            break;
46        case CODEC_BUFFER_TYPE_DYNAMIC_HANDLE:
47            buffer = CodecDynaBuffer::Create(codecBuffer);
48            break;
49        case CODEC_BUFFER_TYPE_DMA_MEM_FD:
50            buffer = CodecDMABuffer::Create(codecBuffer);
51            break;
52        default:
53            CODEC_LOGE("bufferType[%{public}d] is unexpected", codecBuffer.bufferType);
54            break;
55    }
56    return buffer;
57}
58
59sptr<ICodecBuffer> ICodecBuffer::AllocateCodecBuffer(struct OmxCodecBuffer &codecBuffer,
60                                                     OMX_BUFFERHEADERTYPE &omxBuffer)
61{
62    sptr<ICodecBuffer> buffer = nullptr;
63    switch (codecBuffer.bufferType) {
64        case CODEC_BUFFER_TYPE_AVSHARE_MEM_FD:
65            buffer = CodecShareBuffer::Allocate(codecBuffer);
66            break;
67        case CODEC_BUFFER_TYPE_DMA_MEM_FD:
68            buffer = CodecDMABuffer::Allocate(codecBuffer, omxBuffer);
69            break;
70        default:
71            CODEC_LOGE("bufferType[%{public}d] is unexpected", codecBuffer.bufferType);
72            break;
73    }
74
75    return buffer;
76}
77
78struct OmxCodecBuffer &ICodecBuffer::GetCodecBuffer()
79{
80    return codecBuffer_;
81}
82
83void ICodecBuffer::SetBufferId(int32_t bufferId)
84{
85    codecBuffer_.bufferId = bufferId;
86}
87
88bool ICodecBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer)
89{
90    if (codecBuffer_.type != codecBuffer.type) {
91        CODEC_LOGE("input buffer type [%{public}d], but expect type [%{public}d]", codecBuffer.bufferType,
92                   codecBuffer_.bufferType);
93        return false;
94    }
95    return true;
96}
97
98int32_t ICodecBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer)
99{
100    omxBuffer.nOffset = codecBuffer.offset;
101    omxBuffer.nFilledLen = codecBuffer.filledLen;
102    omxBuffer.nFlags = codecBuffer.flag;
103    return HDF_SUCCESS;
104}
105
106int32_t ICodecBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer)
107{
108    omxBuffer.nOffset = codecBuffer.offset;
109    omxBuffer.nFilledLen = codecBuffer.filledLen;
110    omxBuffer.nFlags = codecBuffer.flag;
111    omxBuffer.nTimeStamp = codecBuffer.pts;
112    return HDF_SUCCESS;
113}
114
115int32_t ICodecBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer)
116{
117    codecBuffer_.offset = omxBuffer.nOffset;
118    codecBuffer_.filledLen = omxBuffer.nFilledLen;
119    return HDF_SUCCESS;
120}
121
122int32_t ICodecBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer)
123{
124    codecBuffer_.offset = omxBuffer.nOffset;
125    codecBuffer_.filledLen = omxBuffer.nFilledLen;
126    codecBuffer_.flag = omxBuffer.nFlags;
127    codecBuffer_.pts = omxBuffer.nTimeStamp;
128    return HDF_SUCCESS;
129}
130
131int32_t ICodecBuffer::SyncWait(int fd, uint32_t timeout)
132{
133    int retCode = -EPERM;
134    if (fd < 0) {
135        CODEC_LOGE("The fence id is invalid.");
136        return retCode;
137    }
138
139    struct pollfd pollfds = {0};
140    pollfds.fd = fd;
141    pollfds.events = POLLIN;
142
143    do {
144        retCode = poll(&pollfds, 1, timeout);
145    } while (retCode == -EPERM && (errno == EINTR || errno == EAGAIN));
146
147    if (retCode == 0) {
148        retCode = -EPERM;
149        errno = ETIME;
150    } else if (retCode > 0) {
151        if (static_cast<uint32_t>(pollfds.revents) & (POLLERR | POLLNVAL)) {
152            retCode = -EPERM;
153            errno = EINVAL;
154        }
155    }
156    return retCode < 0 ? -errno : EOK;
157}
158
159uint8_t *ICodecBuffer::GetBuffer()
160{
161    return nullptr;
162}
163
164int32_t ICodecBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer)
165{
166    (void)codecBuffer;
167    return HDF_SUCCESS;
168}
169}  // namespace Omx
170}  // namespace Codec
171}  // namespace OHOS