Commit 73aa0ab2 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

Revert "Reland: Add dav1d decoder and build configurations."

This reverts commit d8ec7dbd.

Reason for revert: This patch is suspicious to have caused failure at Dav1dVideoDecoderTest in media_unittests.

https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/Linux%20CFI/12634

Original change's description:
> Reland: Add dav1d decoder and build configurations.
> 
> PS#1 is the original change, the latest PS disables assembly
> for MSAN and fixes up the .gitignore file.
> 
> -----------[Original Description Below]-----------
> We're planning to experiment with av1 decoders, so this change
> adds support for dav1d in Chromium.
> 
> This sets up the dav1d repo per modern 3rd party style: It's a
> read-only clone of dav1d's GitHub mirror with the build config
> and helper scripts living in the main Chromium src.git repo.
> Due to this configuration, no local patches can be made.
> 
> Two helper scripts have been added "generate_configs.py" and
> "generate_source.py". The former requires a few dependencies
> spelled out in the README.chromium. The latter works simply
> by globbing some source patterns into GN variables.
> 
> Thus far it seems all posix configurations (mac, linux, CrOS)
> can share the same config, so only support linux and windows
> in x86, x64 configurations has been added.
> 
> ARM support is not enabled yet since we haven't enabled libaom
> for ARM and similarly dav1d is lacking much of the SIMD code.
> 
> To wire everything up this also:
> - Adds a media::VideoDecoder based implementation and unit test.
> - Adds a disabled-by-default Dav1dVideoDecoder base::Feature.
> 
> TBR=jam,liberato,mmoroz
> 
> Bug: 924370, 928357
> Change-Id: I0e921599830d6e52019106e3ad42672873c94ece
> Reviewed-on: https://chromium-review.googlesource.com/c/1452782
> Reviewed-by: Max Moroz <mmoroz@chromium.org>
> Reviewed-by: Frank Liberato <liberato@chromium.org>
> Reviewed-by: John Abd-El-Malek <jam@chromium.org>
> Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
> Commit-Queue: John Abd-El-Malek <jam@chromium.org>
> Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#628921}

TBR=dalecurtis@chromium.org,jam@chromium.org,liberato@chromium.org,mmoroz@chromium.org

