• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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