Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <unordered_map> | |
| 6 | |
| 7 #include "mojo/services/media/common/cpp/video_packet_layout.h" | |
| 8 | |
| 9 namespace mojo { | |
| 10 namespace media { | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 static inline size_t RoundUpToAlign(size_t value, size_t alignment) { | |
| 15 return ((value + (alignment - 1)) & ~(alignment - 1)); | |
| 16 } | |
| 17 | |
| 18 } // namespace | |
| 19 | |
| 20 // static | |
| 21 const VideoPacketLayout::PixelFormatInfo& VideoPacketLayout::InfoForPixelFormat( | |
| 22 PixelFormat pixel_format) { | |
| 23 struct Hash { | |
| 24 std::size_t operator()(PixelFormat const& pixel_format) const { | |
| 25 return static_cast<size_t>(pixel_format); | |
| 26 } | |
| 27 }; | |
| 28 static const std::unordered_map<PixelFormat, PixelFormatInfo, Hash> table = { | |
| 29 {PixelFormat::I420, | |
| 30 {3, {1, 1, 1}, {Extent(1, 1), Extent(2, 2), Extent(2, 2)}}}, | |
| 31 {PixelFormat::YV12, | |
| 32 {3, {1, 1, 1}, {Extent(1, 1), Extent(2, 2), Extent(2, 2)}}}, | |
| 33 {PixelFormat::YV16, | |
| 34 {3, {1, 1, 1}, {Extent(1, 1), Extent(2, 1), Extent(2, 1)}}}, | |
| 35 {PixelFormat::YV12A, | |
| 36 {4, | |
| 37 {1, 1, 1, 1}, | |
| 38 {Extent(1, 1), Extent(2, 2), Extent(2, 2), Extent(1, 1)}}}, | |
| 39 {PixelFormat::YV24, | |
| 40 {3, {1, 1, 1}, {Extent(1, 1), Extent(1, 1), Extent(1, 1)}}}, | |
| 41 {PixelFormat::NV12, {2, {1, 2}, {Extent(1, 1), Extent(2, 2)}}}, | |
| 42 {PixelFormat::NV21, {2, {1, 2}, {Extent(1, 1), Extent(2, 2)}}}, | |
| 43 {PixelFormat::UYVY, {1, {2}, {Extent(1, 1)}}}, | |
| 44 {PixelFormat::YUY2, {1, {2}, {Extent(1, 1)}}}, | |
| 45 {PixelFormat::ARGB, {1, {4}, {Extent(1, 1)}}}, | |
| 46 {PixelFormat::XRGB, {1, {4}, {Extent(1, 1)}}}, | |
| 47 {PixelFormat::RGB24, {1, {3}, {Extent(1, 1)}}}, | |
| 48 {PixelFormat::RGB32, {1, {4}, {Extent(1, 1)}}}, | |
| 49 {PixelFormat::MJPEG, {1, {0}, {Extent(1, 1)}}}, | |
| 50 {PixelFormat::MT21, {2, {1, 2}, {Extent(1, 1), Extent(2, 2)}}}}; | |
| 51 | |
| 52 MOJO_DCHECK(table.find(pixel_format) != table.end()); | |
| 53 return table.find(pixel_format)->second; | |
| 54 } | |
| 55 | |
| 56 size_t VideoPacketLayout::PixelFormatInfo::RowCount(size_t plane, | |
| 57 size_t height) const { | |
| 58 MOJO_DCHECK(plane < plane_count_); | |
| 59 const int sample_height = sample_size_for_plane(plane).height(); | |
| 60 return RoundUpToAlign(height, sample_height) / sample_height; | |
| 61 } | |
| 62 | |
| 63 size_t VideoPacketLayout::PixelFormatInfo::ColumnCount(size_t plane, | |
| 64 size_t width) const { | |
| 65 MOJO_DCHECK(plane < plane_count_); | |
| 66 const size_t sample_width = sample_size_for_plane(plane).width(); | |
| 67 return RoundUpToAlign(width, sample_width) / sample_width; | |
| 68 } | |
| 69 | |
| 70 size_t VideoPacketLayout::PixelFormatInfo::BytesPerRow(size_t plane, | |
| 71 size_t width) const { | |
| 72 MOJO_DCHECK(plane < plane_count_); | |
| 73 return bytes_per_element_for_plane(plane) * ColumnCount(plane, width); | |
| 74 } | |
| 75 | |
| 76 VideoPacketLayout::Extent VideoPacketLayout::PixelFormatInfo::AlignedSize( | |
| 77 const Extent& unaligned_size) const { | |
| 78 const Extent alignment = CommonAlignment(); | |
| 79 const Extent adjusted = | |
| 80 Extent(RoundUpToAlign(unaligned_size.width(), alignment.width()), | |
| 81 RoundUpToAlign(unaligned_size.height(), alignment.height())); | |
| 82 MOJO_DCHECK((adjusted.width() % alignment.width() == 0) && | |
| 83 (adjusted.height() % alignment.height() == 0)); | |
| 84 return adjusted; | |
| 85 } | |
| 86 | |
| 87 VideoPacketLayout::Extent VideoPacketLayout::PixelFormatInfo::CommonAlignment() | |
| 88 const { | |
| 89 size_t max_sample_width = 0; | |
| 90 size_t max_sample_height = 0; | |
| 91 for (size_t plane = 0; plane < plane_count_; ++plane) { | |
| 92 const Extent sample_size = sample_size_for_plane(plane); | |
| 93 max_sample_width = std::max(max_sample_width, sample_size.width()); | |
| 94 max_sample_height = std::max(max_sample_height, sample_size.height()); | |
| 95 } | |
| 96 return Extent(max_sample_width, max_sample_height); | |
| 97 } | |
| 98 | |
| 99 VideoPacketLayout::VideoPacketLayout() {} | |
| 100 | |
| 101 VideoPacketLayout::VideoPacketLayout(PixelFormat pixel_format, | |
| 102 uint32_t width, | |
| 103 uint32_t height, | |
| 104 uint32_t coded_width, | |
| 105 uint32_t coded_height) | |
| 106 : pixel_format_(pixel_format), | |
| 107 width_(width), | |
| 108 height_(height), | |
| 109 coded_width_(coded_width), | |
| 110 coded_height_(coded_height) { | |
| 111 const PixelFormatInfo& info = GetPixelFormatInfo(); | |
| 112 | |
| 113 Extent coded_size(coded_width, coded_height); | |
| 114 plane_count_ = info.plane_count_; | |
| 115 | |
| 116 size_ = 0; | |
| 117 Extent aligned_size = info.AlignedSize(coded_size); | |
| 118 | |
| 119 for (size_t plane = 0; plane < plane_count_; ++plane) { | |
| 120 // The *2 in alignment for height is because some formats (e.g. h264) | |
| 121 // allow interlaced coding, and then the size needs to be a multiple of two | |
| 122 // macroblocks (vertically). See avcodec_align_dimensions2. | |
| 123 const size_t height = RoundUpToAlign( | |
| 124 info.RowCount(plane, aligned_size.height()), kFrameSizeAlignment * 2); | |
| 125 line_stride_[plane] = RoundUpToAlign( | |
| 126 info.BytesPerRow(plane, aligned_size.width()), kFrameSizeAlignment); | |
| 127 plane_offset_[plane] = size_; | |
| 128 size_ += height * line_stride_[plane]; | |
| 129 } | |
| 130 | |
| 131 // The extra line of UV being allocated is because h264 chroma MC overreads | |
|
kulakowski
2016/06/17 21:15:40
Perhaps have a short version of this comment in on
dalesat
2016/06/18 00:07:08
Done.
| |
| 132 // by one line in some cases, see avcodec_align_dimensions2() and | |
| 133 // h264_chromamc.asm:put_h264_chroma_mc4_ssse3(). | |
| 134 MOJO_DCHECK(static_cast<size_t>(kUPlaneIndex) < plane_count_); | |
| 135 size_ += line_stride_[kUPlaneIndex] + kFrameSizePadding; | |
| 136 } | |
| 137 | |
| 138 VideoPacketLayout::~VideoPacketLayout() {} | |
| 139 | |
| 140 } // namespace media | |
| 141 } // namespace mojo | |
| OLD | NEW |