Change-Id: I08a969e9d221bf8a3b2128f83cd14080da8c7139
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 924370, 928357
Reviewed-on: https://chromium-review.googlesource.com/c/1454100Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629077}
parent 6476a7fa
...@@ -607,9 +607,6 @@ deps = { ...@@ -607,9 +607,6 @@ deps = {
'src/third_party/angle': 'src/third_party/angle':
Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'), Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'),
'src/third_party/dav1d/libdav1d':
Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'f1b756ef5bdc0bb759b2b140f15362fec024c1ff',
'src/third_party/dawn': 'src/third_party/dawn':
Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'), Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'),
......
...@@ -22,7 +22,6 @@ buildflag_header("media_buildflags") { ...@@ -22,7 +22,6 @@ buildflag_header("media_buildflags") {
"ENABLE_CBCS_ENCRYPTION_SCHEME=$enable_cbcs_encryption_scheme", "ENABLE_CBCS_ENCRYPTION_SCHEME=$enable_cbcs_encryption_scheme",
"ENABLE_CDM_HOST_VERIFICATION=$enable_cdm_host_verification", "ENABLE_CDM_HOST_VERIFICATION=$enable_cdm_host_verification",
"ENABLE_CDM_STORAGE_ID=$enable_cdm_storage_id", "ENABLE_CDM_STORAGE_ID=$enable_cdm_storage_id",
"ENABLE_DAV1D_DECODER=$enable_dav1d_decoder",
"ENABLE_DOLBY_VISION_DEMUXING=$enable_dolby_vision_demuxing", "ENABLE_DOLBY_VISION_DEMUXING=$enable_dolby_vision_demuxing",
"ENABLE_FFMPEG=$media_use_ffmpeg", "ENABLE_FFMPEG=$media_use_ffmpeg",
"ENABLE_FFMPEG_VIDEO_DECODERS=$enable_ffmpeg_video_decoders", "ENABLE_FFMPEG_VIDEO_DECODERS=$enable_ffmpeg_video_decoders",
......
...@@ -12,7 +12,6 @@ include_rules = [ ...@@ -12,7 +12,6 @@ include_rules = [
"+mojo/public/cpp/system/platform_handle.h", "+mojo/public/cpp/system/platform_handle.h",
"+services/ws/public/cpp/gpu/context_provider_command_buffer.h", "+services/ws/public/cpp/gpu/context_provider_command_buffer.h",
"+skia/ext", "+skia/ext",
"+third_party/dav1d",
"+third_party/ffmpeg", "+third_party/ffmpeg",
"+third_party/libaom", "+third_party/libaom",
"+third_party/libvpx", "+third_party/libvpx",
......
...@@ -262,10 +262,6 @@ const base::Feature kMojoVideoDecoder{"MojoVideoDecoder", ...@@ -262,10 +262,6 @@ const base::Feature kMojoVideoDecoder{"MojoVideoDecoder",
const base::Feature kD3D11VideoDecoder{"D3D11VideoDecoder", const base::Feature kD3D11VideoDecoder{"D3D11VideoDecoder",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
// Enable usage of dav1d for AV1 video decoding.
const base::Feature kDav1dVideoDecoder{"Dav1dVideoDecoder",
base::FEATURE_DISABLED_BY_DEFAULT};
// Falls back to other decoders after audio/video decode error happens. The // Falls back to other decoders after audio/video decode error happens. The
// implementation may choose different strategies on when to fallback. See // implementation may choose different strategies on when to fallback. See
// DecoderStream for details. When disabled, playback will fail immediately // DecoderStream for details. When disabled, playback will fail immediately
......
...@@ -104,7 +104,6 @@ MEDIA_EXPORT extern const base::Feature kAutoplayWhitelistSettings; ...@@ -104,7 +104,6 @@ MEDIA_EXPORT extern const base::Feature kAutoplayWhitelistSettings;
MEDIA_EXPORT extern const base::Feature kBackgroundSrcVideoTrackOptimization; MEDIA_EXPORT extern const base::Feature kBackgroundSrcVideoTrackOptimization;
MEDIA_EXPORT extern const base::Feature kBackgroundVideoPauseOptimization; MEDIA_EXPORT extern const base::Feature kBackgroundVideoPauseOptimization;
MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoder; MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoder;
MEDIA_EXPORT extern const base::Feature kDav1dVideoDecoder;
MEDIA_EXPORT extern const base::Feature kExternalClearKeyForTesting; MEDIA_EXPORT extern const base::Feature kExternalClearKeyForTesting;
MEDIA_EXPORT extern const base::Feature kFallbackAfterDecodeError; MEDIA_EXPORT extern const base::Feature kFallbackAfterDecodeError;
MEDIA_EXPORT extern const base::Feature kHardwareMediaKeyHandling; MEDIA_EXPORT extern const base::Feature kHardwareMediaKeyHandling;
......
...@@ -161,14 +161,6 @@ jumbo_source_set("filters") { ...@@ -161,14 +161,6 @@ jumbo_source_set("filters") {
deps += [ "//third_party/libaom" ] deps += [ "//third_party/libaom" ]
} }
if (enable_dav1d_decoder) {
sources += [
"dav1d_video_decoder.cc",
"dav1d_video_decoder.h",
]
deps += [ "//third_party/dav1d" ]
}
if (media_use_ffmpeg) { if (media_use_ffmpeg) {
if (proprietary_codecs) { if (proprietary_codecs) {
sources += [ sources += [
...@@ -371,10 +363,6 @@ source_set("unit_tests") { ...@@ -371,10 +363,6 @@ source_set("unit_tests") {
if (enable_av1_decoder) { if (enable_av1_decoder) {
sources += [ "aom_video_decoder_unittest.cc" ] sources += [ "aom_video_decoder_unittest.cc" ]
if (enable_dav1d_decoder) {
sources += [ "dav1d_video_decoder_unittest.cc" ]
}
} }
if (current_cpu != "arm" && is_linux) { if (current_cpu != "arm" && is_linux) {
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/dav1d_video_decoder.h"
#include <memory>
#include <string>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/decoder_buffer.h"
#include "media/base/media_log.h"
#include "media/base/video_util.h"
extern "C" {
// Prevents symbol exports. See //third_party/dav1d/BUILD.gn for details.
#define DAV1D_API
#include "third_party/dav1d/libdav1d/include/dav1d/dav1d.h"
}
namespace media {
// Returns the number of threads.
static int GetDecoderThreadCount(const VideoDecoderConfig& config) {
// For AV1 decode when using the default thread count, increase the number
// of decode threads to equal the maximum number of tiles possible for
// higher resolution streams.
return VideoDecoder::GetRecommendedThreadCount(config.coded_size().width() /
256);
}
static VideoPixelFormat Dav1dImgFmtToVideoPixelFormat(
const Dav1dPictureParameters* pic) {
switch (pic->layout) {
case DAV1D_PIXEL_LAYOUT_I420:
switch (pic->bpc) {
case 8:
return PIXEL_FORMAT_I420;
case 10:
return PIXEL_FORMAT_YUV420P10;
case 12:
return PIXEL_FORMAT_YUV420P12;
default:
DLOG(ERROR) << "Unsupported bit depth: " << pic->bpc;
return PIXEL_FORMAT_UNKNOWN;
}
case DAV1D_PIXEL_LAYOUT_I422:
switch (pic->bpc) {
case 8:
return PIXEL_FORMAT_I422;
case 10:
return PIXEL_FORMAT_YUV422P10;
case 12:
return PIXEL_FORMAT_YUV422P12;
default:
DLOG(ERROR) << "Unsupported bit depth: " << pic->bpc;
return PIXEL_FORMAT_UNKNOWN;
}
case DAV1D_PIXEL_LAYOUT_I444:
switch (pic->bpc) {
case 8:
return PIXEL_FORMAT_I444;
case 10:
return PIXEL_FORMAT_YUV444P10;
case 12:
return PIXEL_FORMAT_YUV444P12;
default:
DLOG(ERROR) << "Unsupported bit depth: " << pic->bpc;
return PIXEL_FORMAT_UNKNOWN;
}
default:
DLOG(ERROR) << "Unsupported pixel format: " << pic->layout;
return PIXEL_FORMAT_UNKNOWN;
}
}
static void ReleaseDecoderBuffer(const uint8_t* buffer, void* opaque) {
if (opaque)
static_cast<DecoderBuffer*>(opaque)->Release();
}
static void LogDav1dMessage(void* cookie, const char* format, va_list ap) {
auto log = base::StringPrintV(format, ap);
if (log.empty())
return;
if (log.back() == '\n')
log.pop_back();
DLOG(ERROR) << log;
}
// std::unique_ptr release helper.
struct ScopedDav1dPictureFree {
void operator()(void* x) const {
dav1d_picture_unref(static_cast<Dav1dPicture*>(x));
}
};
Dav1dVideoDecoder::Dav1dVideoDecoder(MediaLog* media_log)
: media_log_(media_log) {
DETACH_FROM_THREAD(thread_checker_);
}
Dav1dVideoDecoder::~Dav1dVideoDecoder() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
CloseDecoder();
}
std::string Dav1dVideoDecoder::GetDisplayName() const {
return "Dav1dVideoDecoder";
}
void Dav1dVideoDecoder::Initialize(const VideoDecoderConfig& config,
bool low_delay,
CdmContext* /* cdm_context */,
const InitCB& init_cb,
const OutputCB& output_cb,
const WaitingCB& /* waiting_cb */) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(config.IsValidConfig());
InitCB bound_init_cb = BindToCurrentLoop(init_cb);
if (config.is_encrypted() || config.codec() != kCodecAV1) {
bound_init_cb.Run(false);
return;
}
// Clear any previously initialized decoder.
CloseDecoder();
Dav1dSettings s;
dav1d_default_settings(&s);
s.n_tile_threads = GetDecoderThreadCount(config);
// Use only 1 frame thread in low delay mode, otherwise we'll require at least
// two buffers before the first frame can be output.
s.n_frame_threads = low_delay ? 1 : 2;
// Route dav1d internal logs through Chrome's DLOG system.
s.logger = {nullptr, &LogDav1dMessage};
if (dav1d_open(&dav1d_decoder_, &s) < 0) {
bound_init_cb.Run(false);
return;
}
config_ = config;
state_ = DecoderState::kNormal;
output_cb_ = BindToCurrentLoop(output_cb);
bound_init_cb.Run(true);
}
void Dav1dVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
const DecodeCB& decode_cb) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(buffer);
DCHECK(decode_cb);
DCHECK_NE(state_, DecoderState::kUninitialized)
<< "Called Decode() before successful Initialize()";
DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb);
if (state_ == DecoderState::kError) {
bound_decode_cb.Run(DecodeStatus::DECODE_ERROR);
return;
}
if (!DecodeBuffer(std::move(buffer))) {
state_ = DecoderState::kError;
bound_decode_cb.Run(DecodeStatus::DECODE_ERROR);
return;
}
// VideoDecoderShim expects |decode_cb| call after |output_cb_|.
bound_decode_cb.Run(DecodeStatus::OK);
}
void Dav1dVideoDecoder::Reset(const base::RepeatingClosure& reset_cb) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
state_ = DecoderState::kNormal;
dav1d_flush(dav1d_decoder_);
timestamps_.clear();
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, reset_cb);
}
void Dav1dVideoDecoder::CloseDecoder() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!dav1d_decoder_)
return;
dav1d_close(&dav1d_decoder_);
DCHECK(!dav1d_decoder_);
}
bool Dav1dVideoDecoder::DecodeBuffer(scoped_refptr<DecoderBuffer> buffer) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
Dav1dData* input_buffer = nullptr;
if (!buffer->end_of_stream()) {
// TODO(dalecurtis): Add a pool of these?
input_buffer = new Dav1dData();
if (dav1d_data_wrap(input_buffer, buffer->data(), buffer->data_size(),
&ReleaseDecoderBuffer, buffer.get()) < 0) {
return false;
}
timestamps_.push_back(buffer->timestamp());
buffer->AddRef();
}
while (!input_buffer || input_buffer->sz) {
if (input_buffer) {
const int res = dav1d_send_data(dav1d_decoder_, input_buffer);
if (res < 0 && res != -EAGAIN) {
MEDIA_LOG(ERROR, media_log_) << "dav1d_send_data() failed on "
<< buffer->AsHumanReadableString();
return false;
}
// Even if dav1d_send_data() returned EAGAIN, try dav1d_get_picture().
}
using ScopedPtrDav1dPicture =
std::unique_ptr<Dav1dPicture, ScopedDav1dPictureFree>;
ScopedPtrDav1dPicture p(new Dav1dPicture{0});
const int res = dav1d_get_picture(dav1d_decoder_, p.get());
if (res < 0) {
if (res != -EAGAIN) {
MEDIA_LOG(ERROR, media_log_) << "dav1d_get_picture() failed on "
<< buffer->AsHumanReadableString();
return false;
}
// We've reached end of stream and no frames remain to drain.
if (!input_buffer)
return true;
continue;
}
auto frame = CopyImageToVideoFrame(p.get());
if (!frame) {
MEDIA_LOG(DEBUG, media_log_)
<< "Failed to produce video frame from Dav1dPicture.";
return false;
}
// AV1 color space defines match ISO 23001-8:2016 via ISO/IEC 23091-4/ITU-T
// H.273. https://aomediacodec.github.io/av1-spec/#color-config-semantics
media::VideoColorSpace color_space(
p->seq_hdr->pri, p->seq_hdr->trc, p->seq_hdr->mtrx,
p->seq_hdr->color_range ? gfx::ColorSpace::RangeID::FULL
: gfx::ColorSpace::RangeID::LIMITED);
// If the frame doesn't specify a color space, use the container's.
if (!color_space.IsSpecified())
color_space = config_.color_space_info();
frame->set_color_space(color_space.ToGfxColorSpace());
frame->metadata()->SetBoolean(VideoFrameMetadata::POWER_EFFICIENT, false);
frame->AddDestructionObserver(base::BindOnce(
base::DoNothing::Once<ScopedPtrDav1dPicture>(), std::move(p)));
output_cb_.Run(std::move(frame));
}
return true;
}
scoped_refptr<VideoFrame> Dav1dVideoDecoder::CopyImageToVideoFrame(
const Dav1dPicture* pic) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
VideoPixelFormat pixel_format = Dav1dImgFmtToVideoPixelFormat(&pic->p);
if (pixel_format == PIXEL_FORMAT_UNKNOWN)
return nullptr;
const auto timestamp = timestamps_.front();
timestamps_.pop_front();
// Since we're making a copy, only copy the visible area.
const gfx::Size visible_size(pic->p.w, pic->p.h);
return VideoFrame::WrapExternalYuvData(
pixel_format, visible_size, gfx::Rect(visible_size),
config_.natural_size(), pic->stride[0], pic->stride[1], pic->stride[1],
static_cast<uint8_t*>(pic->data[0]), static_cast<uint8_t*>(pic->data[1]),
static_cast<uint8_t*>(pic->data[2]), timestamp);
}
} // namespace media
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FILTERS_DAV1D_VIDEO_DECODER_H_
#define MEDIA_FILTERS_DAV1D_VIDEO_DECODER_H_
#include <string>
#include "base/callback_forward.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_pool.h"
struct Dav1dContext;
struct Dav1dPicture;
namespace media {
class MediaLog;
class MEDIA_EXPORT Dav1dVideoDecoder : public VideoDecoder {
public:
explicit Dav1dVideoDecoder(MediaLog* media_log);
~Dav1dVideoDecoder() override;
// VideoDecoder implementation.
std::string GetDisplayName() const override;
void Initialize(const VideoDecoderConfig& config,
bool low_delay,
CdmContext* cdm_context,
const InitCB& init_cb,
const OutputCB& output_cb,
const WaitingCB& waiting_cb) override;
void Decode(scoped_refptr<DecoderBuffer> buffer,
const DecodeCB& decode_cb) override;
void Reset(const base::RepeatingClosure& reset_cb) override;
private:
enum class DecoderState {
kUninitialized,
kNormal,
kFlushCodec,
kDecodeFinished,
kError
};
// Releases any configured decoder and clears |dav1d_decoder_|.
void CloseDecoder();
// Invokes the decoder and calls |output_cb_| for any returned frames.
bool DecodeBuffer(scoped_refptr<DecoderBuffer> buffer);
scoped_refptr<VideoFrame> CopyImageToVideoFrame(const Dav1dPicture* img);
THREAD_CHECKER(thread_checker_);
// Used to report error messages to the client.
MediaLog* const media_log_ = nullptr;
// Current decoder state. Used to ensure methods are called as expected.
DecoderState state_ = DecoderState::kUninitialized;
// Callback given during Initialize() used for delivering decoded frames.
OutputCB output_cb_;
// The configuration passed to Initialize(), saved since some fields are
// needed to annotate video frames after decoding.
VideoDecoderConfig config_;
// The allocated decoder; null before Initialize() and anytime after
// CloseDecoder().
Dav1dContext* dav1d_decoder_ = nullptr;
base::circular_deque<base::TimeDelta> timestamps_;
DISALLOW_COPY_AND_ASSIGN(Dav1dVideoDecoder);
};
} // namespace media
#endif // MEDIA_FILTERS_DAV1D_VIDEO_DECODER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "media/base/decoder_buffer.h"
#include "media/base/limits.h"
#include "media/base/mock_media_log.h"
#include "media/base/test_data_util.h"
#include "media/base/test_helpers.h"
#include "media/base/video_frame.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/dav1d_video_decoder.h"
#include "media/filters/in_memory_url_protocol.h"
#include "testing/gmock/include/gmock/gmock.h"
using ::testing::_;
namespace media {
// TODO(dalecurtis): There is some weird collision going on with this matcher
// and the one defined in the AomVideoDecoder unittest. Somehow only one ends
// up in the final binary so one test or the other will fail. To workaround this
// give it a unique name for now...
MATCHER(ContainsDav1dDecoderErrorLog, "") {
return CONTAINS_STRING(arg, "dav1d_get_picture() failed");
}
class Dav1dVideoDecoderTest : public testing::Test {
public:
Dav1dVideoDecoderTest()
: decoder_(new Dav1dVideoDecoder(&media_log_)),
i_frame_buffer_(ReadTestDataFile("av1-I-frame-320x240")) {}
~Dav1dVideoDecoderTest() override { Destroy(); }
void Initialize() {
InitializeWithConfig(TestVideoConfig::Normal(kCodecAV1));
}
void InitializeWithConfigWithResult(const VideoDecoderConfig& config,
bool success) {
decoder_->Initialize(
config, true, // Use low delay so we get 1 frame out for each frame in.
nullptr, NewExpectedBoolCB(success),
base::BindRepeating(&Dav1dVideoDecoderTest::FrameReady,
base::Unretained(this)),
base::NullCallback());
base::RunLoop().RunUntilIdle();
}
void InitializeWithConfig(const VideoDecoderConfig& config) {
InitializeWithConfigWithResult(config, true);
}
void Reinitialize() {
InitializeWithConfig(TestVideoConfig::Large(kCodecAV1));
}
void Reset() {
decoder_->Reset(NewExpectedClosure());
base::RunLoop().RunUntilIdle();
}
void Destroy() {
decoder_.reset();
base::RunLoop().RunUntilIdle();
}
// Sets up expectations and actions to put Dav1dVideoDecoder in an active
// decoding state.
void ExpectDecodingState() {
EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_));
ASSERT_EQ(1U, output_frames_.size());
}
// Sets up expectations and actions to put Dav1dVideoDecoder in an end
// of stream state.
void ExpectEndOfStreamState() {
EXPECT_EQ(DecodeStatus::OK,
DecodeSingleFrame(DecoderBuffer::CreateEOSBuffer()));
ASSERT_FALSE(output_frames_.empty());
}
using InputBuffers = std::vector<scoped_refptr<DecoderBuffer>>;
using OutputFrames = std::vector<scoped_refptr<VideoFrame>>;
// Decodes all buffers in |input_buffers| and push all successfully decoded
// output frames into |output_frames|. Returns the last decode status returned
// by the decoder.
DecodeStatus DecodeMultipleFrames(const InputBuffers& input_buffers) {
for (auto iter = input_buffers.begin(); iter != input_buffers.end();
++iter) {
DecodeStatus status = Decode(*iter);
switch (status) {
case DecodeStatus::OK:
break;
case DecodeStatus::ABORTED:
NOTREACHED();
FALLTHROUGH;
case DecodeStatus::DECODE_ERROR:
DCHECK(output_frames_.empty());
return status;
}
}
return DecodeStatus::OK;
}
// Decodes the single compressed frame in |buffer|.
DecodeStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) {
InputBuffers input_buffers;
input_buffers.push_back(std::move(buffer));
return DecodeMultipleFrames(input_buffers);
}
// Decodes |i_frame_buffer_| and then decodes the data contained in the file
// named |test_file_name|. This function expects both buffers to decode to
// frames that are the same size.
void DecodeIFrameThenTestFile(const std::string& test_file_name,
const gfx::Size& expected_size) {
Initialize();
scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name);
InputBuffers input_buffers;
input_buffers.push_back(i_frame_buffer_);
input_buffers.push_back(buffer);
input_buffers.push_back(DecoderBuffer::CreateEOSBuffer());
DecodeStatus status = DecodeMultipleFrames(input_buffers);
EXPECT_EQ(DecodeStatus::OK, status);
ASSERT_EQ(2U, output_frames_.size());
gfx::Size original_size = TestVideoConfig::NormalCodedSize();
EXPECT_EQ(original_size.width(),
output_frames_[0]->visible_rect().size().width());
EXPECT_EQ(original_size.height(),
output_frames_[0]->visible_rect().size().height());
EXPECT_EQ(expected_size.width(),
output_frames_[1]->visible_rect().size().width());
EXPECT_EQ(expected_size.height(),
output_frames_[1]->visible_rect().size().height());
}
DecodeStatus Decode(scoped_refptr<DecoderBuffer> buffer) {
DecodeStatus status;
EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status));
decoder_->Decode(std::move(buffer),
base::BindRepeating(&Dav1dVideoDecoderTest::DecodeDone,
base::Unretained(this)));
base::RunLoop().RunUntilIdle();
return status;
}
void FrameReady(const scoped_refptr<VideoFrame>& frame) {
DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
output_frames_.push_back(frame);
}
MOCK_METHOD1(DecodeDone, void(DecodeStatus));
testing::StrictMock<MockMediaLog> media_log_;
base::MessageLoop message_loop_;
std::unique_ptr<Dav1dVideoDecoder> decoder_;
scoped_refptr<DecoderBuffer> i_frame_buffer_;
OutputFrames output_frames_;
private:
DISALLOW_COPY_AND_ASSIGN(Dav1dVideoDecoderTest);
};
TEST_F(Dav1dVideoDecoderTest, Initialize_Normal) {
Initialize();
}
TEST_F(Dav1dVideoDecoderTest, Reinitialize_Normal) {
Initialize();
Reinitialize();
}
TEST_F(Dav1dVideoDecoderTest, Reinitialize_AfterDecodeFrame) {
Initialize();
ExpectDecodingState();
Reinitialize();
}
TEST_F(Dav1dVideoDecoderTest, Reinitialize_AfterReset) {
Initialize();
ExpectDecodingState();
Reset();
Reinitialize();
}
TEST_F(Dav1dVideoDecoderTest, DecodeFrame_Normal) {
Initialize();
// Simulate decoding a single frame.
EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_));
ASSERT_EQ(1U, output_frames_.size());
}
// Decode |i_frame_buffer_| and then a frame with a larger width and verify
// the output size was adjusted.
// TODO(dalecurtis): Get an I-frame from a larger video.
TEST_F(Dav1dVideoDecoderTest, DISABLED_DecodeFrame_LargerWidth) {
DecodeIFrameThenTestFile("av1-I-frame-320x240", gfx::Size(1280, 720));
}
// Decode a VP9 frame which should trigger a decoder error.
TEST_F(Dav1dVideoDecoderTest, DecodeFrame_Error) {
Initialize();
EXPECT_MEDIA_LOG(ContainsDav1dDecoderErrorLog());
DecodeSingleFrame(ReadTestDataFile("vp9-I-frame-320x240"));
}
// Test resetting when decoder has initialized but not decoded.
TEST_F(Dav1dVideoDecoderTest, Reset_Initialized) {
Initialize();
Reset();
}
// Test resetting when decoder has decoded single frame.
TEST_F(Dav1dVideoDecoderTest, Reset_Decoding) {
Initialize();
ExpectDecodingState();
Reset();
}
// Test resetting when decoder has hit end of stream.
TEST_F(Dav1dVideoDecoderTest, Reset_EndOfStream) {
Initialize();
ExpectDecodingState();
ExpectEndOfStreamState();
Reset();
}
// Test destruction when decoder has initialized but not decoded.
TEST_F(Dav1dVideoDecoderTest, Destroy_Initialized) {
Initialize();
Destroy();
}
// Test destruction when decoder has decoded single frame.
TEST_F(Dav1dVideoDecoderTest, Destroy_Decoding) {
Initialize();
ExpectDecodingState();
Destroy();
}
// Test destruction when decoder has hit end of stream.
TEST_F(Dav1dVideoDecoderTest, Destroy_EndOfStream) {
Initialize();
ExpectDecodingState();
ExpectEndOfStreamState();
Destroy();
}
TEST_F(Dav1dVideoDecoderTest, FrameValidAfterPoolDestruction) {
Initialize();
Decode(i_frame_buffer_);
Destroy();
ASSERT_FALSE(output_frames_.empty());
// Write to the Y plane. The memory tools should detect a
// use-after-free if the storage was actually removed by pool destruction.
memset(output_frames_.front()->data(VideoFrame::kYPlane), 0xff,
output_frames_.front()->rows(VideoFrame::kYPlane) *
output_frames_.front()->stride(VideoFrame::kYPlane));
}
} // namespace media
...@@ -7,7 +7,6 @@ import("//build/config/chromecast_build.gni") ...@@ -7,7 +7,6 @@ import("//build/config/chromecast_build.gni")
import("//build/config/features.gni") import("//build/config/features.gni")
import("//media/gpu/args.gni") import("//media/gpu/args.gni")
import("//testing/libfuzzer/fuzzer_test.gni") import("//testing/libfuzzer/fuzzer_test.gni")
import("//third_party/libaom/options.gni")
# Do not expand this list without double-checking with OWNERS, this is a list of # Do not expand this list without double-checking with OWNERS, this is a list of
# all targets which roll up into the //media component. It controls visibility # all targets which roll up into the //media component. It controls visibility
...@@ -84,9 +83,6 @@ declare_args() { ...@@ -84,9 +83,6 @@ declare_args() {
# If true, use cast CMA backend instead of default chromium media pipeline. # If true, use cast CMA backend instead of default chromium media pipeline.
# TODO(sanfin): Remove this flag when all builds enable CMA. # TODO(sanfin): Remove this flag when all builds enable CMA.
is_cast_using_cma_backend = true is_cast_using_cma_backend = true
# Dav1d is only enabled when av1 decoding is enabled.
enable_dav1d_decoder = enable_av1_decoder
} }
# enable_hls_sample_aes can only be true if enable_mse_mpeg2ts_stream_parser is. # enable_hls_sample_aes can only be true if enable_mse_mpeg2ts_stream_parser is.
......
...@@ -31,10 +31,6 @@ ...@@ -31,10 +31,6 @@
#include "media/filters/aom_video_decoder.h" #include "media/filters/aom_video_decoder.h"
#endif #endif
#if BUILDFLAG(ENABLE_DAV1D_DECODER)
#include "media/filters/dav1d_video_decoder.h"
#endif
#if BUILDFLAG(ENABLE_FFMPEG) #if BUILDFLAG(ENABLE_FFMPEG)
#include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_audio_decoder.h"
#endif #endif
...@@ -62,7 +58,7 @@ void DefaultDecoderFactory::CreateAudioDecoders( ...@@ -62,7 +58,7 @@ void DefaultDecoderFactory::CreateAudioDecoders(
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
// DecryptingAudioDecoder is only needed in External Clear Key testing to // DecryptingAudioDecoder is only needed in External Clear Key testing to
// cover the audio decrypt-and-decode path. // cover the audio decrypt-and-decode path.
if (base::FeatureList::IsEnabled(kExternalClearKeyForTesting)) { if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting)) {
audio_decoders->push_back( audio_decoders->push_back(
std::make_unique<DecryptingAudioDecoder>(task_runner, media_log)); std::make_unique<DecryptingAudioDecoder>(task_runner, media_log));
} }
...@@ -103,7 +99,7 @@ void DefaultDecoderFactory::CreateVideoDecoders( ...@@ -103,7 +99,7 @@ void DefaultDecoderFactory::CreateVideoDecoders(
// MojoVideoDecoder replaces any VDA for this platform when it's enabled. // MojoVideoDecoder replaces any VDA for this platform when it's enabled.
if (external_decoder_factory_ && if (external_decoder_factory_ &&
base::FeatureList::IsEnabled(kMojoVideoDecoder)) { base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) {
external_decoder_factory_->CreateVideoDecoders( external_decoder_factory_->CreateVideoDecoders(
task_runner, gpu_factories, media_log, request_overlay_info_cb, task_runner, gpu_factories, media_log, request_overlay_info_cb,
target_color_space, video_decoders); target_color_space, video_decoders);
...@@ -122,12 +118,7 @@ void DefaultDecoderFactory::CreateVideoDecoders( ...@@ -122,12 +118,7 @@ void DefaultDecoderFactory::CreateVideoDecoders(
video_decoders->push_back(std::make_unique<OffloadingVpxVideoDecoder>()); video_decoders->push_back(std::make_unique<OffloadingVpxVideoDecoder>());
#endif #endif
#if BUILDFLAG(ENABLE_DAV1D_DECODER) #if BUILDFLAG(ENABLE_AV1_DECODER)
if (base::FeatureList::IsEnabled(kDav1dVideoDecoder))
video_decoders->push_back(std::make_unique<Dav1dVideoDecoder>(media_log));
else
video_decoders->push_back(std::make_unique<AomVideoDecoder>(media_log));
#elif BUILDFLAG(ENABLE_AV1_DECODER)
video_decoders->push_back(std::make_unique<AomVideoDecoder>(media_log)); video_decoders->push_back(std::make_unique<AomVideoDecoder>(media_log));
#endif #endif
......
...@@ -248,20 +248,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -248,20 +248,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzerVariant variant = PIPELINE_FUZZER_VARIANT; FuzzerVariant variant = PIPELINE_FUZZER_VARIANT;
if (variant == SRC) { if (variant == SRC) {
{ media::ProgressivePipelineIntegrationFuzzerTest test;
media::ProgressivePipelineIntegrationFuzzerTest test; test.RunTest(data, size);
test.RunTest(data, size);
}
{
// Rerun the test with the dav1d video decoder instead of libaom. Note:
// this ends up running for all SRC fuzzing and not just AV1 content, but
// that's true for our entire corpus.
base::test::ScopedFeatureList features_with_dav1d;
features_with_dav1d.InitAndEnableFeature(media::kDav1dVideoDecoder);
media::ProgressivePipelineIntegrationFuzzerTest test;
test.RunTest(data, size);
}
} else { } else {
// Sequentially fuzz with new and old MSE buffering APIs. See // Sequentially fuzz with new and old MSE buffering APIs. See
// https://crbug.com/718641. // https://crbug.com/718641.
...@@ -279,15 +267,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -279,15 +267,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
media::MediaSourcePipelineIntegrationFuzzerTest test; media::MediaSourcePipelineIntegrationFuzzerTest test;
test.RunTest(data, size, MseFuzzerVariantEnumToMimeTypeString(variant)); test.RunTest(data, size, MseFuzzerVariantEnumToMimeTypeString(variant));
} }
// Rerun the test with the dav1d video decoder instead of libaom. No need to
// run with ByPts in both configurations, just use the default.
if (variant == MP4_AV1) {
base::test::ScopedFeatureList features_with_dav1d;
features_with_dav1d.InitAndEnableFeature(media::kDav1dVideoDecoder);
media::MediaSourcePipelineIntegrationFuzzerTest test;
test.RunTest(data, size, MseFuzzerVariantEnumToMimeTypeString(variant));
}
} }
return 0; return 0;
......
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
#include "media/filters/aom_video_decoder.h" #include "media/filters/aom_video_decoder.h"
#endif #endif
#if BUILDFLAG(ENABLE_DAV1D_DECODER)
#include "media/filters/dav1d_video_decoder.h"
#endif
#if BUILDFLAG(ENABLE_FFMPEG) #if BUILDFLAG(ENABLE_FFMPEG)
#include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_audio_decoder.h"
#include "media/filters/ffmpeg_demuxer.h" #include "media/filters/ffmpeg_demuxer.h"
...@@ -73,12 +69,7 @@ static std::vector<std::unique_ptr<VideoDecoder>> CreateVideoDecodersForTest( ...@@ -73,12 +69,7 @@ static std::vector<std::unique_ptr<VideoDecoder>> CreateVideoDecodersForTest(
video_decoders.push_back(std::make_unique<OffloadingVpxVideoDecoder>()); video_decoders.push_back(std::make_unique<OffloadingVpxVideoDecoder>());
#endif #endif
#if BUILDFLAG(ENABLE_DAV1D_DECODER) #if BUILDFLAG(ENABLE_AV1_DECODER)
if (base::FeatureList::IsEnabled(kDav1dVideoDecoder))
video_decoders.push_back(std::make_unique<Dav1dVideoDecoder>(media_log));
else
video_decoders.push_back(std::make_unique<AomVideoDecoder>(media_log));
#elif BUILDFLAG(ENABLE_AV1_DECODER)
video_decoders.push_back(std::make_unique<AomVideoDecoder>(media_log)); video_decoders.push_back(std::make_unique<AomVideoDecoder>(media_log));
#endif #endif
......
...@@ -59,7 +59,6 @@ ...@@ -59,7 +59,6 @@
/cros_system_api /cros_system_api
/custom_tabs_client/src /custom_tabs_client/src
/cygwin /cygwin
/dav1d/libdav1d
/dawn /dawn
/depot_tools /depot_tools
/devtools-node-modules /devtools-node-modules
......
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("dav1d_generated.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//third_party/nasm/nasm_assemble.gni")
if (is_win) {
enable_x64_asm = true
platform_config_root = "config/win/$current_cpu"
} else if (is_msan) {
# MemorySanitizer can't handle assembly, https://crbug.com/928357.
enable_x64_asm = false
assert(current_cpu == "x64" && is_linux, "Only Linux X64 MSAN is supported")
platform_config_root = "config/linux-noasm/$current_cpu"
} else {
# Linux configuration files seem to work on Mac, so just reuse them.
enable_x64_asm = true
platform_config_root = "config/linux/$current_cpu"
}
config("dav1d_config") {
include_dirs = [
"version",
"libdav1d",
"libdav1d/include",
"libdav1d/include/dav1d",
platform_config_root,
]
# Disable internal dav1d logs in the official build to save storage.
if (is_official_build) {
defines = [ "CONFIG_LOG=0" ]
} else {
defines = [ "CONFIG_LOG=1" ]
}
# Don't let dav1d export any symbols. Otherwise the verify_order step on macOS
# can fail since these exports end up in the final Chromium binary.
defines += [ "DAV1D_API=" ]
}
dav1d_copts = [
"-D_FILE_OFFSET_BITS=64",
"-D_POSIX_C_SOURCE=200112L",
]
if (!is_win) {
dav1d_copts += [ "-std=c99" ]
if (current_cpu == "x64") {
dav1d_copts += [ "-mstack-alignment=32" ]
} else if (current_cpu == "x86") {
dav1d_copts += [ "-mstack-alignment=16" ]
}
}
if (enable_x64_asm && (current_cpu == "x86" || current_cpu == "x64")) {
nasm_assemble("dav1d_asm") {
sources = x86_asm_sources
inputs = [
"libdav1d/src/ext/x86/x86inc.asm",
"$platform_config_root/config.asm",
]
include_dirs = [
"libdav1d/src/",
platform_config_root,
]
nasm_flags = [
"-P",
rebase_path("$platform_config_root/config.asm", root_build_dir),
]
# Necessary to ensure macOS symbols end up with a _ prefix.
if (is_mac) {
defines = [ "PREFIX" ]
}
}
}
static_library("dav1d_entrypoints") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":dav1d_config",
]
sources = entry_point_sources
# TODO(dalecurtis): Fix arm compiler options...
cflags = dav1d_copts
if (!is_win) {
cflags += [ "-mstackrealign" ]
} else {
sources += [ "libdav1d/src/win32/thread.c" ]
}
}
static_library("dav1d_8bit") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":dav1d_config",
]
sources = template_sources
if (current_cpu == "x86" || current_cpu == "x64") {
sources += x86_template_sources
} else if (current_cpu == "arm") {
sources += arm_template_sources + arm32_asm_sources
} else if (current_cpu == "arm64") {
sources += arm_template_sources + arm64_asm_sources
}
# TODO(dalecurtis): Fix arm compiler options...
cflags = dav1d_copts
cflags += [ "-DBITDEPTH=8" ]
}
static_library("dav1d_10bit") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":dav1d_config",
]
sources = template_sources
if (current_cpu == "x86" || current_cpu == "x64") {
sources += x86_template_sources
} else if (current_cpu == "arm") {
sources += arm_template_sources + arm32_asm_sources
} else if (current_cpu == "arm64") {
sources += arm_template_sources + arm64_asm_sources
}
# TODO(dalecurtis): Fix arm compiler options...
cflags = dav1d_copts
cflags += [ "-DBITDEPTH=16" ]
}
if (current_cpu == "x86" || current_cpu == "x64") {
static_library("dav1d_x86") {
sources = [
"libdav1d/src/x86/cpu.c",
"libdav1d/src/x86/cpu.h",
]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":dav1d_config",
]
cflags = dav1d_copts
}
} else if (current_cpu == "arm" || current_cpu == "arm64") {
static_library("dav1d_arm") {
sources = [
"libdav1d/src/arm/cpu.c",
"libdav1d/src/arm/cpu.h",
]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":dav1d_config",
]
# TODO(dalecurtis): Fix arm compiler options...
cflags = dav1d_copts
}
}
static_library("dav1d") {
sources = c_sources
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":dav1d_config",
]
cflags = dav1d_copts
deps = [
":dav1d_10bit",
":dav1d_8bit",
":dav1d_entrypoints",
]
if (current_cpu == "x86" || current_cpu == "x64") {
deps += [ ":dav1d_x86" ]
if (enable_x64_asm) {
deps += [ ":dav1d_asm" ]
}
} else if (current_cpu == "arm" || current_cpu == "arm64") {
deps += [ ":dav1d_arm" ]
}
}
Copyright © 2018, VideoLAN and dav1d authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# COMPONENT: Internals>Media>Codecs
file://media/OWNERS
Name: dav1d is an AV1 decoder :)
Short Name: dav1d
URL: https://code.videolan.org/videolan/dav1d
Version: f1b756ef5bdc0bb759b2b140f15362fec024c1ff
License: 2-Clause BSD
License File: LICENSE, copied from: libdav1d/COPYING
Security Critical: yes
Source: https://code.videolan.org/videolan/dav1d
--[ DESCRIPTION ] ------------------
This contains the source to the dav1d video decoder; used for AV1 decoding in
Chromium.
--[ UPDATING ] ------------------
To update run "git pull" within the libdav1d directory to sync your local copy
of the checkout to upstream. Then you need to update the configuration files
and source listing.
First have clang (//third_party/llvm-build/Release+Asserts/bin), clang-cl
(https://chromium.googlesource.com/chromium/src/+/lkgr/docs/win_cross.md),
meson (https://github.com/mesonbuild/meson/releases), and wine
(https://www.winehq.org/) in your path. Then you can run ./generate_configs.py
Next you should update the dav1d_generated.gni file, to that run the
./generate_sources.py command.
Hopefully all that works and then you can roll DEPS to the new revision with
all the updated configuration files. If not, you'll need to debug the bots :(
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#pragma once
#define ARCH_AARCH64 0
#define ARCH_ARM 0
#define ARCH_X86 1
#define ARCH_X86_32 0
#define ARCH_X86_64 1
#define CONFIG_16BPC 1
#define CONFIG_8BPC 1
/* #define CONFIG_LOG 1 -- logging is controlled by the Chrome build */
#define HAVE_ASM 0
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_UNISTD_H 1
#define STACK_ALIGNMENT 32
; Autogenerated by the Meson build system.
; Do not edit, your changes will be lost.
%define ARCH_X86_32 0
%define ARCH_X86_64 1
%define STACK_ALIGNMENT 32
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#pragma once
#define ARCH_AARCH64 0
#define ARCH_ARM 0
#define ARCH_X86 1
#define ARCH_X86_32 0
#define ARCH_X86_64 1
#define CONFIG_16BPC 1
#define CONFIG_8BPC 1
/* #define CONFIG_LOG 1 -- logging is controlled by the Chrome build */
#define HAVE_ASM 1
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_UNISTD_H 1
#define STACK_ALIGNMENT 32
; Autogenerated by the Meson build system.
; Do not edit, your changes will be lost.
%define ARCH_X86_32 1
%define ARCH_X86_64 0
%define PIC 1
%define STACK_ALIGNMENT 16
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#pragma once
#define ARCH_AARCH64 0
#define ARCH_ARM 0
#define ARCH_X86 1
#define ARCH_X86_32 1
#define ARCH_X86_64 0
#define CONFIG_16BPC 1
#define CONFIG_8BPC 1
/* #define CONFIG_LOG 1 -- logging is controlled by the Chrome build */
#define HAVE_ASM 1
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_UNISTD_H 1
#define STACK_ALIGNMENT 16
; Autogenerated by the Meson build system.
; Do not edit, your changes will be lost.
%define ARCH_X86_32 0
%define ARCH_X86_64 1
%define STACK_ALIGNMENT 16
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#pragma once
#define ARCH_AARCH64 0
#define ARCH_ARM 0
#define ARCH_X86 1
#define ARCH_X86_32 0
#define ARCH_X86_64 1
#define CONFIG_16BPC 1
#define CONFIG_8BPC 1
/* #define CONFIG_LOG 1 -- logging is controlled by the Chrome build */
#define HAVE_ALIGNED_MALLOC 1
#define HAVE_ASM 1
#define STACK_ALIGNMENT 16
; Autogenerated by the Meson build system.
; Do not edit, your changes will be lost.
%define ARCH_X86_32 1
%define ARCH_X86_64 0
%define PIC 1
%define PREFIX 1
%define STACK_ALIGNMENT 4
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#pragma once
#define ARCH_AARCH64 0
#define ARCH_ARM 0
#define ARCH_X86 1
#define ARCH_X86_32 1
#define ARCH_X86_64 0
#define CONFIG_16BPC 1
#define CONFIG_8BPC 1
/* #define CONFIG_LOG 1 -- logging is controlled by the Chrome build */
#define HAVE_ALIGNED_MALLOC 1
#define HAVE_ASM 1
#define PREFIX 1
#define STACK_ALIGNMENT 4
[binaries]
c = 'clang'
ar = 'llvm-ar'
[properties]
c_args = ['-m32']
[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
[binaries]
c = 'clang-cl'
ar = 'llvm-ar'
exe_wrapper = 'wine'
[properties]
needs_exe_wrapper = true
c_args = ['-m32', '-fuse-ld=lld',]
[host_machine]
system = 'win'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
c_winlibs = []
[binaries]
c = 'clang-cl'
ar = 'llvm-ar'
exe_wrapper = 'wine'
[properties]
needs_exe_wrapper = true
c_args = ['-fuse-ld=lld',]
[host_machine]
system = 'win'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
cpp_winlibs = ['adsg']
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# NOTE: this file is autogenerated by dav1d/generate_sources.py - DO NOT EDIT.
x86_asm_sources = [
"libdav1d/src/x86/cdef.asm",
"libdav1d/src/x86/cpuid.asm",
"libdav1d/src/x86/ipred.asm",
"libdav1d/src/x86/ipred_ssse3.asm",
"libdav1d/src/x86/itx.asm",
"libdav1d/src/x86/itx_ssse3.asm",
"libdav1d/src/x86/loopfilter.asm",
"libdav1d/src/x86/looprestoration.asm",
"libdav1d/src/x86/mc.asm",
"libdav1d/src/x86/mc_ssse3.asm",
]
x86_template_sources = [
"libdav1d/src/x86/cdef_init_tmpl.c",
"libdav1d/src/x86/ipred_init_tmpl.c",
"libdav1d/src/x86/itx_init_tmpl.c",
"libdav1d/src/x86/loopfilter_init_tmpl.c",
"libdav1d/src/x86/looprestoration_init_tmpl.c",
"libdav1d/src/x86/mc_init_tmpl.c",
]
arm32_asm_sources = [
"libdav1d/src/arm/32/mc.S",
"libdav1d/src/arm/32/util.S",
]
arm64_asm_sources = [
"libdav1d/src/arm/64/looprestoration.S",
"libdav1d/src/arm/64/mc.S",
"libdav1d/src/arm/64/util.S",
]
arm_template_sources = [
"libdav1d/src/arm/looprestoration_init_tmpl.c",
"libdav1d/src/arm/mc_init_tmpl.c",
]
template_sources = [
"libdav1d/src/cdef_apply_tmpl.c",
"libdav1d/src/cdef_tmpl.c",
"libdav1d/src/film_grain_tmpl.c",
"libdav1d/src/ipred_prepare_tmpl.c",
"libdav1d/src/ipred_tmpl.c",
"libdav1d/src/itx_tmpl.c",
"libdav1d/src/lf_apply_tmpl.c",
"libdav1d/src/loopfilter_tmpl.c",
"libdav1d/src/looprestoration_tmpl.c",
"libdav1d/src/lr_apply_tmpl.c",
"libdav1d/src/mc_tmpl.c",
"libdav1d/src/recon_tmpl.c",
]
c_sources = [
"libdav1d/src/cdef.h",
"libdav1d/src/cdef_apply.h",
"libdav1d/src/cdf.c",
"libdav1d/src/cdf.h",
"libdav1d/src/cpu.c",
"libdav1d/src/cpu.h",
"libdav1d/src/ctx.h",
"libdav1d/src/data.c",
"libdav1d/src/data.h",
"libdav1d/src/decode.c",
"libdav1d/src/decode.h",
"libdav1d/src/dequant_tables.c",
"libdav1d/src/dequant_tables.h",
"libdav1d/src/env.h",
"libdav1d/src/film_grain.h",
"libdav1d/src/getbits.c",
"libdav1d/src/getbits.h",
"libdav1d/src/internal.h",
"libdav1d/src/intra_edge.c",
"libdav1d/src/intra_edge.h",
"libdav1d/src/ipred.h",
"libdav1d/src/ipred_prepare.h",
"libdav1d/src/itx.h",
"libdav1d/src/levels.h",
"libdav1d/src/lf_apply.h",
"libdav1d/src/lf_mask.c",
"libdav1d/src/lf_mask.h",
"libdav1d/src/log.c",
"libdav1d/src/log.h",
"libdav1d/src/loopfilter.h",
"libdav1d/src/looprestoration.h",
"libdav1d/src/lr_apply.h",
"libdav1d/src/mc.h",
"libdav1d/src/msac.c",
"libdav1d/src/msac.h",
"libdav1d/src/obu.c",
"libdav1d/src/obu.h",
"libdav1d/src/picture.c",
"libdav1d/src/picture.h",
"libdav1d/src/qm.c",
"libdav1d/src/qm.h",
"libdav1d/src/recon.h",
"libdav1d/src/ref.c",
"libdav1d/src/ref.h",
"libdav1d/src/ref_mvs.c",
"libdav1d/src/ref_mvs.h",
"libdav1d/src/scan.c",
"libdav1d/src/scan.h",
"libdav1d/src/tables.c",
"libdav1d/src/tables.h",
"libdav1d/src/thread.h",
"libdav1d/src/thread_data.h",
"libdav1d/src/warpmv.c",
"libdav1d/src/warpmv.h",
"libdav1d/src/wedge.c",
"libdav1d/src/wedge.h",
]
entry_point_sources = [
"libdav1d/src/lib.c",
"libdav1d/src/thread_task.c",
"libdav1d/src/thread_task.h",
]
#!/usr/bin/python
#
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Creates config files for building dav1d."""
from __future__ import print_function
import os
import re
import shutil
import subprocess
import sys
import tempfile
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
CHROMIUM_ROOT_DIR = os.path.abspath(os.path.join(BASE_DIR, '..', '..'))
sys.path.append(os.path.join(CHROMIUM_ROOT_DIR, 'build'))
import gn_helpers
MESON = ['meson.py']
DEFAULT_BUILD_ARGS = [
'-Dbuild_tools=false', '-Dbuild_tests=false', '--buildtype', 'release'
]
WINDOWS_BUILD_ARGS = ['-Dc_winlibs=']
def PrintAndCheckCall(argv, *args, **kwargs):
print('\n-------------------------------------------------\nRunning %s' %
' '.join(argv))
c = subprocess.check_call(argv, *args, **kwargs)
def RewriteFile(path, search_replace):
with open(path) as f:
contents = f.read()
with open(path, 'w') as f:
for search, replace in search_replace:
contents = re.sub(search, replace, contents)
f.write(contents)
def SetupWindowsCrossCompileToolchain(target_arch):
# First retrieve various MSVC and Windows SDK paths.
output = subprocess.check_output([
os.path.join(CHROMIUM_ROOT_DIR, 'build', 'vs_toolchain.py'),
'get_toolchain_dir'
])
# Turn this into a dictionary.
win_dirs = gn_helpers.FromGNArgs(output)
# Use those paths with a second script which will tell us the proper include
# and lib paths to specify for cflags and ldflags respectively.
output = subprocess.check_output([
'python',
os.path.join(CHROMIUM_ROOT_DIR, 'build', 'toolchain', 'win',
'setup_toolchain.py'), win_dirs['vs_path'],
win_dirs['sdk_path'], win_dirs['runtime_dirs'], 'win', target_arch, 'none'
])
flags = gn_helpers.FromGNArgs(output)
cwd = os.getcwd()
target_env = os.environ
include_paths = []
for cflag in flags['include_flags_imsvc'].split(' '):
# Apparently setup_toolchain prefers relative include paths, which
# may work for chrome, but it does not work for ffmpeg, so let's make
# them asbolute again.
include_path = cflag.strip('"')
if include_path.startswith('-imsvc'):
include_path = os.path.abspath(os.path.join(cwd, include_path[6:]))
include_paths.append(include_path)
# TODO(dalecurtis): Why isn't the ucrt path printed?
flags['vc_lib_ucrt_path'] = flags['vc_lib_um_path'].replace('/um/', '/ucrt/')
# Unlike the cflags, the lib include paths are each in a separate variable.
lib_paths = []
for k in flags:
# libpath_flags is like cflags. Since it is also redundant, skip it.
if 'lib' in k and k != 'libpath_flags':
lib_paths.append(flags[k])
target_env = os.environ
target_env['INCLUDE'] = ';'.join(include_paths)
target_env['LIB'] = ';'.join(lib_paths)
return target_env
def CopyConfigsAndCleanup(config_dir, dest_dir):
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
shutil.copy(os.path.join(config_dir, 'config.h'), dest_dir)
# The .asm file will not be present for all configurations.
asm_file = os.path.join(config_dir, 'config.asm')
if os.path.exists(asm_file):
shutil.copy(os.path.join(config_dir, 'config.asm'), dest_dir)
shutil.rmtree(config_dir)
def GenerateConfig(config_dir, env, special_args=[]):
temp_dir = tempfile.mkdtemp()
PrintAndCheckCall(
MESON + DEFAULT_BUILD_ARGS + special_args + [temp_dir],
cwd='libdav1d',
env=env)
RewriteFile(
os.path.join(temp_dir, 'config.h'),
[(r'(#define CONFIG_LOG .*)',
r'/* \1 -- logging is controlled by the Chrome build */')])
CopyConfigsAndCleanup(temp_dir, config_dir)
def main():
linux_env = os.environ
linux_env['CC'] = 'clang'
GenerateConfig('config/linux/x64', linux_env)
GenerateConfig('config/linux/x86', linux_env,
['--cross-file', '../crossfiles/linux32.crossfile'])
GenerateConfig('config/linux-noasm/x64', linux_env, ["-Dbuild_asm=false"])
win_x86_env = SetupWindowsCrossCompileToolchain('x86')
GenerateConfig(
'config/win/x86', win_x86_env,
['--cross-file', '../crossfiles/win32.crossfile'] + WINDOWS_BUILD_ARGS)
win_x64_env = SetupWindowsCrossCompileToolchain('x64')
GenerateConfig(
'config/win/x64', win_x64_env,
['--cross-file', '../crossfiles/win64.crossfile'] + WINDOWS_BUILD_ARGS)
if __name__ == '__main__':
main()
#!/usr/bin/python
#
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Creates a GN include file for building dav1d from source."""
__author__ = "dalecurtis@chromium.org (Dale Curtis)"
import datetime
import glob
COPYRIGHT = """# Copyright %d The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# NOTE: this file is autogenerated by dav1d/generate_sources.py - DO NOT EDIT.
""" % (
datetime.datetime.now().year)
# .c files which don't need -DBIT_DEPTH specified for each compilation.
DAV1D_ENTRY_POINT_SOURCES = [
"libdav1d/src/lib.c",
"libdav1d/src/thread_task.c",
"libdav1d/src/thread_task.h",
]
# .c files which are included by other .c files and shouldn't be listed.
DAV1D_C_FILE_INCLUDES = ["libdav1d/src/itx_1d.c"]
def WriteArray(fd, var_name, array, filter_list=[], last_entry=False):
if len(array) == 0:
fd.write("var_name = []\n")
return
fd.write("%s = [\n" % var_name)
for item in sorted(array):
if item not in filter_list:
fd.write(" \"%s\",\n" % item)
fd.write("]\n")
if not last_entry:
fd.write("\n")
def WriteGn(fd):
fd.write(COPYRIGHT)
WriteArray(fd, "x86_asm_sources", glob.glob("libdav1d/src/x86/*.asm"))
WriteArray(fd, "x86_template_sources", glob.glob("libdav1d/src/x86/*_tmpl.c"))
# TODO(dalecurtis): May want to exclude "util.S" here.
WriteArray(fd, "arm32_asm_sources", glob.glob("libdav1d/src/arm/32/*.S"))
WriteArray(fd, "arm64_asm_sources", glob.glob("libdav1d/src/arm/64/*.S"))
WriteArray(fd, "arm_template_sources", glob.glob("libdav1d/src/arm/*_tmpl.c"))
template_sources = glob.glob("libdav1d/src/*_tmpl.c")
WriteArray(fd, "template_sources", template_sources)
# Generate list of sources which need to be compiled multiple times with the
# correct -DBIT_DEPTH=8|10 option specified each time.
WriteArray(
fd, "c_sources", glob.glob("libdav1d/src/*.[c|h]"),
DAV1D_ENTRY_POINT_SOURCES + DAV1D_C_FILE_INCLUDES + template_sources)
WriteArray(
fd, "entry_point_sources", DAV1D_ENTRY_POINT_SOURCES, last_entry=True)
def main():
with open("dav1d_generated.gni", "w") as fd:
WriteGn(fd)
if __name__ == "__main__":
main()
libdav1d @ f1b756ef
Subproject commit f1b756ef5bdc0bb759b2b140f15362fec024c1ff
#define DAV1D_VERSION "Chromium"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment