1 /*
2  * Copyright (c) 2021-2021 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 HISTREAMER_VIDEO_FFMPEG_DECODER_PLUGIN_H
17 #define HISTREAMER_VIDEO_FFMPEG_DECODER_PLUGIN_H
18 
19 #ifdef VIDEO_SUPPORT
20 
21 #include <functional>
22 #include <map>
23 #include "foundation/osal/thread/task.h"
24 #include "foundation/utils/blocking_queue.h"
25 #include "plugin/convert/ffmpeg_convert.h"
26 #include "plugin/interface/codec_plugin.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 #include "libavcodec/avcodec.h"
32 #include "libavutil/imgutils.h"
33 #include "libswscale/swscale.h"
34 #ifdef __cplusplus
35 };
36 #endif
37 #include "plugins/ffmpeg_adapter/utils/ffmpeg_utils.h"
38 #ifdef DUMP_RAW_DATA
39 #include <cstdio>
40 #endif
41 
42 namespace OHOS {
43 namespace Media {
44 namespace Plugin {
45 namespace Ffmpeg {
46 class VideoFfmpegDecoderPlugin : public CodecPlugin {
47 public:
48     explicit VideoFfmpegDecoderPlugin(std::string name);
49     ~VideoFfmpegDecoderPlugin() override = default;
50 
51     Status Init() override;
52     Status Deinit() override;
53     Status Prepare() override;
54     Status Reset() override;
55     Status Start() override;
56     Status Stop() override;
57     Status GetParameter(Tag tag, ValueType& value) override;
58     Status SetParameter(Tag tag, const ValueType& value) override;
59 
60     std::shared_ptr<Allocator> GetAllocator() override;
61 
SetCallback(Callback * cb)62     Status SetCallback(Callback* cb) override
63     {
64         return Status::OK;
65     }
66 
67     Status QueueInputBuffer(const std::shared_ptr<Buffer>& inputBuffer, int32_t timeoutMs) override;
68 
69     Status QueueOutputBuffer(const std::shared_ptr<Buffer>& outputBuffers, int32_t timeoutMs) override;
70 
71     Status Flush() override;
72 
SetDataCallback(DataCallback * dataCallback)73     Status SetDataCallback(DataCallback* dataCallback) override
74     {
75         dataCb_ = dataCallback;
76         return Status::OK;
77     }
78 
79 private:
80     Status CreateCodecContext();
81 
82     void InitCodecContext();
83 
84     void DeinitCodecContext();
85 
86     void SetCodecExtraData();
87 
88     Status OpenCodecContext();
89 
90     Status CloseCodecContext();
91 
92     Status ResetLocked();
93 
94     template<typename T>
95     void FindInParameterMapThenAssignLocked(Tag tag, T& assign);
96 
97     Status SendBufferLocked(const std::shared_ptr<Buffer>& inputBuffer);
98 
99     Status ScaleVideoFrame();
100 
101     Status WriteYuvData(const std::shared_ptr<Buffer>& frameBuffer);
102 
103     Status WriteRgbData(const std::shared_ptr<Buffer>& frameBuffer);
104 
105 #ifndef OHOS_LITE
106     Status WriteYuvDataStride(const std::shared_ptr<Buffer>& frameBuffer, int32_t stride);
107 
108     Status WriteRgbDataStride(const std::shared_ptr<Buffer>& frameBuffer, int32_t stride);
109 #endif
110 
111     Status FillFrameBuffer(const std::shared_ptr<Buffer>& frameBuffer);
112 
113     Status ReceiveBufferLocked(const std::shared_ptr<Buffer>& frameBuffer);
114 
115     void ReceiveFrameBuffer();
116 
117 #ifdef DUMP_RAW_DATA
118     std::FILE* dumpFd_;
119     void DumpVideoRawOutData();
120 #endif
121 
122     void NotifyInputBufferDone(const std::shared_ptr<Buffer>& input);
123 
124     void NotifyOutputBufferDone(const std::shared_ptr<Buffer>& output);
125 
126     std::shared_ptr<const AVCodec> avCodec_;
127     std::shared_ptr<struct SwsContext> swsCtx_ {nullptr};
128     std::map<Tag, ValueType> videoDecParams_ {};
129     std::vector<uint8_t> paddedBuffer_;
130     size_t paddedBufferSize_ {0};
131     std::shared_ptr<AVFrame> cachedFrame_ {nullptr};
132     std::shared_ptr<AVPacket> avPacket_ {};
133     uint8_t* scaleData_[AV_NUM_DATA_POINTERS];
134     int32_t scaleLineSize_[AV_NUM_DATA_POINTERS];
135     bool isAllocScaleData_ {false};
136     std::shared_ptr<Ffmpeg::Scale> scale_ {nullptr};
137 
138     DataCallback* dataCb_ {};
139     uint32_t width_;
140     uint32_t height_;
141     VideoPixelFormat pixelFormat_;
142 
143     mutable OSAL::Mutex avMutex_ {};
144     State state_ {State::CREATED};
145     std::shared_ptr<AVCodecContext> avCodecContext_ {};
146     OHOS::Media::BlockingQueue<std::shared_ptr<Buffer>> outBufferQ_;
147     std::shared_ptr<OHOS::Media::OSAL::Task> decodeTask_;
148 };
149 }
150 }
151 }
152 }
153 #endif
154 #endif // HISTREAMER_VIDEO_FFMPEG_DECODER_PLUGIN_H
155