Improve AV1 support.

- Require presence of CodecPrivate in AV1 tracks in mkvmuxer and
  mkvmuxer_sample.
- In mkvmuxer_sample, copy CodecPrivate for Video Tracks when
  present.

Change-Id: Ic8e48f8c8b934e543518da19cf17d71b368c30d3
diff --git a/mkvmuxer/mkvmuxer.cc b/mkvmuxer/mkvmuxer.cc
index 566b6bb..9a5433a 100644
--- a/mkvmuxer/mkvmuxer.cc
+++ b/mkvmuxer/mkvmuxer.cc
@@ -773,6 +773,14 @@
   if (!type_ || !codec_id_)
     return false;
 
+  // AV1 tracks require a CodecPrivate. See
+  // https://github.com/Matroska-Org/matroska-specification/blob/av1-mappin/codec/av1.md
+  // TODO(tomfinegan): Update the above link to the AV1 Matroska mappings to
+  // point to a stable version once it is finalized, or our own WebM mappings
+  // page on webmproject.org should we decide to release them.
+  if (!strcmp(codec_id_, Tracks::kAv1CodecId) && !codec_private_)
+    return false;
+
   // |size| may be bigger than what is written out in this function because
   // derived classes may write out more data in the Track element.
   const uint64_t payload_size = PayloadSize();
diff --git a/mkvmuxer_sample.cc b/mkvmuxer_sample.cc
index f6d9b32..581ff20 100644
--- a/mkvmuxer_sample.cc
+++ b/mkvmuxer_sample.cc
@@ -543,48 +543,63 @@
         video->set_frame_rate(rate);
       }
 
-      if (!strcmp(video->codec_id(), mkvmuxer::Tracks::kVp9CodecId)) {
-        if (vp9_profile >= 0 || vp9_level >= 0) {
-          const int kMaxVp9PrivateSize = 6;
-          unsigned char private_data[kMaxVp9PrivateSize];
-          int private_size = 0;
-          if (vp9_profile >= 0) {
-            if (vp9_profile < 0 || vp9_profile > 3) {
-              printf("\n VP9 profile(%d) is not valid.\n", vp9_profile);
-              return EXIT_FAILURE;
-            }
-            const uint8_t kVp9ProfileId = 1;
-            const uint8_t kVp9ProfileIdLength = 1;
-            private_data[private_size++] = kVp9ProfileId;
-            private_data[private_size++] = kVp9ProfileIdLength;
-            private_data[private_size++] = vp9_profile;
-          }
+      size_t parser_private_size;
+      const unsigned char* const parser_private_data =
+          pVideoTrack->GetCodecPrivate(parser_private_size);
 
-          if (vp9_level >= 0) {
-            const int kNumLevels = 14;
-            const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40,
-                                            41, 50, 51, 52, 60, 61, 62};
-            bool level_is_valid = false;
-            for (int i = 0; i < kNumLevels; ++i) {
-              if (vp9_level == levels[i]) {
-                level_is_valid = true;
-                break;
-              }
-            }
-            if (!level_is_valid) {
-              printf("\n VP9 level(%d) is not valid.\n", vp9_level);
-              return EXIT_FAILURE;
-            }
-            const uint8_t kVp9LevelId = 2;
-            const uint8_t kVp9LevelIdLength = 1;
-            private_data[private_size++] = kVp9LevelId;
-            private_data[private_size++] = kVp9LevelIdLength;
-            private_data[private_size++] = vp9_level;
-          }
-          if (!video->SetCodecPrivate(private_data, private_size)) {
-            printf("\n Could not add video private data.\n");
+      if (!strcmp(video->codec_id(), mkvmuxer::Tracks::kAv1CodecId)) {
+        if (parser_private_data == NULL || parser_private_size == 0) {
+          printf("AV1 input track has no CodecPrivate. %s is invalid.", input);
+          return EXIT_FAILURE;
+        }
+      }
+
+      if (!strcmp(video->codec_id(), mkvmuxer::Tracks::kVp9CodecId) &&
+          (vp9_profile >= 0 || vp9_level >= 0)) {
+        const int kMaxVp9PrivateSize = 6;
+        unsigned char vp9_private_data[kMaxVp9PrivateSize];
+        int vp9_private_size = 0;
+        if (vp9_profile >= 0) {
+          if (vp9_profile < 0 || vp9_profile > 3) {
+            printf("\n VP9 profile(%d) is not valid.\n", vp9_profile);
             return EXIT_FAILURE;
           }
+          const uint8_t kVp9ProfileId = 1;
+          const uint8_t kVp9ProfileIdLength = 1;
+          vp9_private_data[vp9_private_size++] = kVp9ProfileId;
+          vp9_private_data[vp9_private_size++] = kVp9ProfileIdLength;
+          vp9_private_data[vp9_private_size++] = vp9_profile;
+        }
+
+        if (vp9_level >= 0) {
+          const int kNumLevels = 14;
+          const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40,
+                                          41, 50, 51, 52, 60, 61, 62};
+          bool level_is_valid = false;
+          for (int i = 0; i < kNumLevels; ++i) {
+            if (vp9_level == levels[i]) {
+              level_is_valid = true;
+              break;
+            }
+          }
+          if (!level_is_valid) {
+            printf("\n VP9 level(%d) is not valid.\n", vp9_level);
+            return EXIT_FAILURE;
+          }
+          const uint8_t kVp9LevelId = 2;
+          const uint8_t kVp9LevelIdLength = 1;
+          vp9_private_data[vp9_private_size++] = kVp9LevelId;
+          vp9_private_data[vp9_private_size++] = kVp9LevelIdLength;
+          vp9_private_data[vp9_private_size++] = vp9_level;
+        }
+        if (!video->SetCodecPrivate(vp9_private_data, vp9_private_size)) {
+          printf("\n Could not add video private data.\n");
+          return EXIT_FAILURE;
+        }
+      } else if (parser_private_data && parser_private_size > 0) {
+        if (!video->SetCodecPrivate(parser_private_data, parser_private_size)) {
+          printf("\n Could not add video private data.\n");
+          return EXIT_FAILURE;
         }
       }
     } else if (track_type == Track::kAudio && output_audio) {