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