video_decode_accelerator_unittest.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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)// The bulk of this file is support code; sorry about that. Here's an overview 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to hopefully help readers of this code: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Win/EGL. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - ClientState is an enum for the state of the decode client used by the test. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - ClientStateNotification is a barrier abstraction that allows the test code 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to be written sequentially and wait for the decode client to see certain 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// state transitions. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - GLRenderingVDAClient is a VideoDecodeAccelerator::Client implementation 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Finally actual TEST cases are at the bottom of this file, using the above 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// infrastructure. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include gtest.h out of order because <X11/X.h> #define's Bool & None, which 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gtest uses as struct names (inside a namespace). This means that 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #include'ing gtest after anything that pulls in X.h fails to compile. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is http://code.google.com/p/googletest/issues/detail?id=371 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/process_util.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_number_conversions.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/stringize_macros.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/rendering_helper.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/dxva_video_decode_accelerator.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_CHROMEOS) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ARCH_CPU_ARMEL) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/media/exynos_video_decode_accelerator.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(ARCH_CPU_X86_FAMILY) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/vaapi_video_decode_accelerator.h" 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // ARCH_CPU_ARMEL 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error The VideoAccelerator tests are not supported on this platform. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // OS_WIN 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using media::VideoDecodeAccelerator; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Values optionally filled in from flags; see main() below. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The syntax of multiple test videos is: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// test-video1;test-video2;test-video3 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// where only the first video is required and other optional videos would be 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// decoded by concurrent decoders. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The syntax of each test-video is: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// filename:width:height:numframes:numfragments:minFPSwithRender:minFPSnoRender 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where only the first field is required. Value details: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |filename| must be an h264 Annex B (NAL) stream or an IVF VP8 stream. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |width| and |height| are in pixels. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |numframes| is the number of picture frames in the file. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |numfragments| NALU (h264) or frame (VP8) count in the stream. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expected to be achieved with and without rendering to the screen, resp. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (the latter tests just decode speed). 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |profile| is the media::VideoCodecProfile set during Initialization. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An empty value for a numeric field means "ignore". 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType* test_video_data = 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Magic constants for differentiating the reasons for NotifyResetDone being 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// called. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum ResetPoint { 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MID_STREAM_RESET = -2, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) END_OF_STREAM_RESET = -1 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxResetAfterFrameNum = 100; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TestVideoFile { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit TestVideoFile(base::FilePath::StringType file_name) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : file_name(file_name), 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width(-1), 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) height(-1), 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_frames(-1), 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_fragments(-1), 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) min_fps_render(-1), 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) min_fps_no_render(-1), 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile(-1), 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reset_after_frame_num(END_OF_STREAM_RESET) { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType file_name; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int height; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_frames; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_fragments; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int min_fps_render; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int min_fps_no_render; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int profile; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int reset_after_frame_num; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string data_str; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parse |data| into its constituent parts, set the various output fields 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// accordingly, and read in video stream. CHECK-fails on unexpected or 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// missing required data. Unspecified optional fields are set to -1. 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseAndReadTestVideoData(base::FilePath::StringType data, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t num_concurrent_decoders, 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int reset_point, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<TestVideoFile*>* test_video_files) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath::StringType> entries; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SplitString(data, ';', &entries); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GE(entries.size(), 1U) << data; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t index = 0; index < entries.size(); ++index) { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath::StringType> fields; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SplitString(entries[index], ':', &fields); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GE(fields.size(), 1U) << entries[index]; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_LE(fields.size(), 8U) << entries[index]; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestVideoFile* video_file = new TestVideoFile(fields[0]); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[1].empty()) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[1], &video_file->width)); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[2].empty()) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[2], &video_file->height)); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[3].empty()) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[3], &video_file->num_frames)); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we reset mid-stream and start playback over, account for frames 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that are decoded twice in our expectations. 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (video_file->num_frames > 0 && reset_point == MID_STREAM_RESET) { 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reset should not go beyond the last frame; reset after the first 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // frame for short videos. 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) video_file->reset_after_frame_num = kMaxResetAfterFrameNum; 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (video_file->num_frames <= kMaxResetAfterFrameNum) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) video_file->reset_after_frame_num = 1; 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) video_file->num_frames += video_file->reset_after_frame_num; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[4].empty()) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[4], &video_file->num_fragments)); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[5].empty()) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[5], &video_file->min_fps_render)); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_file->min_fps_render /= num_concurrent_decoders; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[6].empty()) { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[6], &video_file->min_fps_no_render)); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_file->min_fps_no_render /= num_concurrent_decoders; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fields[7].empty()) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(base::StringToInt(fields[7], &video_file->profile)); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Read in the video data. 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath filepath(video_file->file_name); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(file_util::ReadFileToString(filepath, &video_file->data_str)) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "test_video_file: " << filepath.MaybeAsASCII(); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_video_files->push_back(video_file); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// State of the GLRenderingVDAClient below. Order matters here as the test 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// makes assumptions about it. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ClientState { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_CREATED = 0, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_DECODER_SET = 1, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_INITIALIZED = 2, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_FLUSHING = 3, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_FLUSHED = 4, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_DONE = 5, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_RESETTING = 6, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_RESET = 7, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_ERROR = 8, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_DESTROYED = 9, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CS_MAX, // Must be last entry. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class allowing one thread to wait on a notification from another. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If notifications come in faster than they are Wait()'d for, they are 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accumulated (so exactly as many Wait() calls will unblock as Notify() calls 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// were made, regardless of order). 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientStateNotification { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientStateNotification(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ClientStateNotification(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to notify a single waiter of a ClientState. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Notify(ClientState state); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used by waiters to wait for the next ClientState Notification. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientState Wait(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock lock_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ConditionVariable cv_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::queue<ClientState> pending_states_for_notification_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientStateNotification::ClientStateNotification() : cv_(&lock_) {} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientStateNotification::~ClientStateNotification() {} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClientStateNotification::Notify(ClientState state) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_states_for_notification_.push(state); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_.Signal(); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientState ClientStateNotification::Wait() { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pending_states_for_notification_.empty()) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_.Wait(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientState ret = pending_states_for_notification_.front(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_states_for_notification_.pop(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Client that can accept callbacks from a VideoDecodeAccelerator and is used by 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the TESTs below. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Doesn't take ownership of |rendering_helper| or |note|, which must outlive 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |*this|. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |num_fragments_per_decode| counts NALUs for h264 and frames for VP8. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |num_play_throughs| indicates how many times to play through the video. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset() should be done after that frame number is delivered, or 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // END_OF_STREAM_RESET to indicate no mid-stream Reset(). 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |delete_decoder_state| indicates when the underlying decoder should be 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // calls have been made, N>=0 means interpret as ClientState. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // last play-through (governed by |num_play_throughs|). 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLRenderingVDAClient(RenderingHelper* rendering_helper, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rendering_window_id, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientStateNotification* note, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& encoded_data, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_fragments_per_decode, 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_in_flight_decodes, 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_play_throughs, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int reset_after_frame_num, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delete_decoder_state, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int frame_width, 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int frame_height, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int profile); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~GLRenderingVDAClient(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateDecoder(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // VideoDecodeAccelerator::Client implementation. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The heart of the Client. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& dimensions, 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 texture_target) OVERRIDE; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void PictureReady(const media::Picture& picture) OVERRIDE; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simple state changes. 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NotifyInitializeDone() OVERRIDE; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NotifyFlushDone() OVERRIDE; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NotifyResetDone() OVERRIDE; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simple getters for inspecting the state of the Client. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_skipped_fragments() { return num_skipped_fragments_; } 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_queued_fragments() { return num_queued_fragments_; } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_decoded_frames() { return num_decoded_frames_; } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double frames_per_second(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool decoder_deleted() { return !decoder_.get(); } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int, media::PictureBuffer*> PictureBufferById; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetState(ClientState new_state); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the associated OMX decoder helper. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteDecoder(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compute & return the first encoded bytes (including a start frame) to send 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the decoder, starting at |start_pos| and returning 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |num_fragments_per_decode| units. Skips to the first decodable position. 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string GetBytesForFirstFragments(size_t start_pos, size_t* end_pos); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute & return the next encoded bytes to send to the decoder (based on 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |start_pos| & |num_fragments_per_decode_|). 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetBytesForNextFragments(size_t start_pos, size_t* end_pos); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helpers for GetRangeForNextFragments above. 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetBytesForNextNALU(size_t start_pos, size_t* end_pos); // For h.264. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetBytesForNextFrames( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_pos, size_t* end_pos); // For VP8. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Request decode of the next batch of fragments in the encoded data. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecodeNextFragments(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderingHelper* rendering_helper_; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rendering_window_id_; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encoded_data_; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int num_fragments_per_decode_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int num_in_flight_decodes_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int outstanding_decodes_; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t encoded_data_next_pos_to_decode_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int next_bitstream_buffer_id_; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientStateNotification* note_; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<VideoDecodeAccelerator> decoder_; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int> outstanding_texture_ids_; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_play_throughs_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reset_after_frame_num_; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int delete_decoder_state_; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientState state_; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_skipped_fragments_; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_queued_fragments_; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_decoded_frames_; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_done_bitstream_buffers_; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PictureBufferById picture_buffers_by_id_; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks initialize_done_ticks_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks last_frame_delivered_ticks_; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int profile_; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLRenderingVDAClient::GLRenderingVDAClient( 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderingHelper* rendering_helper, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rendering_window_id, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientStateNotification* note, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& encoded_data, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_fragments_per_decode, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_in_flight_decodes, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_play_throughs, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reset_after_frame_num, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int delete_decoder_state, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frame_width, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frame_height, 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int profile) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : rendering_helper_(rendering_helper), 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_window_id_(rendering_window_id), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_data_(encoded_data), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_fragments_per_decode_(num_fragments_per_decode), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) note_(note), 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_play_throughs_(num_play_throughs), 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_after_frame_num_(reset_after_frame_num), 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_decoder_state_(delete_decoder_state), 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(CS_CREATED), 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_skipped_fragments_(0), num_queued_fragments_(0), 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_decoded_frames_(0), num_done_bitstream_buffers_(0), 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(profile) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(num_fragments_per_decode, 0); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(num_in_flight_decodes, 0); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(num_play_throughs, 0); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLRenderingVDAClient::~GLRenderingVDAClient() { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteDecoder(); // Clean up in case of expected error. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(decoder_deleted()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteValues(&picture_buffers_by_id_); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_DESTROYED); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool DoNothingReturnTrue() { return true; } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::CreateDecoder() { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(decoder_deleted()); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!decoder_.get()); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(new DXVAVideoDecodeAccelerator( 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, base::Bind(&DoNothingReturnTrue))); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_CHROMEOS) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ARCH_CPU_ARMEL) 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) decoder_.reset( 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new ExynosVideoDecodeAccelerator( 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()), 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<EGLContext>(rendering_helper_->GetGLContext()), 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, base::Bind(&DoNothingReturnTrue))); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(ARCH_CPU_X86_FAMILY) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(new VaapiVideoDecodeAccelerator( 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<Display*>(rendering_helper_->GetGLDisplay()), 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<GLXContext>(rendering_helper_->GetGLContext()), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, base::Bind(&DoNothingReturnTrue))); 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // ARCH_CPU_ARMEL 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(decoder_.get()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_DECODER_SET); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Configure the decoder. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile = media::H264PROFILE_BASELINE; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile_ != -1) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile = static_cast<media::VideoCodecProfile>(profile_); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(decoder_->Initialize(profile)); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::ProvidePictureBuffers( 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 requested_num_of_buffers, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& dimensions, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 texture_target) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<media::PictureBuffer> buffers; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32 i = 0; i < requested_num_of_buffers; ++i) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 id = picture_buffers_by_id_.size(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 texture_id; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent done(false, false); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_helper_->CreateTexture( 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_window_id_, texture_target, &texture_id, &done); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(outstanding_texture_ids_.insert(texture_id).second); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::PictureBuffer* buffer = 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new media::PictureBuffer(id, dimensions, texture_id); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffers.push_back(*buffer); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->AssignPictureBuffers(buffers); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PictureBufferById::iterator it = 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers_by_id_.find(picture_buffer_id); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(it != picture_buffers_by_id_.end()); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(outstanding_texture_ids_.erase(it->second->texture_id()), 1U); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_helper_->DeleteTexture(it->second->texture_id()); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete it->second; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers_by_id_.erase(it); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We shouldn't be getting pictures delivered after Reset has completed. 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LT(state_, CS_RESET); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_frame_delivered_ticks_ = base::TimeTicks::Now(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_decoded_frames_; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mid-stream reset applies only to the last play-through per constructor 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // comment. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_play_throughs_ == 1 && 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_after_frame_num_ == num_decoded_frames_) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_after_frame_num_ = MID_STREAM_RESET; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Reset(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Re-start decoding from the beginning of the stream to avoid needing to 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // know how to find I-frames and so on in this test. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_data_next_pos_to_decode_ = 0; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::PictureBuffer* picture_buffer = 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) picture_buffers_by_id_[picture.picture_buffer_id()]; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(picture_buffer); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_helper_->RenderTexture(picture_buffer->texture_id()); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->ReusePictureBuffer(picture.picture_buffer_id()); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::NotifyInitializeDone() { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_INITIALIZED); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_done_ticks_ = base::TimeTicks::Now(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num_in_flight_decodes_; ++i) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecodeNextFragments(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 bitstream_buffer_id) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(fischman): this test currently relies on this notification to make 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // forward progress during a Reset(). But the VDA::Reset() API doesn't 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // guarantee this, so stop relying on it (and remove the notifications from 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // VaapiVideoDecodeAccelerator::FinishReset()). 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_done_bitstream_buffers_; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --outstanding_decodes_; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecodeNextFragments(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::NotifyFlushDone() { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_FLUSHED); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --remaining_play_throughs_; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_play_throughs_, 0); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Reset(); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_RESETTING); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::NotifyResetDone() { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reset_after_frame_num_ == MID_STREAM_RESET) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_after_frame_num_ = END_OF_STREAM_RESET; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecodeNextFragments(); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_play_throughs_) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_data_next_pos_to_decode_ = 0; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyInitializeDone(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_RESET); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!decoder_deleted()) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteDecoder(); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_ERROR); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool LookingAtNAL(const std::string& encoded, size_t pos) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return encoded[pos] == 0 && encoded[pos + 1] == 0 && 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded[pos + 2] == 0 && encoded[pos + 3] == 1; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::SetState(ClientState new_state) { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) note_->Notify(new_state); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = new_state; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!remaining_play_throughs_ && new_state == delete_decoder_state_) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!decoder_deleted()); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteDecoder(); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::DeleteDecoder() { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.release()->Destroy(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLClearObject(&encoded_data_); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<int>::iterator it = outstanding_texture_ids_.begin(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != outstanding_texture_ids_.end(); ++it) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_helper_->DeleteTexture(*it); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outstanding_texture_ids_.clear(); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cascade through the rest of the states to simplify test code below. 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = state_ + 1; i < CS_MAX; ++i) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(static_cast<ClientState>(i)); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string GLRenderingVDAClient::GetBytesForFirstFragments( 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t start_pos, size_t* end_pos) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_ < media::H264PROFILE_MAX) { 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *end_pos = start_pos; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (*end_pos + 4 < encoded_data_.size()) { 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((encoded_data_[*end_pos + 4] & 0x1f) == 0x7) // SPS start frame 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetBytesForNextFragments(*end_pos, end_pos); 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetBytesForNextNALU(*end_pos, end_pos); 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_skipped_fragments_++; 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *end_pos = start_pos; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::string(); 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(profile_, media::VP8PROFILE_MAX); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetBytesForNextFragments(start_pos, end_pos); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GLRenderingVDAClient::GetBytesForNextFragments( 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_pos, size_t* end_pos) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile_ < media::H264PROFILE_MAX) { 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t new_end_pos = start_pos; 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *end_pos = start_pos; 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < num_fragments_per_decode_; ++i) { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetBytesForNextNALU(*end_pos, &new_end_pos); 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*end_pos == new_end_pos) 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *end_pos = new_end_pos; 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_queued_fragments_++; 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return encoded_data_.substr(start_pos, *end_pos - start_pos); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(profile_, media::VP8PROFILE_MAX); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetBytesForNextFrames(start_pos, end_pos); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderingVDAClient::GetBytesForNextNALU( 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_pos, size_t* end_pos) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos = start_pos; 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*end_pos + 4 > encoded_data_.size()) 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(LookingAtNAL(encoded_data_, start_pos)); 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *end_pos += 4; 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (*end_pos + 4 <= encoded_data_.size() && 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !LookingAtNAL(encoded_data_, *end_pos)) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++*end_pos; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*end_pos + 3 >= encoded_data_.size()) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *end_pos = encoded_data_.size(); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GLRenderingVDAClient::GetBytesForNextFrames( 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_pos, size_t* end_pos) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string bytes; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_pos == 0) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_pos = 32; // Skip IVF header. 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos = start_pos; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num_fragments_per_decode_; ++i) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 frame_size = *reinterpret_cast<uint32*>(&encoded_data_[*end_pos]); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos += 12; // Skip frame header. 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes.append(encoded_data_.substr(*end_pos, frame_size)); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_pos += frame_size; 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_queued_fragments_++; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*end_pos + 12 >= encoded_data_.size()) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLRenderingVDAClient::DecodeNextFragments() { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_deleted()) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (outstanding_decodes_ == 0) { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Flush(); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CS_FLUSHING); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t end_pos; 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string next_fragment_bytes; 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (encoded_data_next_pos_to_decode_ == 0) { 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_fragment_bytes = GetBytesForFirstFragments(0, &end_pos); 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_fragment_bytes = 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetBytesForNextFragments(encoded_data_next_pos_to_decode_, &end_pos); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t next_fragment_size = next_fragment_bytes.size(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Populate the shared memory buffer w/ the fragments, duplicate its handle, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and hand it off to the decoder. 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory shm; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(shm.CreateAndMapAnonymous(next_fragment_size)); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(shm.memory(), next_fragment_bytes.data(), next_fragment_size); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle dup_handle; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle)); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::BitstreamBuffer bitstream_buffer( 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_bitstream_buffer_id_, dup_handle, next_fragment_size); 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Decode(bitstream_buffer); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++outstanding_decodes_; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoded_data_next_pos_to_decode_ = end_pos; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!remaining_play_throughs_ && 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -delete_decoder_state_ == next_bitstream_buffer_id_) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteDecoder(); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double GLRenderingVDAClient::frames_per_second() { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delta.InSecondsF() == 0) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return num_decoded_frames_ / delta.InSecondsF(); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test parameters: 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Number of fragments per Decode() call. 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Number of concurrent decoders. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Number of concurrent in-flight Decode() calls per decoder. 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Number of play-throughs. 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - reset_after_frame_num: see GLRenderingVDAClient ctor. 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - delete_decoder_phase: see GLRenderingVDAClient ctor. 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoDecodeAcceleratorTest 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public ::testing::TestWithParam< 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tuple6<int, int, int, int, ResetPoint, ClientState> > { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper so that gtest failures emit a more readable version of the tuple than 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// its byte representation. 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)::std::ostream& operator<<( 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::std::ostream& os, 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Tuple6<int, int, int, int, ResetPoint, ClientState>& t) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", " << t.f; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wait for |note| to report a state and if it's not |expected_state| then 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// assert |client| has deleted its decoder. 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void AssertWaitForStateOrDeleted(ClientStateNotification* note, 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLRenderingVDAClient* client, 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientState expected_state) { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientState state = note->Wait(); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == expected_state) return; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(client->decoder_deleted()) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Decoder not deleted but Wait() returned " << state 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", instead of " << expected_state; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We assert a minimal number of concurrent decoders we expect to succeed. 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Different platforms can support more concurrent decoders, so we don't assert 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// failure above this. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { kMinSupportedNumConcurrentDecoders = 3 }; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the most straightforward case possible: data is decoded from a single 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chunk and rendered to the screen. 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Can be useful for debugging VLOGs from OVDA. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // logging::SetMinLogLevel(-1); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Required for Thread to work. Not used otherwise. 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ShadowingAtExitManager at_exit_manager; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int num_fragments_per_decode = GetParam().a; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t num_concurrent_decoders = GetParam().b; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t num_in_flight_decodes = GetParam().c; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int num_play_throughs = GetParam().d; 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int reset_point = GetParam().e; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int delete_decoder_state = GetParam().f; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<TestVideoFile*> test_video_files; 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseAndReadTestVideoData(test_video_data, num_concurrent_decoders, 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reset_point, &test_video_files); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Suppress GL swapping in all but a few tests, to cut down overall test 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // runtime. 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool suppress_swap_to_display = num_fragments_per_decode > 1; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the rendering helper. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread rendering_thread("GLRenderingVDAClientThread"); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For windows the decoding thread initializes the media foundation decoder 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which uses COM. We need the thread to be a UI thread. 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_UI; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.StartWithOptions(options); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderingHelper> rendering_helper(RenderingHelper::Create()); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent done(false, false); 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<gfx::Size> frame_dimensions; 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t index = 0; index < test_video_files.size(); ++index) { 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame_dimensions.push_back(gfx::Size( 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_video_files[index]->width, test_video_files[index]->height)); 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.message_loop()->PostTask( 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&RenderingHelper::Initialize, 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(rendering_helper.get()), 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suppress_swap_to_display, num_concurrent_decoders, 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame_dimensions, &done)); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First kick off all the decoders. 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = 0; index < num_concurrent_decoders; ++index) { 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestVideoFile* video_file = 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_video_files[index % test_video_files.size()]; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientStateNotification* note = new ClientStateNotification(); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notes[index] = note; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLRenderingVDAClient* client = new GLRenderingVDAClient( 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rendering_helper.get(), index, note, video_file->data_str, 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_fragments_per_decode, num_in_flight_decodes, num_play_throughs, 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) video_file->reset_after_frame_num, delete_decoder_state, 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) video_file->width, video_file->height, video_file->profile); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clients[index] = client; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.message_loop()->PostTask( 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GLRenderingVDAClient::CreateDecoder, 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(client))); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(note->Wait(), CS_DECODER_SET); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then wait for all the decodes to finish. 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only check performance & correctness later if we play through only once. 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool skip_performance_and_correctness_checks = num_play_throughs > 1; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < num_concurrent_decoders; ++i) { 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientStateNotification* note = notes[i]; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientState state = note->Wait(); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state != CS_INITIALIZED) { 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_performance_and_correctness_checks = true; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We expect initialization to fail only when more than the supported 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of decoders is instantiated. Assert here that something else 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // didn't trigger failure. 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(num_concurrent_decoders, 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(kMinSupportedNumConcurrentDecoders)); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(state, CS_INITIALIZED); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int n = 0; n < num_play_throughs; ++n) { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For play-throughs other than the first, we expect initialization to 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succeed unconditionally. 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (n > 0) { 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertWaitForStateOrDeleted(note, clients[i], CS_INITIALIZED)); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitializeDone kicks off decoding inside the client, so we just need to 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wait for Flush. 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertWaitForStateOrDeleted(note, clients[i], CS_FLUSHING)); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertWaitForStateOrDeleted(note, clients[i], CS_FLUSHED)); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FlushDone requests Reset(). 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertWaitForStateOrDeleted(note, clients[i], CS_RESETTING)); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertWaitForStateOrDeleted(note, clients[i], CS_RESET)); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ResetDone requests Destroy(). 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertWaitForStateOrDeleted(note, clients[i], CS_DESTROYED)); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally assert that decoding went as expected. 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < num_concurrent_decoders && 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !skip_performance_and_correctness_checks; ++i) { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can only make performance/correctness assertions if the decoder was 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allowed to finish. 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delete_decoder_state < CS_FLUSHED) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLRenderingVDAClient* client = clients[i]; 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestVideoFile* video_file = test_video_files[i % test_video_files.size()]; 826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (video_file->num_frames > 0) { 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Expect the decoded frames may be more than the video frames as frames 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // could still be returned until resetting done. 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (video_file->reset_after_frame_num > 0) 830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_GE(client->num_decoded_frames(), video_file->num_frames); 831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(client->num_decoded_frames(), video_file->num_frames); 833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (reset_point == END_OF_STREAM_RESET) { 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(video_file->num_fragments, client->num_skipped_fragments() + 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->num_queued_fragments()); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(client->num_done_bitstream_buffers(), 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ceil(static_cast<double>(client->num_queued_fragments()) / 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_fragments_per_decode)); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Decoder " << i << " fps: " << client->frames_per_second(); 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int min_fps = suppress_swap_to_display ? 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_file->min_fps_no_render : video_file->min_fps_render; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min_fps > 0) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(client->frames_per_second(), min_fps); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.message_loop()->PostTask( 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*> >, 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &clients)); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.message_loop()->PostTask( 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&STLDeleteElements<std::vector<ClientStateNotification*> >, 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ¬es)); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.message_loop()->PostTask( 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&STLDeleteElements<std::vector<TestVideoFile*> >, 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &test_video_files)); 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rendering_thread.message_loop()->PostTask( 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&RenderingHelper::UnInitialize, 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(rendering_helper.get()), 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &done)); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rendering_thread.Stop(); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that replay after EOS works fine. 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReplayAfterEOS, VideoDecodeAcceleratorTest, 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::Values( 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 4, END_OF_STREAM_RESET, CS_RESET))); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Reset() mid-stream works fine and doesn't affect decoding even when 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decode() calls are made during the reset. 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MidStreamReset, VideoDecodeAcceleratorTest, 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::Values( 880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MakeTuple(1, 1, 1, 1, MID_STREAM_RESET, CS_RESET))); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Destroy() mid-stream works fine (primarily this is testing that no 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// crashes occur). 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TearDownTiming, VideoDecodeAcceleratorTest, 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::Values( 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_DECODER_SET), 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_INITIALIZED), 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHING), 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHED), 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING), 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ClientState>(-1)), 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ClientState>(-10)), 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ClientState>(-100)))); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 900b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Test that decoding various variation works: multiple fragments per Decode() 901b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// call and multiple in-flight decodes. 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecodeVariations, VideoDecodeAcceleratorTest, 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::Values( 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 10, 1, END_OF_STREAM_RESET, CS_RESET), 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tests queuing. 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, 1, 15, 1, END_OF_STREAM_RESET, CS_RESET), 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(2, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(3, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(5, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(8, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET), 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(fischman): decoding more than 15 NALUs at once breaks decode - 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visual artifacts are introduced as well as spurious frames are 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delivered (more pictures are returned than NALUs are fed to the 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decoder). Increase the "15" below when 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://code.google.com/p/chrome-os-partner/issues/detail?id=4378 is 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fixed. 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(15, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET))); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Find out how many concurrent decoders can go before we exhaust system 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resources. 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceExhaustion, VideoDecodeAcceleratorTest, 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::Values( 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +0 hack below to promote enum to int. 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, kMinSupportedNumConcurrentDecoders + 0, 1, 1, 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) END_OF_STREAM_RESET, CS_RESET), 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeTuple(1, kMinSupportedNumConcurrentDecoders + 1, 1, 1, 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) END_OF_STREAM_RESET, CS_RESET))); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(fischman, vrk): add more tests! In particular: 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Test life-cycle: Seek/Stop/Pause/Play for a single decoder. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Test alternate configurations 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Test failure conditions. 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Test frame size changes mid-stream 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) { 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::Init(argc, argv); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Needed to enable DVLOG through --vmodule. 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(logging::InitLogging( 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DONT_LOCK_LOG_FILE, 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::APPEND_TO_OLD_LOG_FILE, 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS)); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(cmd_line); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::SwitchMap switches = cmd_line->GetSwitches(); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CommandLine::SwitchMap::const_iterator it = switches.begin(); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != switches.end(); ++it) { 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->first == "test_video_data") { 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::test_video_data = it->second.c_str(); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->first == "v" || it->first == "vmodule") 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ShadowingAtExitManager at_exit_manager; 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderingHelper::InitializePlatform(); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_CHROMEOS) 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ARCH_CPU_ARMEL) 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(ARCH_CPU_X86_FAMILY) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::VaapiVideoDecodeAccelerator::PreSandboxInitialization(); 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // ARCH_CPU_ARMEL 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // OS_CHROMEOS 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RUN_ALL_TESTS(); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 983