blob: 4c17b0c6089ebfa6c11d48f56c4fb09e9d4a9ef4 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Package encode provides common code to run Chrome binary tests for video encoding.
package encode
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"chromiumos/tast/ctxutil"
"chromiumos/tast/local/bundles/cros/video/lib/logging"
"chromiumos/tast/local/bundles/cros/video/lib/videotype"
"chromiumos/tast/local/chrome/bintest"
"chromiumos/tast/local/upstart"
"chromiumos/tast/testing"
)
// StreamParams is the parameter for video_encode_accelerator_unittest.
type StreamParams struct {
// Name is the name of input raw data file.
Name string
// Size is the width and height of YUV image in the input raw data.
Size videotype.Size
// Bitrate is the requested bitrate in bits per second. VideoEncodeAccelerator is forced to output
// encoded video in expected range around the bitrate.
Bitrate int
// FrameRate is the initial frame rate in the test. This value is optional, and will be set to
// 30 if unspecified.
FrameRate int
// SubseqBitrate is the bitrate to switch to in the middle of the stream in some test cases in
// video_encode_accelerator_unittest. This value is optional, and will be set to two times of Bitrate if unspecified.
SubseqBitrate int
// SubseqFrameRate is the frame rate to switch to in the middle of the stream in some test cases in
// video_encode_accelerator_unittest. This value is optional, and will be set to 30 if unspecified.
SubseqFrameRate int
}
// TestOptions is the arguments for RunAccelVideoTest.
type TestOptions struct {
// Profile is the codec profile to encode.
Profile videotype.CodecProfile
// Params is the test parameters for video_encode_accelerator_unittest.
Params StreamParams
// PixelFormat is the pixel format of input raw video data.
PixelFormat videotype.PixelFormat
// ExtraArgs is the additional arguments to pass video_encode_accelerator_unittest, for example, "--native_input".
ExtraArgs []string
}
// RunAccelVideoTest runs video_encode_accelerator_unittest.
// It fails if video_encode_accelerator_unittest fails.
func RunAccelVideoTest(ctx context.Context, s *testing.State, opts TestOptions) {
vl, err := logging.NewVideoLogger()
if err != nil {
s.Fatal("Failed to set values for verbose logging: ", err)
}
defer vl.Close()
// Reserve time to restart the ui job at the end of the test.
// Only a single process can have access to the GPU, so we are required
// to call "stop ui" at the start of the test. This will shut down the
// chrome process and allow us to claim ownership of the GPU.
shortCtx, cancel := ctxutil.Shorten(ctx, 10*time.Second)
defer cancel()
upstart.StopJob(shortCtx, "ui")
defer upstart.EnsureJobRunning(ctx, "ui")
params := opts.Params
if !strings.HasSuffix(params.Name, ".vp9.webm") {
s.Fatalf("Source video %v must be VP9 WebM", params.Name)
}
streamPath, err := prepareYUV(shortCtx, s.DataPath(params.Name), opts.PixelFormat, params.Size)
if err != nil {
s.Fatal("Failed to prepare YUV file: ", err)
}
defer os.Remove(streamPath)
encodeOutFile := strings.TrimSuffix(params.Name, ".vp9.webm")
if opts.Profile == videotype.H264Prof {
encodeOutFile += ".h264"
} else {
encodeOutFile += ".vp8.ivf"
}
outPath := filepath.Join(s.OutDir(), encodeOutFile)
args := append([]string{logging.ChromeVmoduleFlag(),
createStreamDataArg(params, opts.Profile, opts.PixelFormat, streamPath, outPath),
"--ozone-platform=gbm",
}, opts.ExtraArgs...)
const exec = "video_encode_accelerator_unittest"
if err := bintest.Run(shortCtx, exec, args, s.OutDir()); err != nil {
s.Fatalf("Failed to run %v: %v", exec, err)
}
}
// createStreamDataArg creates an argument of video_encode_accelerator_unittest from profile, dataPath and outFile.
func createStreamDataArg(params StreamParams, profile videotype.CodecProfile, pixelFormat videotype.PixelFormat, dataPath, outFile string) string {
const (
defaultFrameRate = 30
defaultSubseqBitrateRatio = 2
)
// Fill default values if they are unsettled.
if params.FrameRate == 0 {
params.FrameRate = defaultFrameRate
}
if params.SubseqBitrate == 0 {
params.SubseqBitrate = params.Bitrate * defaultSubseqBitrateRatio
}
if params.SubseqFrameRate == 0 {
params.SubseqFrameRate = defaultFrameRate
}
streamDataArgs := fmt.Sprintf("--test_stream_data=%s:%d:%d:%d:%s:%d:%d:%d:%d:%d",
dataPath, params.Size.W, params.Size.H, int(profile), outFile,
params.Bitrate, params.FrameRate, params.SubseqBitrate,
params.SubseqFrameRate, int(pixelFormat))
return streamDataArgs
}