15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_decoder_config.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecoderConfig::VideoDecoderConfig()
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : codec_(kUnknownVideoCodec),
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(VIDEO_CODEC_PROFILE_UNKNOWN),
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      format_(VideoFrame::UNKNOWN),
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_encrypted_(false) {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecoderConfig::VideoDecoderConfig(VideoCodec codec,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       VideoCodecProfile profile,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       VideoFrame::Format format,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Size& coded_size,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& visible_rect,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Size& natural_size,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const uint8* extra_data,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       size_t extra_data_size,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bool is_encrypted) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(codec, profile, format, coded_size, visible_rect, natural_size,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             extra_data, extra_data_size, is_encrypted, true);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoDecoderConfig::~VideoDecoderConfig() {}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some videos just want to watch the world burn, with a height of 0; cap the
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "infinite" aspect ratio resulting.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kInfiniteRatio = 99999;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Common aspect ratios (multiplied by 100 and truncated) used for histogramming
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// video sizes.  These were taken on 20111103 from
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://wikipedia.org/wiki/Aspect_ratio_(image)#Previous_and_currently_used_aspect_ratios
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kCommonAspectRatios100[] = {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  100, 115, 133, 137, 143, 150, 155, 160, 166, 175, 177, 185, 200, 210, 220,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  221, 235, 237, 240, 255, 259, 266, 276, 293, 400, 1200, kInfiniteRatio,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T>  // T has int width() & height() methods.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void UmaHistogramAspectRatio(const char* name, const T& size) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_ENUMERATION(
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Intentionally use integer division to truncate the result.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size.height() ? (size.width() * 100) / size.height() : kInfiniteRatio,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::CustomHistogram::ArrayToCustomRanges(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kCommonAspectRatios100, arraysize(kCommonAspectRatios100)));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecoderConfig::Initialize(VideoCodec codec,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    VideoCodecProfile profile,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    VideoFrame::Format format,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Size& coded_size,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& visible_rect,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Size& natural_size,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const uint8* extra_data,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    size_t extra_data_size,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool is_encrypted,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool record_stats) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK((extra_data_size != 0) == (extra_data != NULL));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (record_stats) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec", codec, kVideoCodecMax + 1);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Drop UNKNOWN because U_H_E() uses one bucket for all values less than 1.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (profile >= 0) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("Media.VideoCodecProfile", profile,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                VIDEO_CODEC_PROFILE_MAX + 1);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_10000("Media.VideoCodedWidth", coded_size.width());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UmaHistogramAspectRatio("Media.VideoCodedAspectRatio", coded_size);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_10000("Media.VideoVisibleWidth", visible_rect.width());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UmaHistogramAspectRatio("Media.VideoVisibleAspectRatio", visible_rect);
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        "Media.VideoPixelFormat", format, VideoFrame::FORMAT_MAX + 1);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_ = codec;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_ = profile;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  format_ = format;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_size_ = coded_size;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visible_rect_ = visible_rect;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  natural_size_ = natural_size;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extra_data_.assign(extra_data, extra_data + extra_data_size);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_encrypted_ = is_encrypted;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoDecoderConfig::IsValidConfig() const {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return codec_ != kUnknownVideoCodec &&
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      natural_size_.width() > 0 &&
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      natural_size_.height() > 0 &&
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VideoFrame::IsValidConfig(format_, coded_size_, visible_rect_,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          natural_size_);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoDecoderConfig::Matches(const VideoDecoderConfig& config) const {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ((codec() == config.codec()) &&
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (format() == config.format()) &&
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (profile() == config.profile()) &&
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (coded_size() == config.coded_size()) &&
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (visible_rect() == config.visible_rect()) &&
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (natural_size() == config.natural_size()) &&
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (extra_data_size() == config.extra_data_size()) &&
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (!extra_data() || !memcmp(extra_data(), config.extra_data(),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    extra_data_size())) &&
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (is_encrypted() == config.is_encrypted()));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string VideoDecoderConfig::AsHumanReadableString() const {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream s;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s << "codec: " << codec()
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " format: " << format()
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " profile: " << profile()
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " coded size: [" << coded_size().width()
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "," << coded_size().height() << "]"
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " visible rect: [" << visible_rect().x()
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "," << visible_rect().y()
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "," << visible_rect().width()
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "," << visible_rect().height() << "]"
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " natural size: [" << natural_size().width()
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "," << natural_size().height() << "]"
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " has extra data? " << (extra_data() ? "true" : "false")
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << " encrypted? " << (is_encrypted() ? "true" : "false");
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return s.str();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoCodec VideoDecoderConfig::codec() const {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return codec_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoCodecProfile VideoDecoderConfig::profile() const {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::Format VideoDecoderConfig::format() const {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return format_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size VideoDecoderConfig::coded_size() const {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return coded_size_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect VideoDecoderConfig::visible_rect() const {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return visible_rect_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size VideoDecoderConfig::natural_size() const {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return natural_size_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const uint8* VideoDecoderConfig::extra_data() const {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extra_data_.empty())
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &extra_data_[0];
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t VideoDecoderConfig::extra_data_size() const {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return extra_data_.size();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VideoDecoderConfig::is_encrypted() const {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_encrypted_;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
171