Add support for parsing VPx track codec private data.
Currently only the VP9 profile level is supported. http://www.webmproject.org/vp9/profiles/ Change-Id: Iff7238e104621b53fdd51a67d752bd72b2dbbacb
This commit is contained in:
@@ -111,4 +111,72 @@ bool CopyColour(const mkvparser::Colour& parser_colour,
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format of VPx private data:
|
||||||
|
//
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | ID Byte | Length | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||||
|
// | |
|
||||||
|
// : Bytes 1..Length of Codec Feature :
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
// ID Byte Format
|
||||||
|
// ID byte is an unsigned byte.
|
||||||
|
// 0 1 2 3 4 5 6 7
|
||||||
|
// +-+-+-+-+-+-+-+-+
|
||||||
|
// |X| ID |
|
||||||
|
// +-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
// The X bit is reserved.
|
||||||
|
//
|
||||||
|
// Currently only profile level is supported. ID byte must be set to 1, and
|
||||||
|
// length must be 1. Supported values are:
|
||||||
|
//
|
||||||
|
// 10: Level 1
|
||||||
|
// 11: Level 1.1
|
||||||
|
// 20: Level 2
|
||||||
|
// 21: Level 2.1
|
||||||
|
// 30: Level 3
|
||||||
|
// 31: Level 3.1
|
||||||
|
// 40: Level 4
|
||||||
|
// 41: Level 4.1
|
||||||
|
// 50: Level 5
|
||||||
|
// 51: Level 5.1
|
||||||
|
// 52: Level 5.2
|
||||||
|
// 60: Level 6
|
||||||
|
// 61: Level 6.1
|
||||||
|
// 62: Level 6.2
|
||||||
|
//
|
||||||
|
// See the following link for more information:
|
||||||
|
// http://www.webmproject.org/vp9/profiles/
|
||||||
|
int ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length) {
|
||||||
|
const int kVpxCodecPrivateLength = 3;
|
||||||
|
if (!private_data || length != kVpxCodecPrivateLength)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const uint8_t id_byte = *private_data;
|
||||||
|
if (id_byte != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const int kVpxProfileLength = 1;
|
||||||
|
const uint8_t length_byte = private_data[1];
|
||||||
|
if (length_byte != kVpxProfileLength)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const int level = static_cast<int>(private_data[2]);
|
||||||
|
|
||||||
|
const int kNumLevels = 14;
|
||||||
|
const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40,
|
||||||
|
41, 50, 51, 52, 60, 61, 62};
|
||||||
|
|
||||||
|
for (int i = 0; i < kNumLevels; ++i) {
|
||||||
|
if (level == levels[i])
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} // namespace libwebm
|
} // namespace libwebm
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#ifndef LIBWEBM_COMMON_HDR_UTIL_H_
|
#ifndef LIBWEBM_COMMON_HDR_UTIL_H_
|
||||||
#define LIBWEBM_COMMON_HDR_UTIL_H_
|
#define LIBWEBM_COMMON_HDR_UTIL_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "mkvmuxer/mkvmuxer.h"
|
#include "mkvmuxer/mkvmuxer.h"
|
||||||
@@ -41,6 +43,9 @@ bool ColourValuePresent(long long value);
|
|||||||
bool CopyColour(const mkvparser::Colour& parser_colour,
|
bool CopyColour(const mkvparser::Colour& parser_colour,
|
||||||
mkvmuxer::Colour* muxer_colour);
|
mkvmuxer::Colour* muxer_colour);
|
||||||
|
|
||||||
|
// Returns VP9 profile upon success or 0 upon failure.
|
||||||
|
int ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length);
|
||||||
|
|
||||||
} // namespace libwebm
|
} // namespace libwebm
|
||||||
|
|
||||||
#endif // LIBWEBM_COMMON_HDR_UTIL_H_
|
#endif // LIBWEBM_COMMON_HDR_UTIL_H_
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "common/hdr_util.h"
|
||||||
#include "mkvparser/mkvparser.h"
|
#include "mkvparser/mkvparser.h"
|
||||||
#include "mkvparser/mkvreader.h"
|
#include "mkvparser/mkvreader.h"
|
||||||
#include "testing/test_util.h"
|
#include "testing/test_util.h"
|
||||||
@@ -662,6 +663,27 @@ TEST_F(ParserTest, StereoModeParsedCorrectly) {
|
|||||||
EXPECT_EQ(144, video_track->GetDisplayHeight());
|
EXPECT_EQ(144, video_track->GetDisplayHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserTest, Vp9CodecProfileTest) {
|
||||||
|
const int kCodecPrivateLength = 3;
|
||||||
|
|
||||||
|
// Test invalid codec private data; all of these should return 0.
|
||||||
|
const uint8_t bad_codec_private[kCodecPrivateLength] = {0, 0, 0};
|
||||||
|
EXPECT_EQ(0, libwebm::ParseVpxCodecPrivate(NULL, kCodecPrivateLength));
|
||||||
|
EXPECT_EQ(0, libwebm::ParseVpxCodecPrivate(&bad_codec_private[0], 0));
|
||||||
|
EXPECT_EQ(0, libwebm::ParseVpxCodecPrivate(&bad_codec_private[0],
|
||||||
|
kCodecPrivateLength));
|
||||||
|
const uint8_t good_codec_private[kCodecPrivateLength] = {1, 1, 11};
|
||||||
|
|
||||||
|
// Test parse of codec private chunks, but lie about length.
|
||||||
|
EXPECT_EQ(0, libwebm::ParseVpxCodecPrivate(&bad_codec_private[0], 0));
|
||||||
|
EXPECT_EQ(0, libwebm::ParseVpxCodecPrivate(&good_codec_private[0], 0));
|
||||||
|
|
||||||
|
// Test a valid codec private; this should return 11.
|
||||||
|
// ID: 1, Length: 1, Profile: 11
|
||||||
|
EXPECT_EQ(11, libwebm::ParseVpxCodecPrivate(&good_codec_private[0],
|
||||||
|
kCodecPrivateLength));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|||||||
15
webm_info.cc
15
webm_info.cc
@@ -16,6 +16,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/hdr_util.h"
|
||||||
#include "common/indent.h"
|
#include "common/indent.h"
|
||||||
#include "common/webm_constants.h"
|
#include "common/webm_constants.h"
|
||||||
#include "common/webm_endian.h"
|
#include "common/webm_endian.h"
|
||||||
@@ -364,10 +365,22 @@ bool OutputTracks(const mkvparser::Segment& segment, const Options& options,
|
|||||||
size_t private_size;
|
size_t private_size;
|
||||||
const unsigned char* const private_data =
|
const unsigned char* const private_data =
|
||||||
track->GetCodecPrivate(private_size);
|
track->GetCodecPrivate(private_size);
|
||||||
if (private_data)
|
if (private_data) {
|
||||||
fprintf(o, "%sPrivateData(size): %d\n", indent->indent_str().c_str(),
|
fprintf(o, "%sPrivateData(size): %d\n", indent->indent_str().c_str(),
|
||||||
static_cast<int>(private_size));
|
static_cast<int>(private_size));
|
||||||
|
|
||||||
|
if (track_type == mkvparser::Track::kVideo) {
|
||||||
|
const std::string codec_id = track->GetCodecId();
|
||||||
|
const std::string v_vp9 = "V_VP9";
|
||||||
|
if (codec_id == v_vp9) {
|
||||||
|
const int vp9_profile_level =
|
||||||
|
libwebm::ParseVpxCodecPrivate(private_data, private_size);
|
||||||
|
fprintf(o, "%sVP9 profile level: %d\n", indent->indent_str().c_str(),
|
||||||
|
vp9_profile_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t default_duration = track->GetDefaultDuration();
|
const uint64_t default_duration = track->GetDefaultDuration();
|
||||||
if (default_duration > 0)
|
if (default_duration > 0)
|
||||||
fprintf(o, "%sDefaultDuration: %" PRIu64 "\n",
|
fprintf(o, "%sDefaultDuration: %" PRIu64 "\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user