Internal change
PiperOrigin-RevId: 506345436
This commit is contained in:
parent
0919a6c0a3
commit
83e33b4dbe
|
@ -40,16 +40,19 @@ cc_library(
|
||||||
srcs = ["external_file_handler.cc"],
|
srcs = ["external_file_handler.cc"],
|
||||||
hdrs = ["external_file_handler.h"],
|
hdrs = ["external_file_handler.h"],
|
||||||
deps = [
|
deps = [
|
||||||
"//mediapipe/framework/port:integral_types",
|
|
||||||
"//mediapipe/framework/port:status",
|
|
||||||
"//mediapipe/tasks/cc:common",
|
|
||||||
"//mediapipe/tasks/cc/core/proto:external_file_cc_proto",
|
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/status",
|
"@com_google_absl//absl/status",
|
||||||
"@com_google_absl//absl/status:statusor",
|
"@com_google_absl//absl/status:statusor",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/strings:str_format",
|
||||||
],
|
"//mediapipe/framework/port:integral_types",
|
||||||
|
"//mediapipe/framework/port:status",
|
||||||
|
"//mediapipe/tasks/cc:common",
|
||||||
|
"//mediapipe/tasks/cc/core/proto:external_file_cc_proto",
|
||||||
|
] + select({
|
||||||
|
"//mediapipe:windows": ["@bazel_tools//tools/cpp/runfiles"],
|
||||||
|
"//conditions:default": [],
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
|
|
|
@ -37,12 +37,17 @@ limitations under the License.
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
|
#include "absl/strings/match.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "mediapipe/framework/port/status_macros.h"
|
#include "mediapipe/framework/port/status_macros.h"
|
||||||
#include "mediapipe/tasks/cc/common.h"
|
#include "mediapipe/tasks/cc/common.h"
|
||||||
#include "mediapipe/tasks/cc/core/proto/external_file.pb.h"
|
#include "mediapipe/tasks/cc/core/proto/external_file.pb.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "tools/cpp/runfiles/runfiles.h"
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
namespace mediapipe {
|
namespace mediapipe {
|
||||||
namespace tasks {
|
namespace tasks {
|
||||||
namespace core {
|
namespace core {
|
||||||
|
@ -50,13 +55,21 @@ namespace {
|
||||||
|
|
||||||
using ::absl::StatusCode;
|
using ::absl::StatusCode;
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#ifdef _O_BINARY
|
||||||
|
#define O_BINARY _O_BINARY
|
||||||
|
#else
|
||||||
|
#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
|
||||||
|
#endif // _O_BINARY
|
||||||
|
#endif // O_BINARY
|
||||||
|
|
||||||
// Gets the offset aligned to page size for mapping given files into memory by
|
// Gets the offset aligned to page size for mapping given files into memory by
|
||||||
// file descriptor correctly, as according to mmap(2), the offset used in mmap
|
// file descriptor correctly, as according to mmap(2), the offset used in mmap
|
||||||
// must be a multiple of sysconf(_SC_PAGE_SIZE).
|
// must be a multiple of sysconf(_SC_PAGE_SIZE).
|
||||||
int64 GetPageSizeAlignedOffset(int64 offset) {
|
int64 GetPageSizeAlignedOffset(int64 offset) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// mmap is not used on Windows
|
// mmap is not used on Windows
|
||||||
return -1;
|
return 0;
|
||||||
#else
|
#else
|
||||||
int64 aligned_offset = offset;
|
int64 aligned_offset = offset;
|
||||||
int64 page_size = sysconf(_SC_PAGE_SIZE);
|
int64 page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
|
@ -64,7 +77,7 @@ int64 GetPageSizeAlignedOffset(int64 offset) {
|
||||||
aligned_offset = offset / page_size * page_size;
|
aligned_offset = offset / page_size * page_size;
|
||||||
}
|
}
|
||||||
return aligned_offset;
|
return aligned_offset;
|
||||||
#endif
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -83,6 +96,24 @@ ExternalFileHandler::CreateFromExternalFile(
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<std::string> PathToResourceAsFile(std::string path) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
return path;
|
||||||
|
#else
|
||||||
|
if (absl::StartsWith(path, "./")) {
|
||||||
|
path = "mediapipe" + path.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::unique_ptr<::bazel::tools::cpp::runfiles::Runfiles> runfiles(
|
||||||
|
::bazel::tools::cpp::runfiles::Runfiles::Create("", &error));
|
||||||
|
if (!runfiles) {
|
||||||
|
return absl::InternalError("Unable to initialize runfiles: " + error);
|
||||||
|
}
|
||||||
|
return runfiles->Rlocation(path);
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
|
||||||
absl::Status ExternalFileHandler::MapExternalFile() {
|
absl::Status ExternalFileHandler::MapExternalFile() {
|
||||||
if (!external_file_.file_content().empty()) {
|
if (!external_file_.file_content().empty()) {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
|
@ -101,12 +132,6 @@ absl::Status ExternalFileHandler::MapExternalFile() {
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add Windows support
|
|
||||||
#ifdef _WIN32
|
|
||||||
return CreateStatusWithPayload(StatusCode::kFailedPrecondition,
|
|
||||||
"File loading is not yet supported on Windows",
|
|
||||||
MediaPipeTasksStatus::kFileReadError);
|
|
||||||
#else
|
|
||||||
if (external_file_.file_name().empty() &&
|
if (external_file_.file_name().empty() &&
|
||||||
!external_file_.has_file_descriptor_meta()) {
|
!external_file_.has_file_descriptor_meta()) {
|
||||||
return CreateStatusWithPayload(
|
return CreateStatusWithPayload(
|
||||||
|
@ -118,7 +143,9 @@ absl::Status ExternalFileHandler::MapExternalFile() {
|
||||||
// Obtain file descriptor, offset and size.
|
// Obtain file descriptor, offset and size.
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
if (!external_file_.file_name().empty()) {
|
if (!external_file_.file_name().empty()) {
|
||||||
owned_fd_ = open(external_file_.file_name().c_str(), O_RDONLY);
|
ASSIGN_OR_RETURN(std::string file_name,
|
||||||
|
PathToResourceAsFile(external_file_.file_name()));
|
||||||
|
owned_fd_ = open(file_name.c_str(), O_RDONLY | O_BINARY);
|
||||||
if (owned_fd_ < 0) {
|
if (owned_fd_ < 0) {
|
||||||
const std::string error_message = absl::StrFormat(
|
const std::string error_message = absl::StrFormat(
|
||||||
"Unable to open file at %s", external_file_.file_name());
|
"Unable to open file at %s", external_file_.file_name());
|
||||||
|
@ -149,6 +176,12 @@ absl::Status ExternalFileHandler::MapExternalFile() {
|
||||||
}
|
}
|
||||||
fd = owned_fd_;
|
fd = owned_fd_;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return CreateStatusWithPayload(
|
||||||
|
StatusCode::kFailedPrecondition,
|
||||||
|
"File descriptors are not supported on Windows.",
|
||||||
|
MediaPipeTasksStatus::kFileReadError);
|
||||||
|
#else
|
||||||
fd = external_file_.file_descriptor_meta().fd();
|
fd = external_file_.file_descriptor_meta().fd();
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return CreateStatusWithPayload(
|
return CreateStatusWithPayload(
|
||||||
|
@ -158,6 +191,7 @@ absl::Status ExternalFileHandler::MapExternalFile() {
|
||||||
}
|
}
|
||||||
buffer_offset_ = external_file_.file_descriptor_meta().offset();
|
buffer_offset_ = external_file_.file_descriptor_meta().offset();
|
||||||
buffer_size_ = external_file_.file_descriptor_meta().length();
|
buffer_size_ = external_file_.file_descriptor_meta().length();
|
||||||
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
// Get actual file size. Always use 0 as offset to lseek(2) to get the actual
|
// Get actual file size. Always use 0 as offset to lseek(2) to get the actual
|
||||||
// file size, as SEEK_END returns the size of the file *plus* offset.
|
// file size, as SEEK_END returns the size of the file *plus* offset.
|
||||||
|
@ -189,22 +223,37 @@ absl::Status ExternalFileHandler::MapExternalFile() {
|
||||||
buffer_size_ + buffer_offset_, file_size),
|
buffer_size_ + buffer_offset_, file_size),
|
||||||
MediaPipeTasksStatus::kInvalidArgumentError);
|
MediaPipeTasksStatus::kInvalidArgumentError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If buffer_offset_ is not multiple of sysconf(_SC_PAGE_SIZE), align with
|
// If buffer_offset_ is not multiple of sysconf(_SC_PAGE_SIZE), align with
|
||||||
// extra leading bytes and adjust buffer_size_ to account for the extra
|
// extra leading bytes and adjust buffer_size_ to account for the extra
|
||||||
// leading bytes.
|
// leading bytes.
|
||||||
buffer_aligned_offset_ = GetPageSizeAlignedOffset(buffer_offset_);
|
buffer_aligned_offset_ = GetPageSizeAlignedOffset(buffer_offset_);
|
||||||
buffer_aligned_size_ = buffer_size_ + buffer_offset_ - buffer_aligned_offset_;
|
buffer_aligned_size_ = buffer_size_ + buffer_offset_ - buffer_aligned_offset_;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
buffer_ = malloc(file_size);
|
||||||
|
// Return the file pointer back to the beginning of the file
|
||||||
|
lseek(fd, 0L, SEEK_SET);
|
||||||
|
buffer_size_ = read(fd, buffer_, file_size);
|
||||||
|
if (buffer_size_ <= 0) {
|
||||||
|
free(buffer_);
|
||||||
|
buffer_ = nullptr;
|
||||||
|
}
|
||||||
|
#else
|
||||||
// Map into memory.
|
// Map into memory.
|
||||||
buffer_ = mmap(/*addr=*/nullptr, buffer_aligned_size_, PROT_READ, MAP_SHARED,
|
buffer_ = mmap(/*addr=*/nullptr, buffer_aligned_size_, PROT_READ, MAP_SHARED,
|
||||||
fd, buffer_aligned_offset_);
|
fd, buffer_aligned_offset_);
|
||||||
if (buffer_ == MAP_FAILED) {
|
if (buffer_ == MAP_FAILED) {
|
||||||
|
buffer_ = nullptr;
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
if (!buffer_) {
|
||||||
return CreateStatusWithPayload(
|
return CreateStatusWithPayload(
|
||||||
StatusCode::kUnknown,
|
StatusCode::kUnknown,
|
||||||
absl::StrFormat("Unable to map file to memory buffer, errno=%d", errno),
|
absl::StrFormat("Unable to map file to memory buffer, errno=%d", errno),
|
||||||
MediaPipeTasksStatus::kFileMmapError);
|
MediaPipeTasksStatus::kFileMmapError);
|
||||||
}
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::string_view ExternalFileHandler::GetFileContent() {
|
absl::string_view ExternalFileHandler::GetFileContent() {
|
||||||
|
@ -223,11 +272,13 @@ absl::string_view ExternalFileHandler::GetFileContent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalFileHandler::~ExternalFileHandler() {
|
ExternalFileHandler::~ExternalFileHandler() {
|
||||||
#ifndef _WIN32
|
if (buffer_) {
|
||||||
if (buffer_ != MAP_FAILED) {
|
#ifdef _WIN32
|
||||||
|
free(buffer_);
|
||||||
|
#else
|
||||||
munmap(buffer_, buffer_aligned_size_);
|
munmap(buffer_, buffer_aligned_size_);
|
||||||
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (owned_fd_ >= 0) {
|
if (owned_fd_ >= 0) {
|
||||||
close(owned_fd_);
|
close(owned_fd_);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user