Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Side by Side Diff: remoting/codec/video_decoder_vpx.cc

Issue 2088953004: Fix VideoDecoderVpx to use pixel format the consumer wants. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/codec/video_decoder_vpx.h" 5 #include "remoting/codec/video_decoder_vpx.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 10 matching lines...) Expand all
21 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" 21 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
22 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h" 22 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h"
23 } 23 }
24 24
25 namespace remoting { 25 namespace remoting {
26 26
27 namespace { 27 namespace {
28 28
29 void RenderRect(vpx_image_t* image, 29 void RenderRect(vpx_image_t* image,
30 webrtc::DesktopRect rect, 30 webrtc::DesktopRect rect,
31 VideoDecoder::PixelFormat pixel_format,
31 webrtc::DesktopFrame* frame) { 32 webrtc::DesktopFrame* frame) {
33 auto yuv_to_rgb_function = libyuv::I420ToARGB;
34 int u_offset;
35 int v_offset;
36
32 switch (image->fmt) { 37 switch (image->fmt) {
33 case VPX_IMG_FMT_I420: { 38 case VPX_IMG_FMT_I420: {
34 // Align position of the top left corner so that its coordinates are 39 // Align position of the top left corner so that its coordinates are
35 // always even. 40 // always even.
36 rect = webrtc::DesktopRect::MakeLTRB(rect.left() & ~1, rect.top() & ~1, 41 rect = webrtc::DesktopRect::MakeLTRB(rect.left() & ~1, rect.top() & ~1,
37 rect.right(), rect.bottom()); 42 rect.right(), rect.bottom());
38 uint8_t* image_data_ptr = frame->GetFrameDataAtPos(rect.top_left()); 43 u_offset = rect.top() / 2 * image->stride[1] + rect.left() / 2;
39 int y_offset = rect.top() * image->stride[0] + rect.left(); 44 v_offset = rect.top() / 2 * image->stride[2] + rect.left() / 2;
40 int u_offset = rect.top() / 2 * image->stride[1] + rect.left() / 2; 45 yuv_to_rgb_function = (pixel_format == VideoDecoder::PixelFormat::BGRA)
41 int v_offset = rect.top() / 2 * image->stride[2] + rect.left() / 2; 46 ? libyuv::I420ToARGB
42 libyuv::I420ToARGB(image->planes[0] + y_offset, image->stride[0], 47 : libyuv::I420ToABGR;
43 image->planes[1] + u_offset, image->stride[1],
44 image->planes[2] + v_offset, image->stride[2],
45 image_data_ptr, frame->stride(),
46 rect.width(), rect.height());
47 break; 48 break;
48 } 49 }
49 // VP8 only outputs I420 frames, but VP9 can also produce I444. 50 // VP8 only outputs I420 frames, but VP9 can also produce I444.
50 case VPX_IMG_FMT_I444: { 51 case VPX_IMG_FMT_I444: {
51 uint8_t* image_data_ptr = frame->GetFrameDataAtPos(rect.top_left()); 52 u_offset = rect.top() * image->stride[1] + rect.left();
52 int y_offset = rect.top() * image->stride[0] + rect.left(); 53 v_offset = rect.top() * image->stride[2] + rect.left();
53 int u_offset = rect.top() * image->stride[1] + rect.left(); 54 yuv_to_rgb_function = (pixel_format == VideoDecoder::PixelFormat::BGRA)
54 int v_offset = rect.top() * image->stride[2] + rect.left(); 55 ? libyuv::I444ToARGB
55 libyuv::I444ToARGB(image->planes[0] + y_offset, image->stride[0], 56 : libyuv::I444ToABGR;
56 image->planes[1] + u_offset, image->stride[1],
57 image->planes[2] + v_offset, image->stride[2],
58 image_data_ptr, frame->stride(),
59 rect.width(), rect.height());
60 break; 57 break;
61 } 58 }
62 default: { 59 default: {
63 LOG(ERROR) << "Unsupported image format:" << image->fmt; 60 LOG(ERROR) << "Unsupported image format:" << image->fmt;
64 return; 61 return;
65 } 62 }
66 } 63 }
64
65 int y_offset = rect.top() * image->stride[0] + rect.left();
66 uint8_t* image_data_ptr = frame->GetFrameDataAtPos(rect.top_left());
67 yuv_to_rgb_function(image->planes[0] + y_offset, image->stride[0],
68 image->planes[1] + u_offset, image->stride[1],
69 image->planes[2] + v_offset, image->stride[2],
70 image_data_ptr, frame->stride(), rect.width(),
71 rect.height());
67 } 72 }
68 73
69 } // namespace 74 } // namespace
70 75
71 // static 76 // static
72 std::unique_ptr<VideoDecoderVpx> VideoDecoderVpx::CreateForVP8() { 77 std::unique_ptr<VideoDecoderVpx> VideoDecoderVpx::CreateForVP8() {
73 return base::WrapUnique(new VideoDecoderVpx(vpx_codec_vp8_dx())); 78 return base::WrapUnique(new VideoDecoderVpx(vpx_codec_vp8_dx()));
74 } 79 }
75 80
76 // static 81 // static
77 std::unique_ptr<VideoDecoderVpx> VideoDecoderVpx::CreateForVP9() { 82 std::unique_ptr<VideoDecoderVpx> VideoDecoderVpx::CreateForVP9() {
78 return base::WrapUnique(new VideoDecoderVpx(vpx_codec_vp9_dx())); 83 return base::WrapUnique(new VideoDecoderVpx(vpx_codec_vp9_dx()));
79 } 84 }
80 85
81 VideoDecoderVpx::~VideoDecoderVpx() {} 86 VideoDecoderVpx::~VideoDecoderVpx() {}
82 87
88 void VideoDecoderVpx::SetPixelFormat(PixelFormat pixel_format) {
89 pixel_format_ = pixel_format;
90 }
91
83 bool VideoDecoderVpx::DecodePacket(const VideoPacket& packet, 92 bool VideoDecoderVpx::DecodePacket(const VideoPacket& packet,
84 webrtc::DesktopFrame* frame) { 93 webrtc::DesktopFrame* frame) {
85 // Pass the packet to the codec to process. 94 // Pass the packet to the codec to process.
86 vpx_codec_err_t ret = vpx_codec_decode( 95 vpx_codec_err_t ret = vpx_codec_decode(
87 codec_.get(), reinterpret_cast<const uint8_t*>(packet.data().data()), 96 codec_.get(), reinterpret_cast<const uint8_t*>(packet.data().data()),
88 packet.data().size(), nullptr, 0); 97 packet.data().size(), nullptr, 0);
89 if (ret != VPX_CODEC_OK) { 98 if (ret != VPX_CODEC_OK) {
90 const char* error = vpx_codec_error(codec_.get()); 99 const char* error = vpx_codec_error(codec_.get());
91 const char* error_detail = vpx_codec_error_detail(codec_.get()); 100 const char* error_detail = vpx_codec_error_detail(codec_.get());
92 LOG(ERROR) << "Decoding failed:" << (error ? error : "(NULL)") << "\n" 101 LOG(ERROR) << "Decoding failed:" << (error ? error : "(NULL)") << "\n"
(...skipping 15 matching lines...) Expand all
108 117
109 // Determine which areas have been updated. 118 // Determine which areas have been updated.
110 webrtc::DesktopRegion* region = frame->mutable_updated_region(); 119 webrtc::DesktopRegion* region = frame->mutable_updated_region();
111 region->Clear(); 120 region->Clear();
112 for (int i = 0; i < packet.dirty_rects_size(); ++i) { 121 for (int i = 0; i < packet.dirty_rects_size(); ++i) {
113 Rect proto_rect = packet.dirty_rects(i); 122 Rect proto_rect = packet.dirty_rects(i);
114 webrtc::DesktopRect rect = 123 webrtc::DesktopRect rect =
115 webrtc::DesktopRect::MakeXYWH(proto_rect.x(), proto_rect.y(), 124 webrtc::DesktopRect::MakeXYWH(proto_rect.x(), proto_rect.y(),
116 proto_rect.width(), proto_rect.height()); 125 proto_rect.width(), proto_rect.height());
117 region->AddRect(rect); 126 region->AddRect(rect);
118 RenderRect(image, rect, frame); 127 RenderRect(image, rect, pixel_format_, frame);
119 } 128 }
120 129
121 return true; 130 return true;
122 } 131 }
123 132
124 VideoDecoderVpx::VideoDecoderVpx(vpx_codec_iface_t* codec) { 133 VideoDecoderVpx::VideoDecoderVpx(vpx_codec_iface_t* codec) {
125 codec_.reset(new vpx_codec_ctx_t); 134 codec_.reset(new vpx_codec_ctx_t);
126 135
127 vpx_codec_dec_cfg config; 136 vpx_codec_dec_cfg config;
128 config.w = 0; 137 config.w = 0;
129 config.h = 0; 138 config.h = 0;
130 config.threads = 2; 139 config.threads = 2;
131 vpx_codec_err_t ret = vpx_codec_dec_init(codec_.get(), codec, &config, 0); 140 vpx_codec_err_t ret = vpx_codec_dec_init(codec_.get(), codec, &config, 0);
132 CHECK_EQ(VPX_CODEC_OK, ret); 141 CHECK_EQ(VPX_CODEC_OK, ret);
133 } 142 }
134 143
135 } // namespace remoting 144 } // namespace remoting
OLDNEW
« remoting/codec/video_decoder.h ('K') | « remoting/codec/video_decoder_vpx.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698