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

Side by Side Diff: media/gpu/video_encode_accelerator_unittest.cc

Issue 2058413003: H264 HW encode using MediaFoundation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: grt@ and sanders@ comments. Created 4 years, 5 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 <inttypes.h> 5 #include <inttypes.h>
6 #include <stddef.h> 6 #include <stddef.h>
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
11 #include <queue> 11 #include <queue>
12 #include <string> 12 #include <string>
13 #include <utility> 13 #include <utility>
14 14
15 #include "base/at_exit.h" 15 #include "base/at_exit.h"
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/bits.h" 17 #include "base/bits.h"
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/files/file_util.h" 19 #include "base/files/file_util.h"
20 #include "base/macros.h" 20 #include "base/macros.h"
21 #include "base/memory/aligned_memory.h" 21 #include "base/memory/aligned_memory.h"
22 #include "base/memory/scoped_vector.h" 22 #include "base/memory/scoped_vector.h"
23 #include "base/message_loop/message_loop.h" 23 #include "base/message_loop/message_loop.h"
24 #include "base/numerics/safe_conversions.h" 24 #include "base/numerics/safe_conversions.h"
25 #include "base/process/process_handle.h" 25 #include "base/process/process_handle.h"
26 #include "base/single_thread_task_runner.h" 26 #include "base/single_thread_task_runner.h"
27 #include "base/strings/string_number_conversions.h" 27 #include "base/strings/string_number_conversions.h"
28 #include "base/strings/string_split.h" 28 #include "base/strings/string_split.h"
29 #include "base/strings/stringprintf.h" 29 #include "base/strings/stringprintf.h"
30 #include "base/strings/utf_string_conversions.h"
30 #include "base/threading/thread.h" 31 #include "base/threading/thread.h"
31 #include "base/threading/thread_checker.h" 32 #include "base/threading/thread_checker.h"
32 #include "base/time/time.h" 33 #include "base/time/time.h"
33 #include "base/timer/timer.h" 34 #include "base/timer/timer.h"
34 #include "build/build_config.h" 35 #include "build/build_config.h"
35 #include "media/base/bind_to_current_loop.h" 36 #include "media/base/bind_to_current_loop.h"
36 #include "media/base/bitstream_buffer.h" 37 #include "media/base/bitstream_buffer.h"
37 #include "media/base/cdm_context.h" 38 #include "media/base/cdm_context.h"
38 #include "media/base/decoder_buffer.h" 39 #include "media/base/decoder_buffer.h"
39 #include "media/base/media_util.h" 40 #include "media/base/media_util.h"
(...skipping 14 matching lines...) Expand all
54 #include "media/gpu/v4l2_video_encode_accelerator.h" 55 #include "media/gpu/v4l2_video_encode_accelerator.h"
55 #endif 56 #endif
56 #if defined(ARCH_CPU_X86_FAMILY) 57 #if defined(ARCH_CPU_X86_FAMILY)
57 #include "media/gpu/vaapi_video_encode_accelerator.h" 58 #include "media/gpu/vaapi_video_encode_accelerator.h"
58 #include "media/gpu/vaapi_wrapper.h" 59 #include "media/gpu/vaapi_wrapper.h"
59 // Status has been defined as int in Xlib.h. 60 // Status has been defined as int in Xlib.h.
60 #undef Status 61 #undef Status
61 #endif // defined(ARCH_CPU_X86_FAMILY) 62 #endif // defined(ARCH_CPU_X86_FAMILY)
62 #elif defined(OS_MACOSX) 63 #elif defined(OS_MACOSX)
63 #include "media/gpu/vt_video_encode_accelerator_mac.h" 64 #include "media/gpu/vt_video_encode_accelerator_mac.h"
65 #elif defined(OS_WIN)
66 #include "media/gpu/media_foundation_video_encode_accelerator_win.h"
64 #else 67 #else
65 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. 68 #error The VideoEncodeAcceleratorUnittest is not supported on this platform.
66 #endif 69 #endif
67 70
68 namespace media { 71 namespace media {
69 namespace { 72 namespace {
70 73
71 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; 74 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420;
72 75
73 // The absolute differences between original frame and decoded frame usually 76 // The absolute differences between original frame and decoded frame usually
(...skipping 26 matching lines...) Expand all
100 // an encoder to be able to converge to the requested bitrate over. 103 // an encoder to be able to converge to the requested bitrate over.
101 // The input stream will be looped as many times as needed in bitrate tests 104 // The input stream will be looped as many times as needed in bitrate tests
102 // to reach at least this number of frames before calculating final bitrate. 105 // to reach at least this number of frames before calculating final bitrate.
103 const unsigned int kMinFramesForBitrateTests = 300; 106 const unsigned int kMinFramesForBitrateTests = 300;
104 // The percentiles to measure for encode latency. 107 // The percentiles to measure for encode latency.
105 const unsigned int kLoggedLatencyPercentiles[] = {50, 75, 95}; 108 const unsigned int kLoggedLatencyPercentiles[] = {50, 75, 95};
106 109
107 // The syntax of multiple test streams is: 110 // The syntax of multiple test streams is:
108 // test-stream1;test-stream2;test-stream3 111 // test-stream1;test-stream2;test-stream3
109 // The syntax of each test stream is: 112 // The syntax of each test stream is:
110 // "in_filename:width:height:profile:out_filename:requested_bitrate 113 // "in_filename&width&height&profile&out_filename&requested_bitrate
111 // :requested_framerate:requested_subsequent_bitrate 114 // &requested_framerate&requested_subsequent_bitrate
112 // :requested_subsequent_framerate" 115 // &requested_subsequent_framerate"
113 // - |in_filename| must be an I420 (YUV planar) raw stream 116 // - |in_filename| must be an I420 (YUV planar) raw stream
114 // (see http://www.fourcc.org/yuv.php#IYUV). 117 // (see http://www.fourcc.org/yuv.php#IYUV).
115 // - |width| and |height| are in pixels. 118 // - |width| and |height| are in pixels.
116 // - |profile| to encode into (values of VideoCodecProfile). 119 // - |profile| to encode into (values of VideoCodecProfile).
117 // - |out_filename| filename to save the encoded stream to (optional). The 120 // - |out_filename| filename to save the encoded stream to (optional). The
118 // format for H264 is Annex-B byte stream. The format for VP8 is IVF. Output 121 // format for H264 is Annex-B byte stream. The format for VP8 is IVF. Output
119 // stream is saved for the simple encode test only. H264 raw stream and IVF 122 // stream is saved for the simple encode test only. H264 raw stream and IVF
120 // can be used as input of VDA unittest. H264 raw stream can be played by 123 // can be used as input of VDA unittest. H264 raw stream can be played by
121 // "mplayer -fps 25 out.h264" and IVF can be played by mplayer directly. 124 // "mplayer -fps 25 out.h264" and IVF can be played by mplayer directly.
122 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF 125 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
123 // Further parameters are optional (need to provide preceding positional 126 // Further parameters are optional (need to provide preceding positional
124 // parameters if a specific subsequent parameter is required): 127 // parameters if a specific subsequent parameter is required):
125 // - |requested_bitrate| requested bitrate in bits per second. 128 // - |requested_bitrate| requested bitrate in bits per second.
126 // - |requested_framerate| requested initial framerate. 129 // - |requested_framerate| requested initial framerate.
127 // - |requested_subsequent_bitrate| bitrate to switch to in the middle of the 130 // - |requested_subsequent_bitrate| bitrate to switch to in the middle of the
128 // stream. 131 // stream.
129 // - |requested_subsequent_framerate| framerate to switch to in the middle 132 // - |requested_subsequent_framerate| framerate to switch to in the middle
130 // of the stream. 133 // of the stream.
131 // Bitrate is only forced for tests that test bitrate. 134 // Bitrate is only forced for tests that test bitrate.
132 const char* g_default_in_filename = "bear_320x192_40frames.yuv"; 135 const char* g_default_in_filename = "bear_320x192_40frames.yuv";
133 #if !defined(OS_MACOSX) 136
134 const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; 137 #if defined(OS_CHROMEOS)
135 #else 138 const char* g_default_in_parameters = "&320&192&1&out.h264&200000";
wuchengli 2016/07/15 13:39:40 Why do we need to change from ":" to "&"? Several
emircan 2016/07/16 06:56:38 In windows file paths contain ":", i.e. C:\Program
wuchengli 2016/07/19 15:50:44 - Uniform parsing code is better. But we need to m
136 const char* g_default_in_parameters = ":320:192:0:out.h264:200000"; 139 #elif defined(OS_MACOSX)
137 #endif 140 const char* g_default_in_parameters = "&320&192&0&out.h264&200000";
wuchengli 2016/07/15 13:39:40 Can we make these all const base::FilePath::CharTy
emircan 2016/07/16 06:56:38 Done.
141 #elif defined(OS_WIN)
142 const base::FilePath::CharType* g_default_in_parameters =
143 FILE_PATH_LITERAL("&320&192&0&out.h264&200000");
144 #endif // defined(OS_CHROMEOS)
138 145
139 // Enabled by including a --fake_encoder flag to the command line invoking the 146 // Enabled by including a --fake_encoder flag to the command line invoking the
140 // test. 147 // test.
141 bool g_fake_encoder = false; 148 bool g_fake_encoder = false;
142 149
143 // Environment to store test stream data for all test cases. 150 // Environment to store test stream data for all test cases.
144 class VideoEncodeAcceleratorTestEnvironment; 151 class VideoEncodeAcceleratorTestEnvironment;
145 VideoEncodeAcceleratorTestEnvironment* g_env; 152 VideoEncodeAcceleratorTestEnvironment* g_env;
146 153
147 // The number of frames to be encoded. This variable is set by the switch 154 // The number of frames to be encoded. This variable is set by the switch
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 visible_bpl[i] = VideoFrame::RowBytes(i, kInputFormat, 290 visible_bpl[i] = VideoFrame::RowBytes(i, kInputFormat,
284 test_stream->visible_size.width()); 291 test_stream->visible_size.width());
285 visible_plane_rows[i] = 292 visible_plane_rows[i] =
286 VideoFrame::Rows(i, kInputFormat, test_stream->visible_size.height()); 293 VideoFrame::Rows(i, kInputFormat, test_stream->visible_size.height());
287 const size_t padding_rows = 294 const size_t padding_rows =
288 VideoFrame::Rows(i, kInputFormat, coded_size.height()) - 295 VideoFrame::Rows(i, kInputFormat, coded_size.height()) -
289 visible_plane_rows[i]; 296 visible_plane_rows[i];
290 padding_sizes[i] = padding_rows * coded_bpl[i] + Align64Bytes(size) - size; 297 padding_sizes[i] = padding_rows * coded_bpl[i] + Align64Bytes(size) - size;
291 } 298 }
292 299
300 #if defined(OS_POSIX)
293 base::FilePath src_file(test_stream->in_filename); 301 base::FilePath src_file(test_stream->in_filename);
302 #elif defined(OS_WIN)
303 base::FilePath src_file(base::UTF8ToWide(test_stream->in_filename));
304 #endif
294 int64_t src_file_size = 0; 305 int64_t src_file_size = 0;
295 LOG_ASSERT(base::GetFileSize(src_file, &src_file_size)); 306 LOG_ASSERT(base::GetFileSize(src_file, &src_file_size));
296 307
297 size_t visible_buffer_size = 308 size_t visible_buffer_size =
298 VideoFrame::AllocationSize(kInputFormat, test_stream->visible_size); 309 VideoFrame::AllocationSize(kInputFormat, test_stream->visible_size);
299 LOG_ASSERT(src_file_size % visible_buffer_size == 0U) 310 LOG_ASSERT(src_file_size % visible_buffer_size == 0U)
300 << "Stream byte size is not a product of calculated frame byte size"; 311 << "Stream byte size is not a product of calculated frame byte size";
301 312
302 test_stream->num_frames = src_file_size / visible_buffer_size; 313 test_stream->num_frames = src_file_size / visible_buffer_size;
303 314
(...skipping 17 matching lines...) Expand all
321 visible_bpl[i]); 332 visible_bpl[i]);
322 src_ptr += visible_bpl[i]; 333 src_ptr += visible_bpl[i];
323 dest_offset += coded_bpl[i]; 334 dest_offset += coded_bpl[i];
324 } 335 }
325 dest_offset += padding_sizes[i]; 336 dest_offset += padding_sizes[i];
326 } 337 }
327 src_offset += visible_buffer_size; 338 src_offset += visible_buffer_size;
328 } 339 }
329 src.Close(); 340 src.Close();
330 341
342 #if defined(OS_POSIX)
331 // Assert that memory mapped of file starts at 64 byte boundary. So each 343 // Assert that memory mapped of file starts at 64 byte boundary. So each
332 // plane of frames also start at 64 byte boundary. 344 // plane of frames also start at 64 byte boundary.
333 ASSERT_EQ(reinterpret_cast<off_t>(&test_stream->aligned_in_file_data[0]) & 63, 345 ASSERT_EQ(reinterpret_cast<off_t>(&test_stream->aligned_in_file_data[0]) & 63,
334 0) 346 0)
335 << "File should be mapped at a 64 byte boundary"; 347 << "File should be mapped at a 64 byte boundary";
348 #endif // defined(OS_POSIX)
336 349
337 LOG_ASSERT(test_stream->num_frames > 0UL); 350 LOG_ASSERT(test_stream->num_frames > 0UL);
338 } 351 }
339 352
340 // Parse |data| into its constituent parts, set the various output fields 353 // Parse |data| into its constituent parts, set the various output fields
341 // accordingly, read in video stream, and store them to |test_streams|. 354 // accordingly, read in video stream, and store them to |test_streams|.
342 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data, 355 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data,
343 ScopedVector<TestStream>* test_streams) { 356 ScopedVector<TestStream>* test_streams) {
344 // Split the string to individual test stream data. 357 // Split the string to individual test stream data.
345 std::vector<base::FilePath::StringType> test_streams_data = 358 std::vector<base::FilePath::StringType> test_streams_data =
346 base::SplitString(data, base::FilePath::StringType(1, ';'), 359 base::SplitString(data, base::FilePath::StringType(1, ';'),
347 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 360 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
348 LOG_ASSERT(test_streams_data.size() >= 1U) << data; 361 LOG_ASSERT(test_streams_data.size() >= 1U) << data;
349 362
350 // Parse each test stream data and read the input file. 363 // Parse each test stream data and read the input file.
351 for (size_t index = 0; index < test_streams_data.size(); ++index) { 364 for (size_t index = 0; index < test_streams_data.size(); ++index) {
352 std::vector<base::FilePath::StringType> fields = base::SplitString( 365 std::vector<base::FilePath::StringType> fields = base::SplitString(
353 test_streams_data[index], base::FilePath::StringType(1, ':'), 366 test_streams_data[index], base::FilePath::StringType(1, '&'),
354 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 367 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
355 LOG_ASSERT(fields.size() >= 4U) << data; 368 LOG_ASSERT(fields.size() >= 4U) << data;
356 LOG_ASSERT(fields.size() <= 9U) << data; 369 LOG_ASSERT(fields.size() <= 9U) << data;
357 TestStream* test_stream = new TestStream(); 370 TestStream* test_stream = new TestStream();
358 371
372 #if defined(OS_POSIX)
359 test_stream->in_filename = fields[0]; 373 test_stream->in_filename = fields[0];
wuchengli 2016/07/15 13:39:40 I don't understand. Why we only set in_filename fo
emircan 2016/07/16 06:56:38 FilePath is defined specifically for POSIX and WIN
374 #elif defined(OS_WIN)
375 test_stream->in_filename = base::WideToUTF8(fields[0]);
wuchengli 2016/07/15 13:39:40 Make string conversion a function. It can be reuse
emircan 2016/07/16 06:56:38 Done.
376 #endif // defined(OS_POSIX)
360 int width, height; 377 int width, height;
361 bool result = base::StringToInt(fields[1], &width); 378 bool result = base::StringToInt(fields[1], &width);
362 LOG_ASSERT(result); 379 LOG_ASSERT(result);
363 result = base::StringToInt(fields[2], &height); 380 result = base::StringToInt(fields[2], &height);
364 LOG_ASSERT(result); 381 LOG_ASSERT(result);
365 test_stream->visible_size = gfx::Size(width, height); 382 test_stream->visible_size = gfx::Size(width, height);
366 LOG_ASSERT(!test_stream->visible_size.IsEmpty()); 383 LOG_ASSERT(!test_stream->visible_size.IsEmpty());
367 int profile; 384 int profile;
368 result = base::StringToInt(fields[3], &profile); 385 result = base::StringToInt(fields[3], &profile);
369 LOG_ASSERT(result); 386 LOG_ASSERT(result);
370 LOG_ASSERT(profile > VIDEO_CODEC_PROFILE_UNKNOWN); 387 LOG_ASSERT(profile > VIDEO_CODEC_PROFILE_UNKNOWN);
371 LOG_ASSERT(profile <= VIDEO_CODEC_PROFILE_MAX); 388 LOG_ASSERT(profile <= VIDEO_CODEC_PROFILE_MAX);
372 test_stream->requested_profile = static_cast<VideoCodecProfile>(profile); 389 test_stream->requested_profile = static_cast<VideoCodecProfile>(profile);
373 390
374 if (fields.size() >= 5 && !fields[4].empty()) 391 if (fields.size() >= 5 && !fields[4].empty()) {
392 #if defined(OS_POSIX)
375 test_stream->out_filename = fields[4]; 393 test_stream->out_filename = fields[4];
394 #elif defined(OS_WIN)
395 test_stream->out_filename = base::WideToUTF8(fields[4]);
396 #endif // defined(OS_POSIX)
397 }
376 398
377 if (fields.size() >= 6 && !fields[5].empty()) 399 if (fields.size() >= 6 && !fields[5].empty())
378 LOG_ASSERT( 400 LOG_ASSERT(
379 base::StringToUint(fields[5], &test_stream->requested_bitrate)); 401 base::StringToUint(fields[5], &test_stream->requested_bitrate));
380 402
381 if (fields.size() >= 7 && !fields[6].empty()) 403 if (fields.size() >= 7 && !fields[6].empty())
382 LOG_ASSERT( 404 LOG_ASSERT(
383 base::StringToUint(fields[6], &test_stream->requested_framerate)); 405 base::StringToUint(fields[6], &test_stream->requested_framerate));
384 406
385 if (fields.size() >= 8 && !fields[7].empty()) { 407 if (fields.size() >= 8 && !fields[7].empty()) {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 // Flush the decoder. 650 // Flush the decoder.
629 void Flush(); 651 void Flush();
630 652
631 private: 653 private:
632 void InitializeCB(bool success); 654 void InitializeCB(bool success);
633 void DecodeDone(DecodeStatus status); 655 void DecodeDone(DecodeStatus status);
634 void FlushDone(DecodeStatus status); 656 void FlushDone(DecodeStatus status);
635 void VerifyOutputFrame(const scoped_refptr<VideoFrame>& output_frame); 657 void VerifyOutputFrame(const scoped_refptr<VideoFrame>& output_frame);
636 void Decode(); 658 void Decode();
637 659
638 enum State { UNINITIALIZED, INITIALIZED, DECODING, ERROR }; 660 enum State { UNINITIALIZED, INITIALIZED, DECODING, DECODER_ERROR };
639 661
640 const VideoCodecProfile profile_; 662 const VideoCodecProfile profile_;
641 std::unique_ptr<FFmpegVideoDecoder> decoder_; 663 std::unique_ptr<FFmpegVideoDecoder> decoder_;
642 VideoDecoder::DecodeCB decode_cb_; 664 VideoDecoder::DecodeCB decode_cb_;
643 // Decode callback of an EOS buffer. 665 // Decode callback of an EOS buffer.
644 VideoDecoder::DecodeCB eos_decode_cb_; 666 VideoDecoder::DecodeCB eos_decode_cb_;
645 // Callback of Flush(). Called after all frames are decoded. 667 // Callback of Flush(). Called after all frames are decoded.
646 const base::Closure flush_complete_cb_; 668 const base::Closure flush_complete_cb_;
647 const base::Closure decode_error_cb_; 669 const base::Closure decode_error_cb_;
648 State decoder_state_; 670 State decoder_state_;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 base::Unretained(this)), 713 base::Unretained(this)),
692 base::Bind(&VideoFrameQualityValidator::VerifyOutputFrame, 714 base::Bind(&VideoFrameQualityValidator::VerifyOutputFrame,
693 base::Unretained(this))); 715 base::Unretained(this)));
694 } 716 }
695 717
696 void VideoFrameQualityValidator::InitializeCB(bool success) { 718 void VideoFrameQualityValidator::InitializeCB(bool success) {
697 if (success) { 719 if (success) {
698 decoder_state_ = INITIALIZED; 720 decoder_state_ = INITIALIZED;
699 Decode(); 721 Decode();
700 } else { 722 } else {
701 decoder_state_ = ERROR; 723 decoder_state_ = DECODER_ERROR;
702 if (IsH264(profile_)) 724 if (IsH264(profile_))
703 LOG(ERROR) << "Chromium does not support H264 decode. Try Chrome."; 725 LOG(ERROR) << "Chromium does not support H264 decode. Try Chrome.";
704 FAIL() << "Decoder initialization error"; 726 FAIL() << "Decoder initialization error";
705 decode_error_cb_.Run(); 727 decode_error_cb_.Run();
706 } 728 }
707 } 729 }
708 730
709 void VideoFrameQualityValidator::AddOriginalFrame( 731 void VideoFrameQualityValidator::AddOriginalFrame(
710 scoped_refptr<VideoFrame> frame) { 732 scoped_refptr<VideoFrame> frame) {
711 original_frames_.push(frame); 733 original_frames_.push(frame);
712 } 734 }
713 735
714 void VideoFrameQualityValidator::DecodeDone(DecodeStatus status) { 736 void VideoFrameQualityValidator::DecodeDone(DecodeStatus status) {
715 if (status == DecodeStatus::OK) { 737 if (status == DecodeStatus::OK) {
716 decoder_state_ = INITIALIZED; 738 decoder_state_ = INITIALIZED;
717 Decode(); 739 Decode();
718 } else { 740 } else {
719 decoder_state_ = ERROR; 741 decoder_state_ = DECODER_ERROR;
720 FAIL() << "Unexpected decode status = " << status << ". Stop decoding."; 742 FAIL() << "Unexpected decode status = " << status << ". Stop decoding.";
721 decode_error_cb_.Run(); 743 decode_error_cb_.Run();
722 } 744 }
723 } 745 }
724 746
725 void VideoFrameQualityValidator::FlushDone(DecodeStatus status) { 747 void VideoFrameQualityValidator::FlushDone(DecodeStatus status) {
726 flush_complete_cb_.Run(); 748 flush_complete_cb_.Run();
727 } 749 }
728 750
729 void VideoFrameQualityValidator::Flush() { 751 void VideoFrameQualityValidator::Flush() {
730 if (decoder_state_ != ERROR) { 752 if (decoder_state_ != DECODER_ERROR) {
731 decode_buffers_.push(DecoderBuffer::CreateEOSBuffer()); 753 decode_buffers_.push(DecoderBuffer::CreateEOSBuffer());
732 Decode(); 754 Decode();
733 } 755 }
734 } 756 }
735 757
736 void VideoFrameQualityValidator::AddDecodeBuffer( 758 void VideoFrameQualityValidator::AddDecodeBuffer(
737 const scoped_refptr<DecoderBuffer>& buffer) { 759 const scoped_refptr<DecoderBuffer>& buffer) {
738 if (decoder_state_ != ERROR) { 760 if (decoder_state_ != DECODER_ERROR) {
739 decode_buffers_.push(buffer); 761 decode_buffers_.push(buffer);
740 Decode(); 762 Decode();
741 } 763 }
742 } 764 }
743 765
744 void VideoFrameQualityValidator::Decode() { 766 void VideoFrameQualityValidator::Decode() {
745 if (decoder_state_ == INITIALIZED && !decode_buffers_.empty()) { 767 if (decoder_state_ == INITIALIZED && !decode_buffers_.empty()) {
746 scoped_refptr<DecoderBuffer> next_buffer = decode_buffers_.front(); 768 scoped_refptr<DecoderBuffer> next_buffer = decode_buffers_.front();
747 decode_buffers_.pop(); 769 decode_buffers_.pop();
748 decoder_state_ = DECODING; 770 decoder_state_ = DECODING;
(...skipping 15 matching lines...) Expand all
764 double difference = 0; 786 double difference = 0;
765 for (int plane : planes) { 787 for (int plane : planes) {
766 uint8_t* original_plane = original_frame->data(plane); 788 uint8_t* original_plane = original_frame->data(plane);
767 uint8_t* output_plane = output_frame->data(plane); 789 uint8_t* output_plane = output_frame->data(plane);
768 790
769 size_t rows = VideoFrame::Rows(plane, kInputFormat, visible_size.height()); 791 size_t rows = VideoFrame::Rows(plane, kInputFormat, visible_size.height());
770 size_t columns = 792 size_t columns =
771 VideoFrame::Columns(plane, kInputFormat, visible_size.width()); 793 VideoFrame::Columns(plane, kInputFormat, visible_size.width());
772 size_t stride = original_frame->stride(plane); 794 size_t stride = original_frame->stride(plane);
773 795
774 for (size_t i = 0; i < rows; i++) 796 for (size_t i = 0; i < rows; i++) {
775 for (size_t j = 0; j < columns; j++) 797 for (size_t j = 0; j < columns; j++) {
776 difference += std::abs(original_plane[stride * i + j] - 798 difference += std::abs(original_plane[stride * i + j] -
777 output_plane[stride * i + j]); 799 output_plane[stride * i + j]);
800 }
801 }
778 } 802 }
803
779 // Divide the difference by the size of frame. 804 // Divide the difference by the size of frame.
780 difference /= VideoFrame::AllocationSize(kInputFormat, visible_size); 805 difference /= VideoFrame::AllocationSize(kInputFormat, visible_size);
781 EXPECT_TRUE(difference <= kDecodeSimilarityThreshold) 806 EXPECT_TRUE(difference <= kDecodeSimilarityThreshold)
782 << "differrence = " << difference << " > decode similarity threshold"; 807 << "difference = " << difference << " > decode similarity threshold";
783 } 808 }
784 809
785 class VEAClient : public VideoEncodeAccelerator::Client { 810 class VEAClient : public VideoEncodeAccelerator::Client {
786 public: 811 public:
787 VEAClient(TestStream* test_stream, 812 VEAClient(TestStream* test_stream,
788 ClientStateNotification<ClientState>* note, 813 ClientStateNotification<ClientState>* note,
789 bool save_to_file, 814 bool save_to_file,
790 unsigned int keyframe_period, 815 unsigned int keyframe_period,
791 bool force_bitrate, 816 bool force_bitrate,
792 bool test_perf, 817 bool test_perf,
(...skipping 18 matching lines...) Expand all
811 private: 836 private:
812 bool has_encoder() { return encoder_.get(); } 837 bool has_encoder() { return encoder_.get(); }
813 838
814 // Return the number of encoded frames per second. 839 // Return the number of encoded frames per second.
815 double frames_per_second(); 840 double frames_per_second();
816 841
817 std::unique_ptr<VideoEncodeAccelerator> CreateFakeVEA(); 842 std::unique_ptr<VideoEncodeAccelerator> CreateFakeVEA();
818 std::unique_ptr<VideoEncodeAccelerator> CreateV4L2VEA(); 843 std::unique_ptr<VideoEncodeAccelerator> CreateV4L2VEA();
819 std::unique_ptr<VideoEncodeAccelerator> CreateVaapiVEA(); 844 std::unique_ptr<VideoEncodeAccelerator> CreateVaapiVEA();
820 std::unique_ptr<VideoEncodeAccelerator> CreateVTVEA(); 845 std::unique_ptr<VideoEncodeAccelerator> CreateVTVEA();
846 std::unique_ptr<VideoEncodeAccelerator> CreateMFVEA();
821 847
822 void SetState(ClientState new_state); 848 void SetState(ClientState new_state);
823 849
824 // Set current stream parameters to given |bitrate| at |framerate|. 850 // Set current stream parameters to given |bitrate| at |framerate|.
825 void SetStreamParameters(unsigned int bitrate, unsigned int framerate); 851 void SetStreamParameters(unsigned int bitrate, unsigned int framerate);
826 852
827 // Called when encoder is done with a VideoFrame. 853 // Called when encoder is done with a VideoFrame.
828 void InputNoLongerNeededCallback(int32_t input_id); 854 void InputNoLongerNeededCallback(int32_t input_id);
829 855
830 // Feed the encoder with one input frame. 856 // Feed the encoder with one input frame.
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 // Fake encoder produces an invalid stream, so skip validating it. 1069 // Fake encoder produces an invalid stream, so skip validating it.
1044 if (!g_fake_encoder) { 1070 if (!g_fake_encoder) {
1045 stream_validator_ = StreamValidator::Create( 1071 stream_validator_ = StreamValidator::Create(
1046 test_stream_->requested_profile, 1072 test_stream_->requested_profile,
1047 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); 1073 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this)));
1048 CHECK(stream_validator_); 1074 CHECK(stream_validator_);
1049 } 1075 }
1050 1076
1051 if (save_to_file_) { 1077 if (save_to_file_) {
1052 LOG_ASSERT(!test_stream_->out_filename.empty()); 1078 LOG_ASSERT(!test_stream_->out_filename.empty());
1079 #if defined(OS_POSIX)
1053 base::FilePath out_filename(test_stream_->out_filename); 1080 base::FilePath out_filename(test_stream_->out_filename);
1081 #elif defined(OS_WIN)
1082 base::FilePath out_filename(base::UTF8ToWide(test_stream_->out_filename));
1083 #endif
1054 // This creates or truncates out_filename. 1084 // This creates or truncates out_filename.
1055 // Without it, AppendToFile() will not work. 1085 // Without it, AppendToFile() will not work.
1056 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); 1086 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0));
1057 } 1087 }
1058 1088
1059 // Initialize the parameters of the test streams. 1089 // Initialize the parameters of the test streams.
1060 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); 1090 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch);
1061 1091
1062 thread_checker_.DetachFromThread(); 1092 thread_checker_.DetachFromThread();
1063 } 1093 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 } 1126 }
1097 1127
1098 std::unique_ptr<VideoEncodeAccelerator> VEAClient::CreateVTVEA() { 1128 std::unique_ptr<VideoEncodeAccelerator> VEAClient::CreateVTVEA() {
1099 std::unique_ptr<VideoEncodeAccelerator> encoder; 1129 std::unique_ptr<VideoEncodeAccelerator> encoder;
1100 #if defined(OS_MACOSX) 1130 #if defined(OS_MACOSX)
1101 encoder.reset(new VTVideoEncodeAccelerator()); 1131 encoder.reset(new VTVideoEncodeAccelerator());
1102 #endif 1132 #endif
1103 return encoder; 1133 return encoder;
1104 } 1134 }
1105 1135
1136 std::unique_ptr<VideoEncodeAccelerator> VEAClient::CreateMFVEA() {
1137 std::unique_ptr<VideoEncodeAccelerator> encoder;
1138 #if defined(OS_WIN)
1139 MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
1140 encoder.reset(new MediaFoundationVideoEncodeAccelerator());
1141 #endif
1142 return encoder;
1143 }
1144
1106 void VEAClient::CreateEncoder() { 1145 void VEAClient::CreateEncoder() {
1107 DCHECK(thread_checker_.CalledOnValidThread()); 1146 DCHECK(thread_checker_.CalledOnValidThread());
1108 LOG_ASSERT(!has_encoder()); 1147 LOG_ASSERT(!has_encoder());
1109 1148
1110 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { 1149 std::unique_ptr<VideoEncodeAccelerator> encoders[] = {
1111 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA()}; 1150 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(),
1151 CreateMFVEA()};
1112 1152
1113 DVLOG(1) << "Profile: " << test_stream_->requested_profile 1153 DVLOG(1) << "Profile: " << test_stream_->requested_profile
1114 << ", initial bitrate: " << requested_bitrate_; 1154 << ", initial bitrate: " << requested_bitrate_;
1115 1155
1116 for (size_t i = 0; i < arraysize(encoders); ++i) { 1156 for (size_t i = 0; i < arraysize(encoders); ++i) {
1117 if (!encoders[i]) 1157 if (!encoders[i])
1118 continue; 1158 continue;
1119 encoder_ = std::move(encoders[i]); 1159 encoder_ = std::move(encoders[i]);
1120 SetState(CS_ENCODER_SET); 1160 SetState(CS_ENCODER_SET);
1121 if (encoder_->Initialize(kInputFormat, test_stream_->visible_size, 1161 if (encoder_->Initialize(kInputFormat, test_stream_->visible_size,
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 for (size_t i = 0; i < num_concurrent_encoders; ++i) { 1731 for (size_t i = 0; i < num_concurrent_encoders; ++i) {
1692 encoder_thread.task_runner()->PostTask( 1732 encoder_thread.task_runner()->PostTask(
1693 FROM_HERE, 1733 FROM_HERE,
1694 base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i]))); 1734 base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i])));
1695 } 1735 }
1696 1736
1697 // This ensures all tasks have finished. 1737 // This ensures all tasks have finished.
1698 encoder_thread.Stop(); 1738 encoder_thread.Stop();
1699 } 1739 }
1700 1740
1701 #if !defined(OS_MACOSX) 1741 #if defined(OS_CHROMEOS)
1702 INSTANTIATE_TEST_CASE_P( 1742 INSTANTIATE_TEST_CASE_P(
1703 SimpleEncode, 1743 SimpleEncode,
1704 VideoEncodeAcceleratorTest, 1744 VideoEncodeAcceleratorTest,
1705 ::testing::Values( 1745 ::testing::Values(
1706 std::make_tuple(1, true, 0, false, false, false, false, false, false), 1746 std::make_tuple(1, true, 0, false, false, false, false, false, false),
1707 std::make_tuple(1, true, 0, false, false, false, false, true, false))); 1747 std::make_tuple(1, true, 0, false, false, false, false, true, false)));
1708 1748
1709 INSTANTIATE_TEST_CASE_P( 1749 INSTANTIATE_TEST_CASE_P(
1710 EncoderPerf, 1750 EncoderPerf,
1711 VideoEncodeAcceleratorTest, 1751 VideoEncodeAcceleratorTest,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1749 std::make_tuple(3, false, 0, false, false, false, false, false, false), 1789 std::make_tuple(3, false, 0, false, false, false, false, false, false),
1750 std::make_tuple(3, false, 0, true, false, false, true, false, false), 1790 std::make_tuple(3, false, 0, true, false, false, true, false, false),
1751 std::make_tuple(3, false, 0, true, false, true, false, false, false))); 1791 std::make_tuple(3, false, 0, true, false, true, false, false, false)));
1752 1792
1753 INSTANTIATE_TEST_CASE_P( 1793 INSTANTIATE_TEST_CASE_P(
1754 VerifyTimestamp, 1794 VerifyTimestamp,
1755 VideoEncodeAcceleratorTest, 1795 VideoEncodeAcceleratorTest,
1756 ::testing::Values( 1796 ::testing::Values(
1757 std::make_tuple(1, false, 0, false, false, false, false, false, true))); 1797 std::make_tuple(1, false, 0, false, false, false, false, false, true)));
1758 1798
1759 #else 1799 #elif defined(OS_MACOSX) || defined(OS_WIN)
1760 INSTANTIATE_TEST_CASE_P( 1800 INSTANTIATE_TEST_CASE_P(
1761 SimpleEncode, 1801 SimpleEncode,
1762 VideoEncodeAcceleratorTest, 1802 VideoEncodeAcceleratorTest,
1763 ::testing::Values( 1803 ::testing::Values(
1764 std::make_tuple(1, true, 0, false, false, false, false, false, false), 1804 std::make_tuple(1, true, 0, false, false, false, false, false, false),
1765 std::make_tuple(1, true, 0, false, false, false, false, true, false))); 1805 std::make_tuple(1, true, 0, false, false, false, false, true, false)));
1766 1806
1767 INSTANTIATE_TEST_CASE_P( 1807 INSTANTIATE_TEST_CASE_P(
1768 EncoderPerf, 1808 EncoderPerf,
1769 VideoEncodeAcceleratorTest, 1809 VideoEncodeAcceleratorTest,
1770 ::testing::Values( 1810 ::testing::Values(
1771 std::make_tuple(1, false, 0, false, true, false, false, false, false))); 1811 std::make_tuple(1, false, 0, false, true, false, false, false, false)));
1772 1812
1773 INSTANTIATE_TEST_CASE_P(MultipleEncoders, 1813 INSTANTIATE_TEST_CASE_P(MultipleEncoders,
1774 VideoEncodeAcceleratorTest, 1814 VideoEncodeAcceleratorTest,
1775 ::testing::Values(std::make_tuple(3, 1815 ::testing::Values(std::make_tuple(3,
1776 false, 1816 false,
1777 0, 1817 0,
1778 false, 1818 false,
1779 false, 1819 false,
1780 false, 1820 false,
1781 false, 1821 false,
1782 false, 1822 false,
1783 false))); 1823 false)));
1784 #endif 1824 #if defined(OS_WIN)
1825 INSTANTIATE_TEST_CASE_P(
1826 ForceBitrate,
1827 VideoEncodeAcceleratorTest,
1828 ::testing::Values(
1829 std::make_tuple(1, false, 0, true, false, false, false, false, false)));
1830 #endif // defined(OS_WIN)
1831
1832 #endif // defined(OS_CHROMEOS)
1785 1833
1786 // TODO(posciak): more tests: 1834 // TODO(posciak): more tests:
1787 // - async FeedEncoderWithOutput 1835 // - async FeedEncoderWithOutput
1788 // - out-of-order return of outputs to encoder 1836 // - out-of-order return of outputs to encoder
1789 // - multiple encoders + decoders 1837 // - multiple encoders + decoders
1790 // - mid-stream encoder_->Destroy() 1838 // - mid-stream encoder_->Destroy()
1791 1839
1792 } // namespace 1840 } // namespace
1793 } // namespace media 1841 } // namespace media
1794 1842
1795 int main(int argc, char** argv) { 1843 int main(int argc, char** argv) {
1796 testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. 1844 testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args.
1797 base::CommandLine::Init(argc, argv); 1845 base::CommandLine::Init(argc, argv);
1798 1846
1799 base::ShadowingAtExitManager at_exit_manager; 1847 base::ShadowingAtExitManager at_exit_manager;
1800 base::MessageLoop main_loop; 1848 base::MessageLoop main_loop;
1801 1849
1802 std::unique_ptr<base::FilePath::StringType> test_stream_data( 1850 std::unique_ptr<base::FilePath::StringType> test_stream_data(
1803 new base::FilePath::StringType( 1851 new base::FilePath::StringType(
1804 media::GetTestDataFilePath(media::g_default_in_filename).value() + 1852 media::GetTestDataFilePath(media::g_default_in_filename).value()));
1805 media::g_default_in_parameters)); 1853 test_stream_data->append(media::g_default_in_parameters);
1806 1854
1807 // Needed to enable DVLOG through --vmodule. 1855 // Needed to enable DVLOG through --vmodule.
1808 logging::LoggingSettings settings; 1856 logging::LoggingSettings settings;
1809 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 1857 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
1810 LOG_ASSERT(logging::InitLogging(settings)); 1858 LOG_ASSERT(logging::InitLogging(settings));
1811 1859
1812 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 1860 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
1813 DCHECK(cmd_line); 1861 DCHECK(cmd_line);
1814 1862
1815 bool run_at_fps = false; 1863 bool run_at_fps = false;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 1919
1872 media::g_env = 1920 media::g_env =
1873 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( 1921 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>(
1874 testing::AddGlobalTestEnvironment( 1922 testing::AddGlobalTestEnvironment(
1875 new media::VideoEncodeAcceleratorTestEnvironment( 1923 new media::VideoEncodeAcceleratorTestEnvironment(
1876 std::move(test_stream_data), log_path, run_at_fps, 1924 std::move(test_stream_data), log_path, run_at_fps,
1877 needs_encode_latency, verify_all_output))); 1925 needs_encode_latency, verify_all_output)));
1878 1926
1879 return RUN_ALL_TESTS(); 1927 return RUN_ALL_TESTS();
1880 } 1928 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698