Add command line support for projection_type
Add command line for projection_type, projection_pose_{yaw,pitch,roll}.
Use a file for projection_private data to allow setting the contents
for cubemap, equirect, or mesh.
Change-Id: I45f20c68a5d01150d0fb3882ad1c587a8b9f63f2
diff --git a/common/file_util.cc b/common/file_util.cc
index 6dab146..252e74b 100644
--- a/common/file_util.cc
+++ b/common/file_util.cc
@@ -65,6 +65,15 @@
return file_size;
}
+bool GetFileContents(const std::string& file_name, std::string* contents) {
+ std::ifstream file(file_name.c_str());
+ *contents = std::string(static_cast<size_t>(GetFileSize(file_name)), 0);
+ if (file.good() && contents->size()) {
+ file.read(&(*contents)[0], contents->size());
+ }
+ return !file.fail();
+}
+
TempFileDeleter::TempFileDeleter() { file_name_ = GetTempFileName(); }
TempFileDeleter::~TempFileDeleter() {
diff --git a/common/file_util.h b/common/file_util.h
index 0e71eac..a873734 100644
--- a/common/file_util.h
+++ b/common/file_util.h
@@ -22,6 +22,9 @@
// Returns size of file specified by |file_name|, or 0 upon failure.
uint64_t GetFileSize(const std::string& file_name);
+// Gets the contents file_name as a string. Returns false on error.
+bool GetFileContents(const std::string& file_name, std::string* contents);
+
// Manages life of temporary file specified at time of construction. Deletes
// file upon destruction.
class TempFileDeleter {
@@ -38,4 +41,4 @@
} // namespace libwebm
-#endif // LIBWEBM_COMMON_FILE_UTIL_H_
\ No newline at end of file
+#endif // LIBWEBM_COMMON_FILE_UTIL_H_
diff --git a/mkvmuxer_sample.cc b/mkvmuxer_sample.cc
index b590c89..e534582 100644
--- a/mkvmuxer_sample.cc
+++ b/mkvmuxer_sample.cc
@@ -62,11 +62,21 @@
printf(" -copy_input_duration >0 Copies the input duration\n");
printf("\n");
printf("Video options:\n");
- printf(" -display_width <int> Display width in pixels\n");
- printf(" -display_height <int> Display height in pixels\n");
- printf(" -pixel_width <int> Override pixel width\n");
- printf(" -pixel_height <int> Override pixel height\n");
- printf(" -stereo_mode <int> 3D video mode\n");
+ printf(" -display_width <int> Display width in pixels\n");
+ printf(" -display_height <int> Display height in pixels\n");
+ printf(" -pixel_width <int> Override pixel width\n");
+ printf(" -pixel_height <int> Override pixel height\n");
+ printf(" -projection_type <int> Set/override projection type:\n");
+ printf(" 0: Rectangular\n");
+ printf(" 1: Equirectangular\n");
+ printf(" 2: Cube map\n");
+ printf(" 3: Mesh\n");
+ printf(" -projection_file <string> Override projection private data");
+ printf(" with contents of this file\n");
+ printf(" -projection_pose_yaw <float> Projection pose yaw\n");
+ printf(" -projection_pose_pitch <float> Projection pose pitch\n");
+ printf(" -projection_pose_roll <float> Projection pose roll\n");
+ printf(" -stereo_mode <int> 3D video mode\n");
printf("\n");
printf("VP9 options:\n");
printf(" -profile <int> VP9 profile\n");
@@ -154,6 +164,32 @@
return 0; // not a WebVTT arg
}
+bool CopyVideoProjection(const mkvparser::Projection& parser_projection,
+ mkvmuxer::Projection* muxer_projection) {
+ typedef mkvmuxer::Projection::ProjectionType MuxerProjType;
+ const int kTypeNotPresent = mkvparser::Projection::kTypeNotPresent;
+ if (parser_projection.type != kTypeNotPresent) {
+ muxer_projection->set_type(
+ static_cast<MuxerProjType>(parser_projection.type));
+ }
+ if (parser_projection.private_data &&
+ parser_projection.private_data_length > 0) {
+ if (!muxer_projection->SetProjectionPrivate(
+ parser_projection.private_data,
+ parser_projection.private_data_length)) {
+ return false;
+ }
+ }
+
+ const float kValueNotPresent = mkvparser::Projection::kValueNotPresent;
+ if (parser_projection.pose_yaw != kValueNotPresent)
+ muxer_projection->set_pose_yaw(parser_projection.pose_yaw);
+ if (parser_projection.pose_pitch != kValueNotPresent)
+ muxer_projection->set_pose_pitch(parser_projection.pose_pitch);
+ if (parser_projection.pose_roll != kValueNotPresent)
+ muxer_projection->set_pose_roll(parser_projection.pose_roll);
+ return true;
+}
} // end namespace
int main(int argc, char* argv[]) {
@@ -187,6 +223,11 @@
uint64_t pixel_width = 0;
uint64_t pixel_height = 0;
uint64_t stereo_mode = 0;
+ const char* projection_file = 0;
+ int64_t projection_type = mkvparser::Projection::kTypeNotPresent;
+ float projection_pose_roll = mkvparser::Projection::kValueNotPresent;
+ float projection_pose_pitch = mkvparser::Projection::kValueNotPresent;
+ float projection_pose_yaw = mkvparser::Projection::kValueNotPresent;
int vp9_profile = -1; // No profile set.
int vp9_level = -1; // No level set.
@@ -257,6 +298,16 @@
pixel_height = strtol(argv[++i], &end, 10);
} else if (!strcmp("-stereo_mode", argv[i]) && i < argc_check) {
stereo_mode = strtol(argv[++i], &end, 10);
+ } else if (!strcmp("-projection_type", argv[i]) && i < argc_check) {
+ projection_type = strtol(argv[++i], &end, 10);
+ } else if (!strcmp("-projection_file", argv[i]) && i < argc_check) {
+ projection_file = argv[++i];
+ } else if (!strcmp("-projection_pose_roll", argv[i]) && i < argc_check) {
+ projection_pose_roll = strtof(argv[++i], &end);
+ } else if (!strcmp("-projection_pose_pitch", argv[i]) && i < argc_check) {
+ projection_pose_pitch = strtof(argv[++i], &end);
+ } else if (!strcmp("-projection_pose_yaw", argv[i]) && i < argc_check) {
+ projection_pose_yaw = strtof(argv[++i], &end);
} else if (!strcmp("-profile", argv[i]) && i < argc_check) {
vp9_profile = static_cast<int>(strtol(argv[++i], &end, 10));
} else if (!strcmp("-level", argv[i]) && i < argc_check) {
@@ -422,32 +473,56 @@
return EXIT_FAILURE;
}
- if (pVideoTrack->GetProjection()) {
+ if (pVideoTrack->GetProjection() ||
+ projection_type != mkvparser::Projection::kTypeNotPresent) {
mkvmuxer::Projection muxer_projection;
const mkvparser::Projection* const parser_projection =
pVideoTrack->GetProjection();
typedef mkvmuxer::Projection::ProjectionType MuxerProjType;
- const int kTypeNotPresent = mkvparser::Projection::kTypeNotPresent;
- if (parser_projection->type != kTypeNotPresent) {
- muxer_projection.set_type(
- static_cast<MuxerProjType>(parser_projection->type));
+ if (parser_projection &&
+ !CopyVideoProjection(*parser_projection, &muxer_projection)) {
+ printf("\n Unable to copy video projection.\n");
+ return EXIT_FAILURE;
}
- if (parser_projection->private_data &&
- parser_projection->private_data_length > 0) {
- if (!muxer_projection.SetProjectionPrivate(
- parser_projection->private_data,
- parser_projection->private_data_length)) {
+ // Override the values that came from parser if set on command line.
+ if (projection_type != mkvparser::Projection::kTypeNotPresent) {
+ muxer_projection.set_type(
+ static_cast<MuxerProjType>(projection_type));
+ if (projection_type == mkvparser::Projection::kRectangular &&
+ projection_file != NULL) {
+ printf("\n Rectangular projection must not have private data.\n");
+ return EXIT_FAILURE;
+ } else if ((projection_type == mkvparser::Projection::kCubeMap ||
+ projection_type == mkvparser::Projection::kMesh) &&
+ projection_file == NULL) {
+ printf("\n Mesh or CubeMap projection must have private data.\n");
return EXIT_FAILURE;
}
+ if (projection_file != NULL) {
+ std::string contents;
+ if (!libwebm::GetFileContents(projection_file, &contents) ||
+ contents.size() == 0) {
+ printf("\n Failed to read file \"%s\" or file is empty\n",
+ projection_file);
+ return EXIT_FAILURE;
+ }
+ if (!muxer_projection.SetProjectionPrivate(
+ reinterpret_cast<uint8_t*>(&contents[0]),
+ contents.size())) {
+ printf("\n Failed to SetProjectionPrivate of length %zu.\n",
+ contents.size());
+ return EXIT_FAILURE;
+ }
+ }
}
-
const float kValueNotPresent = mkvparser::Projection::kValueNotPresent;
- if (parser_projection->pose_yaw != kValueNotPresent)
- muxer_projection.set_pose_yaw(parser_projection->pose_yaw);
- if (parser_projection->pose_pitch != kValueNotPresent)
- muxer_projection.set_pose_pitch(parser_projection->pose_pitch);
- if (parser_projection->pose_roll != kValueNotPresent)
- muxer_projection.set_pose_roll(parser_projection->pose_roll);
+ if (projection_pose_yaw != kValueNotPresent)
+ muxer_projection.set_pose_yaw(projection_pose_yaw);
+ if (projection_pose_pitch != kValueNotPresent)
+ muxer_projection.set_pose_pitch(projection_pose_pitch);
+ if (projection_pose_roll != kValueNotPresent)
+ muxer_projection.set_pose_roll(projection_pose_roll);
+
if (!video->SetProjection(muxer_projection))
return EXIT_FAILURE;
}