Add support for overriding PixelWidth and PixelHeight.

Change-Id: I226f6bb6be99e71373fcbd8ec9b9d556064305e4
diff --git a/mkvmuxer/mkvmuxer.cc b/mkvmuxer/mkvmuxer.cc
index f48d282..31920c7 100644
--- a/mkvmuxer/mkvmuxer.cc
+++ b/mkvmuxer/mkvmuxer.cc
@@ -1403,6 +1403,8 @@
     : Track(seed),
       display_height_(0),
       display_width_(0),
+      pixel_height_(0),
+      pixel_width_(0),
       crop_left_(0),
       crop_right_(0),
       crop_top_(0),
@@ -1461,11 +1463,13 @@
   if (payload_position < 0)
     return false;
 
-  if (!WriteEbmlElement(writer, libwebm::kMkvPixelWidth,
-                        static_cast<uint64>(width_)))
+  if (!WriteEbmlElement(
+          writer, libwebm::kMkvPixelWidth,
+          static_cast<uint64>((pixel_width_ > 0) ? pixel_width_ : width_)))
     return false;
-  if (!WriteEbmlElement(writer, libwebm::kMkvPixelHeight,
-                        static_cast<uint64>(height_)))
+  if (!WriteEbmlElement(
+          writer, libwebm::kMkvPixelHeight,
+          static_cast<uint64>((pixel_height_ > 0) ? pixel_height_ : height_)))
     return false;
   if (display_width_ > 0) {
     if (!WriteEbmlElement(writer, libwebm::kMkvDisplayWidth,
@@ -1581,10 +1585,12 @@
 }
 
 uint64_t VideoTrack::VideoPayloadSize() const {
-  uint64_t size =
-      EbmlElementSize(libwebm::kMkvPixelWidth, static_cast<uint64>(width_));
-  size +=
-      EbmlElementSize(libwebm::kMkvPixelHeight, static_cast<uint64>(height_));
+  uint64_t size = EbmlElementSize(
+      libwebm::kMkvPixelWidth,
+      static_cast<uint64>((pixel_width_ > 0) ? pixel_width_ : width_));
+  size += EbmlElementSize(
+      libwebm::kMkvPixelHeight,
+      static_cast<uint64>((pixel_height_ > 0) ? pixel_height_ : height_));
   if (display_width_ > 0)
     size += EbmlElementSize(libwebm::kMkvDisplayWidth,
                             static_cast<uint64>(display_width_));
@@ -3534,7 +3540,6 @@
 
   if (frame_created)
     delete frame;
-
   return true;
 }
 
diff --git a/mkvmuxer/mkvmuxer.h b/mkvmuxer/mkvmuxer.h
index 5868266..c3c1c59 100644
--- a/mkvmuxer/mkvmuxer.h
+++ b/mkvmuxer/mkvmuxer.h
@@ -773,6 +773,10 @@
   uint64_t display_height() const { return display_height_; }
   void set_display_width(uint64_t width) { display_width_ = width; }
   uint64_t display_width() const { return display_width_; }
+  void set_pixel_height(uint64_t height) { pixel_height_ = height; }
+  uint64_t pixel_height() const { return pixel_height_; }
+  void set_pixel_width(uint64_t width) { pixel_width_ = width; }
+  uint64_t pixel_width() const { return pixel_width_; }
 
   void set_crop_left(uint64_t crop_left) { crop_left_ = crop_left; }
   uint64_t crop_left() const { return crop_left_; }
@@ -809,6 +813,8 @@
   // Video track element names.
   uint64_t display_height_;
   uint64_t display_width_;
+  uint64_t pixel_height_;
+  uint64_t pixel_width_;
   uint64_t crop_left_;
   uint64_t crop_right_;
   uint64_t crop_top_;
diff --git a/mkvmuxer_sample.cc b/mkvmuxer_sample.cc
index 473b05a..43ae997 100644
--- a/mkvmuxer_sample.cc
+++ b/mkvmuxer_sample.cc
@@ -59,6 +59,8 @@
   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("\n");
   printf("VP9 options:\n");
@@ -177,6 +179,8 @@
 
   uint64_t display_width = 0;
   uint64_t display_height = 0;
+  uint64_t pixel_width = 0;
+  uint64_t pixel_height = 0;
   uint64_t stereo_mode = 0;
   int vp9_profile = -1;  // No profile set.
   int vp9_level = -1;  // No level set.
@@ -242,6 +246,10 @@
       display_width = strtol(argv[++i], &end, 10);
     } else if (!strcmp("-display_height", argv[i]) && i < argc_check) {
       display_height = strtol(argv[++i], &end, 10);
+    } else if (!strcmp("-pixel_width", argv[i]) && i < argc_check) {
+      pixel_width = strtol(argv[++i], &end, 10);
+    } else if (!strcmp("-pixel_height", argv[i]) && i < argc_check) {
+      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("-profile", argv[i]) && i < argc_check) {
@@ -447,6 +455,10 @@
         video->set_display_width(display_width);
       if (display_height > 0)
         video->set_display_height(display_height);
+      if (pixel_width > 0)
+        video->set_pixel_width(pixel_width);
+      if (pixel_height > 0)
+        video->set_pixel_height(pixel_height);
       if (stereo_mode > 0)
         video->SetStereoMode(stereo_mode);
 
diff --git a/testing/mkvmuxer_tests.cc b/testing/mkvmuxer_tests.cc
index 68e279d..2a72589 100644
--- a/testing/mkvmuxer_tests.cc
+++ b/testing/mkvmuxer_tests.cc
@@ -968,6 +968,28 @@
       CompareFiles(GetTestFilePath("estimate_duration.webm"), filename_));
 }
 
+TEST_F(MuxerTest, SetPixelWidthPixelHeight) {
+  EXPECT_TRUE(SegmentInit(false, false, false));
+  segment_.set_estimate_file_duration(false);
+  AddVideoTrack();
+  VideoTrack* const video_track =
+      static_cast<VideoTrack*>(segment_.GetTrackByNumber(kVideoTrackNumber));
+  ASSERT_TRUE(video_track != nullptr);
+  video_track->set_pixel_width(500);
+  video_track->set_pixel_height(650);
+
+  EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
+                                false));
+  EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
+                                2000000, false));
+
+  segment_.Finalize();
+  CloseWriter();
+
+  EXPECT_TRUE(CompareFiles(GetTestFilePath("set_pixelwidth_pixelheight.webm"),
+                           filename_));
+}
+
 }  // namespace test
 
 int main(int argc, char* argv[]) {
diff --git a/testing/testdata/set_pixelwidth_pixelheight.webm b/testing/testdata/set_pixelwidth_pixelheight.webm
new file mode 100644
index 0000000..e81c8bc
--- /dev/null
+++ b/testing/testdata/set_pixelwidth_pixelheight.webm
Binary files differ