• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define HST_LOG_TAG "FilePathSinkPlugin"
16 #include "file_path_sink_plugin.h"
17 #include "foundation/log.h"
18 #include "foundation/osal/filesystem/file_system.h"
19 #include "pipeline/filters/common/plugin_utils.h"
20 
21 namespace OHOS {
22 namespace Media {
23 namespace Plugin {
24 namespace FileSink {
FilePathSinkPluginCreator(const std::string & name)25 std::shared_ptr<OutputSinkPlugin> FilePathSinkPluginCreator(const std::string& name)
26 {
27     return std::make_shared<FilePathSinkPlugin>(name);
28 }
29 
FilePathSinkRegister(const std::shared_ptr<Register> & reg)30 Status FilePathSinkRegister(const std::shared_ptr<Register>& reg)
31 {
32     OutputSinkPluginDef definition;
33     definition.protocolType = ProtocolType::FILE;
34     definition.name = "file_path_sink";
35     definition.description = "file path sink";
36     definition.rank = 100; // 100
37     definition.protocolType = ProtocolType::FILE;
38     definition.creator = FilePathSinkPluginCreator;
39     return reg->AddPlugin(definition);
40 }
41 
__anon3d9eb5a70102null42 PLUGIN_DEFINITION(FilePathSink, LicenseType::APACHE_V2, FilePathSinkRegister, [] {});
43 
FilePathSinkPlugin(std::string name)44 FilePathSinkPlugin::FilePathSinkPlugin(std::string name)
45     : OutputSinkPlugin(std::move(name)), fp_(nullptr), seekable_(Seekable::SEEKABLE)
46 {
47 }
48 
~FilePathSinkPlugin()49 FilePathSinkPlugin::~FilePathSinkPlugin()
50 {
51     if (fp_) {
52         MEDIA_LOG_W("close file in dtor");
53         std::fclose(fp_);
54         fp_ = nullptr;
55     }
56 }
57 
Stop()58 Status FilePathSinkPlugin::Stop()
59 {
60     CloseFile();
61     return Status::OK;
62 }
63 
SetSink(const MediaSink & sink)64 Status FilePathSinkPlugin::SetSink(const MediaSink& sink)
65 {
66     FALSE_RETURN_V((sink.GetProtocolType() == ProtocolType::FILE && !sink.GetPath().empty()),
67         Status::ERROR_INVALID_DATA);
68     fileName_ = sink.GetPath();
69     return OpenFile();
70 }
71 
GetSeekable()72 Seekable FilePathSinkPlugin::GetSeekable()
73 {
74     return seekable_;
75 }
76 
SeekTo(uint64_t offset)77 Status FilePathSinkPlugin::SeekTo(uint64_t offset)
78 {
79     FALSE_RETURN_V_MSG_E(fp_ != nullptr, Status::ERROR_WRONG_STATE, "no files have been opened.");
80     if (std::fseek(fp_, offset, SEEK_SET) == 0) {
81         return Status::OK;
82     } else {
83         MEDIA_LOG_W("Seek to " PUBLIC_LOG_U64 " failed due to " PUBLIC_LOG_S, offset, strerror(errno));
84         std::clearerr(fp_);
85     }
86     return Status::ERROR_UNKNOWN;
87 }
88 
Write(const std::shared_ptr<Buffer> & buffer)89 Status FilePathSinkPlugin::Write(const std::shared_ptr<Buffer>& buffer)
90 {
91     MEDIA_LOG_DD("Write begin");
92     if (buffer == nullptr || buffer->IsEmpty()) {
93         return Status::OK;
94     }
95     auto bufferData = buffer->GetMemory();
96     std::fwrite(bufferData->GetReadOnlyData(), bufferData->GetSize(), 1, fp_);
97     return Status::OK;
98 }
99 
Flush()100 Status FilePathSinkPlugin::Flush()
101 {
102     if (fp_) {
103         MEDIA_LOG_I("flush file");
104         std::fflush(fp_);
105     }
106     return Status::OK;
107 }
108 
Reset()109 Status FilePathSinkPlugin::Reset()
110 {
111     return Status::OK;
112 }
OpenFile()113 Status FilePathSinkPlugin::OpenFile()
114 {
115     tmpFileName_ = OSAL::FileSystem::GetTmpFileName();
116     fp_ = std::fopen(tmpFileName_.c_str(), "wb");
117     if (fp_ == nullptr) {
118         int32_t err = errno;
119         MEDIA_LOG_E("Fail to open file due to " PUBLIC_LOG_S, strerror(err));
120         switch (err) {
121             case EPERM:
122                 return Status::ERROR_PERMISSION_DENIED;
123             case ENOENT:
124                 return Status::ERROR_NOT_EXISTED;
125             default:
126                 return Status::ERROR_UNKNOWN;
127         }
128     }
129     MEDIA_LOG_D("open file %s", tmpFileName_.c_str()); // file name is privacy
130     return Status::OK;
131 }
132 
CloseFile()133 void FilePathSinkPlugin::CloseFile()
134 {
135     if (fp_) {
136         MEDIA_LOG_D("close file");
137         std::fclose(fp_);
138         fp_ = nullptr;
139         std::rename(tmpFileName_.c_str(), fileName_.c_str());
140     }
141 }
142 } // namespace FileSink
143 } // namespace Plugin
144 } // namespace Media
145 } // namespace OHOS