1 /*
2 * Copyright (c) 2022-2022 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 #define HST_LOG_TAG "SyncMode"
17
18 #include "sync_mode.h"
19 #include "common/plugin_utils.h"
20 #include "utils/dump_buffer.h"
21 #include "foundation/log.h"
22 #include "utils/steady_clock.h"
23
24 namespace OHOS {
25 namespace Media {
26 namespace Pipeline {
SyncMode(std::string name)27 SyncMode::SyncMode(std::string name) : CodecMode(std::move(name))
28 {
29 MEDIA_LOG_I(PUBLIC_LOG_S " ThreadMode: SYNC", codecName_.c_str());
30 }
31
~SyncMode()32 SyncMode::~SyncMode()
33 {
34 MEDIA_LOG_D("sync mode dtor called");
35 }
36
Configure()37 ErrorCode SyncMode::Configure()
38 {
39 return CodecMode::Configure();
40 }
41
PushData(const std::string & inPort,const AVBufferPtr & buffer,int64_t offset)42 ErrorCode SyncMode::PushData(const std::string &inPort, const AVBufferPtr& buffer, int64_t offset)
43 {
44 const static int8_t maxRetryCnt = 3; // max retry times of handling one frame
45 ErrorCode handleFrameRes;
46 int8_t retryCnt = 0;
47 do {
48 handleFrameRes = HandleFrame(buffer);
49 while (FinishFrame() == ErrorCode::SUCCESS) {
50 MEDIA_LOG_DD("finish frame");
51 }
52 retryCnt++;
53 if (retryCnt >= maxRetryCnt) { // if retry cnt exceeds we will drop this frame
54 break;
55 }
56 // if timed out or returns again we should try again
57 } while (handleFrameRes == ErrorCode::ERROR_TIMED_OUT || handleFrameRes == ErrorCode::ERROR_AGAIN);
58 return ErrorCode::SUCCESS;
59 }
60
Stop()61 ErrorCode SyncMode::Stop()
62 {
63 MEDIA_LOG_D("SyncMode stop");
64 return ErrorCode::SUCCESS;
65 }
66
FlushStart()67 void SyncMode::FlushStart()
68 {
69 MEDIA_LOG_D("SyncMode FlushStart.");
70 }
71
FlushEnd()72 void SyncMode::FlushEnd()
73 {
74 MEDIA_LOG_D("SyncMode FlushEnd.");
75 }
76
HandleFrame(const std::shared_ptr<AVBuffer> & buffer)77 ErrorCode SyncMode::HandleFrame(const std::shared_ptr<AVBuffer>& buffer)
78 {
79 MEDIA_LOG_DD("SyncMode HandleFrame called");
80 auto ret = TranslatePluginStatus(plugin_->QueueInputBuffer(buffer, 0));
81 if (ret != ErrorCode::SUCCESS && ret != ErrorCode::ERROR_TIMED_OUT) {
82 MEDIA_LOG_E("Queue input buffer to plugin fail: " PUBLIC_LOG_D32, CppExt::to_underlying(ret));
83 }
84 return ret;
85 }
86
FinishFrame()87 ErrorCode SyncMode::FinishFrame()
88 {
89 MEDIA_LOG_DD("SyncMode begin finish frame");
90 auto outBuffer = outBufPool_->AllocateAppendBufferNonBlocking();
91 if (outBuffer == nullptr) {
92 MEDIA_LOG_E("Get out buffer from buffer pool fail");
93 return ErrorCode::ERROR_NO_MEMORY;
94 }
95 outBuffer->Reset();
96 auto status = plugin_->QueueOutputBuffer(outBuffer, 0);
97 if (status != Plugin::Status::OK && status != Plugin::Status::END_OF_STREAM) {
98 if (status != Plugin::Status::ERROR_NOT_ENOUGH_DATA) {
99 MEDIA_LOG_E("Queue output buffer to plugin fail: " PUBLIC_LOG_D32, static_cast<int32_t>((status)));
100 }
101 }
102 MEDIA_LOG_DD("SyncMode end finish frame");
103 return TranslatePluginStatus(status);
104 }
105
OnOutputBufferDone(const std::shared_ptr<Plugin::Buffer> & buffer)106 void SyncMode::OnOutputBufferDone(const std::shared_ptr<Plugin::Buffer>& buffer)
107 {
108 MEDIA_LOG_DD("begin");
109 FALSE_RETURN(buffer != nullptr);
110
111 // push to port
112 auto oPort = outPorts_[0];
113 if (oPort->GetWorkMode() == WorkMode::PUSH) {
114 DUMP_BUFFER2FILE("decoder_output.data", buffer);
115 oPort->PushData(buffer, -1);
116 } else {
117 MEDIA_LOG_W("decoder out port works in pull mode");
118 }
119 // 释放buffer 如果没有被缓存使其回到buffer pool 如果被sink缓存 则从buffer pool拿其他的buffer
120 std::const_pointer_cast<Plugin::Buffer>(buffer).reset();
121 MEDIA_LOG_DD("end");
122 }
123
Prepare()124 ErrorCode SyncMode::Prepare()
125 {
126 return CodecMode::Prepare();
127 }
128
Release()129 ErrorCode SyncMode::Release()
130 {
131 return CodecMode::Release();
132 }
133 } // namespace Pipeline
134 } // namespace Media
135 } // namespace OHOS