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 "DumpBuffer"
16 #define ALL_DUMP_FILES { DEMUXER_INPUT_PEEK, DEMUXER_INPUT_GET, DEMUXER_OUTPUT, DECODER_OUTPUT }
17
18 #include "foundation/utils/dump_buffer.h"
19 #include <cstdio>
20 #include <cstring>
21 #ifdef _WIN32
22 #include <direct.h>
23 #else
24 #include <unistd.h>
25 #endif
26 #include <dirent.h>
27 #include "foundation/log.h"
28 #include "foundation/osal/filesystem/file_system.h"
29 #include "foundation/osal/utils/util.h"
30
31 namespace OHOS {
32 namespace Media {
33 namespace Pipeline {
34 #ifdef _WIN32
35 #define DUMP_FILE_DIR ""
36 #endif
37 // Specify the dump file dir in BUILD.gn
38 #ifndef DUMP_FILE_DIR
39 #define DUMP_FILE_DIR "/data/local/tmp"
40 #endif
41
42 std::map<std::string, FILE*> allDumpFileFds;
43
GetDumpFileDir()44 std::string GetDumpFileDir()
45 {
46 return std::string(DUMP_FILE_DIR);
47 }
48
DumpBufferToFile(const std::string & fileName,const std::shared_ptr<Plugin::Buffer> & buffer)49 void DumpBufferToFile(const std::string& fileName, const std::shared_ptr<Plugin::Buffer>& buffer)
50 {
51 FALSE_RETURN_MSG(allDumpFileFds[fileName] != nullptr, "fd is null");
52 if (buffer->GetMemory() == nullptr) {
53 MEDIA_LOG_E("Get memory failed: nullptr");
54 return;
55 }
56 size_t bufferSize = buffer->GetMemory()->GetSize();
57 FALSE_RETURN(bufferSize != 0);
58 auto addr = reinterpret_cast<const char*>(buffer->GetMemory()->GetReadOnlyData());
59 if (addr == nullptr) {
60 MEDIA_LOG_E("Get address failed: nullptr");
61 return;
62 }
63 (void)fwrite(addr,
64 1, bufferSize, allDumpFileFds[fileName]);
65 }
66
PrepareDumpDir()67 void PrepareDumpDir()
68 {
69 MEDIA_LOG_I("Prepare dumpDir enter.");
70 for (auto iter : ALL_DUMP_FILES) {
71 std::string filePath = GetDumpFileDir() + "/" + iter;
72 MEDIA_LOG_I("Prepare dumpDir: " PUBLIC_LOG_S, filePath.c_str());
73 std::string fullPath;
74 bool isFileExist = OSAL::ConvertFullPath(filePath, fullPath);
75 if (isFileExist) { // 文件存在
76 OSAL::FileSystem::ClearFileContent(fullPath);
77 }
78 char path[PATH_MAX] = {0};
79 auto realPath = realpath(fullPath.c_str(), path);
80 FALSE_RETURN(realPath != nullptr);
81 allDumpFileFds[iter] = fopen(realPath, "ab+");
82 if (allDumpFileFds[iter] == nullptr) {
83 MEDIA_LOG_W("Open file(" PUBLIC_LOG_S ") failed(" PUBLIC_LOG_S ").", fullPath.c_str(), strerror(errno));
84 }
85 }
86 }
87
EndDumpFile()88 void EndDumpFile()
89 {
90 MEDIA_LOG_I("End dump enter.");
91 for (auto iter : ALL_DUMP_FILES) {
92 if (allDumpFileFds[iter]) {
93 fclose(allDumpFileFds[iter]);
94 allDumpFileFds[iter] = nullptr;
95 }
96 }
97 }
98
DumpBufferToLog(const char * desc,const std::shared_ptr<Plugin::Buffer> & buffer,uint64_t offset,size_t dumpSize)99 void DumpBufferToLog(const char* desc, const std::shared_ptr<Plugin::Buffer>& buffer, uint64_t offset, size_t dumpSize)
100 {
101 FALSE_RETURN_MSG(buffer && (!buffer->IsEmpty()), PUBLIC_LOG_S " Buffer(null or empty)", desc);
102 size_t bufferSize = buffer->GetMemory()->GetSize();
103 size_t realDumpSize = std::min(dumpSize, bufferSize);
104 realDumpSize = std::min(realDumpSize, static_cast<size_t>(DUMP_BUFFER2LOG_SIZE)); // max DUMP_BUFFER2LOG_SIZE bytes
105 char tmpStr[2 * DUMP_BUFFER2LOG_SIZE + 10] = {0}; // 字符串长度是打印的buffer长度的2倍 + 1 (字符串结束符)
106 char* dstPtr = tmpStr;
107 int len;
108 const uint8_t* p = buffer->GetMemory()->GetReadOnlyData();
109 for (size_t i = 0; i < realDumpSize; i++) {
110 len = snprintf_s(dstPtr, 3, 2, "%02x", p[i]); // max write 3 bytes, string len 2
111 FALSE_RETURN_MSG(len > 0 && len <= 2, "snprintf_s returned unexpected value " PUBLIC_LOG_D32, len); // max len 2
112 dstPtr += len;
113 }
114 MEDIA_LOG_I(PUBLIC_LOG_S " Buffer(offset " PUBLIC_LOG_D64 ", size " PUBLIC_LOG_ZU ", capacity "
115 PUBLIC_LOG_ZU ") : " PUBLIC_LOG_S, desc, offset, bufferSize, buffer->GetMemory()->GetCapacity(), tmpStr);
116 }
117 } // Pipeline
118 } // Media
119 } // OHOS