1 /*
2  * Copyright (c) 2024-2024 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 #ifndef CAMERA_FRAMEWORK_AUDIO_RECORD_H
17 #define CAMERA_FRAMEWORK_AUDIO_RECORD_H
18 #include <string>
19 #include <condition_variable>
20 #include "native_avcodec_base.h"
21 #include "native_avbuffer.h"
22 #include <refbase.h>
23 #include "camera_log.h"
24 #include "sample_info.h"
25 
26 namespace OHOS {
27 namespace CameraStandard {
28 using namespace std;
29 using ByteArrayPtr = std::unique_ptr<uint8_t[]>;
30 
31 class AudioRecord : public RefBase {
32 public:
AudioRecord(int64_t timestamp)33     explicit AudioRecord(int64_t timestamp) : timestamp_(timestamp)
34     {
35         frameId_ = std::to_string(timestamp);
36         bufferSize = 0;
37     }
~AudioRecord()38     ~AudioRecord()
39     {
40         MEDIA_DEBUG_LOG("AudioRecord release start");
41         if (audioBuffer_ != nullptr) {
42             delete audioBuffer_;
43             audioBuffer_ = nullptr;
44         }
45         if (encodedBuffer) {
46             OH_AVBuffer_Destroy(encodedBuffer);
47             encodedBuffer = nullptr;
48         }
49     }
50     OH_AVBuffer *encodedBuffer = nullptr;
51 
52     std::string frameId_;
53 
SetStatusReadyConvertStatus()54     void SetStatusReadyConvertStatus()
55     {
56         status = STATUS_READY_CONVERT;
57     }
58 
SetStatusFinishEncodeStatus()59     void SetStatusFinishEncodeStatus()
60     {
61         status = STATUS_FINISH_ENCODE;
62         canReleased_.notify_one();
63     }
64 
IsIdle()65     bool IsIdle()
66     {
67         return status == STATUS_NONE;
68     }
69 
IsReadyConvert()70     bool IsReadyConvert()
71     {
72         return status == STATUS_READY_CONVERT;
73     }
74 
IsFinishCache()75     bool IsFinishCache()
76     {
77         return status == STATUS_FINISH_ENCODE;
78     }
79 
CacheEncodedBuffer(OH_AVBuffer * buffer)80     void CacheEncodedBuffer(OH_AVBuffer *buffer)
81     {
82         MEDIA_DEBUG_LOG("cacheEncodedBuffer start");
83         encodedBuffer = buffer;
84         SetStatusFinishEncodeStatus();
85     }
86 
SetEncodedResult(bool encodedResult)87     void SetEncodedResult(bool encodedResult)
88     {
89         isEncoded_ = encodedResult;
90     }
91 
SetDeferredProcessedResult(bool processResult)92     void SetDeferredProcessedResult(bool processResult)
93     {
94         isDeferredProcessed_ = processResult;
95     }
96 
IsEncoded()97     bool IsEncoded()
98     {
99         return isEncoded_;
100     }
101 
IsDeferredProcessed()102     bool IsDeferredProcessed()
103     {
104         return isDeferredProcessed_;
105     }
106 
GetFrameId()107     const std::string& GetFrameId() const
108     {
109         return frameId_;
110     }
111 
GetBufferSize()112     uint32_t GetBufferSize()
113     {
114         return bufferSize;
115     }
116 
GetTimeStamp()117     int64_t GetTimeStamp()
118     {
119         return timestamp_;
120     }
121 
122     struct HashFunction {
operatorHashFunction123         std::size_t operator()(const sptr<AudioRecord>& obj) const
124         {
125             return std::hash<std::string>()(obj->GetFrameId());
126         }
127     };
128 
129     struct EqualFunction {
operatorEqualFunction130         bool operator()(const sptr<AudioRecord>& obj1, const sptr<AudioRecord>& obj2) const
131         {
132             return obj1->GetFrameId() == obj2->GetFrameId();
133         }
134     };
135 
ReleaseAudioBuffer()136     void ReleaseAudioBuffer()
137     {
138         std::unique_lock<std::mutex> lock(mutex_);
139         if (IsReadyConvert()) {
140             MEDIA_DEBUG_LOG("ReleaseAudioBuffer when isReadyConvert");
141             canReleased_.wait_for(lock, std::chrono::milliseconds(BUFFER_RELEASE_EXPIREATION_TIME),
142                 [this] { return IsFinishCache(); });
143             MEDIA_DEBUG_LOG("releaseSurfaceBuffer go %{public}s", frameId_.c_str());
144         }
145         if (audioBuffer_ != nullptr) {
146             delete audioBuffer_;
147             audioBuffer_ = nullptr;
148         }
149     }
150 
GetAudioBuffer()151     uint8_t* GetAudioBuffer()
152     {
153         std::unique_lock<std::mutex> lock(mutex_);
154         return audioBuffer_;
155     }
156 
SetAudioBuffer(uint8_t * audioBuffer)157     void SetAudioBuffer(uint8_t* audioBuffer)
158     {
159         std::unique_lock<std::mutex> lock(mutex_);
160         audioBuffer_ = audioBuffer;
161     }
162 
163 private:
164     static const int32_t STATUS_NONE = 0;
165     static const int32_t STATUS_READY_CONVERT = 1;
166     static const int32_t STATUS_FINISH_ENCODE = 2;
167     int status = STATUS_NONE;
168     std::atomic<bool> isDeferredProcessed_ { false };
169     std::atomic<bool> isEncoded_ { false };
170     uint32_t bufferSize;
171     int64_t timestamp_;
172     std::mutex mutex_;
173     std::condition_variable canReleased_;
174     uint8_t* audioBuffer_ = nullptr;
175 };
176 } // CameraStandard
177 } // OHOS
178 #endif //CAMERA_FRAMEWORK_AUDIO_RECORD_H
179