Commit 54e8ebb0 authored by Xiaohan Wang's avatar Xiaohan Wang Committed by Commit Bot

media: Remove PpapiCdmAdapter and friends

So long!

Bug: 772160
Change-Id: I03b8e919de477bf55d35d14ecde97b0e2524b34b
Reviewed-on: https://chromium-review.googlesource.com/971826Reviewed-by: default avatarJohn Rummell <jrummell@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#544760}
parent ed224aa6
...@@ -29,7 +29,7 @@ namespace media { ...@@ -29,7 +29,7 @@ namespace media {
// indicates the type of CdmPromiseTemplate. CdmPromiseTemplate<T> adds the // indicates the type of CdmPromiseTemplate. CdmPromiseTemplate<T> adds the
// resolve(T) method that is dependent on the type of promise. This base class // resolve(T) method that is dependent on the type of promise. This base class
// is specified so that the promises can be easily saved before passing across // is specified so that the promises can be easily saved before passing across
// the pepper interface. // IPC.
class MEDIA_EXPORT CdmPromise { class MEDIA_EXPORT CdmPromise {
public: public:
enum class Exception { enum class Exception {
......
...@@ -4,14 +4,7 @@ ...@@ -4,14 +4,7 @@
#include "media/cdm/cdm_helpers.h" #include "media/cdm/cdm_helpers.h"
#if defined(USE_PPAPI_CDM_ADAPTER)
// When building the ppapi adapter do not include any non-trivial base/ headers.
#include "ppapi/cpp/logging.h" // nogncheck
#define PLATFORM_DCHECK PP_DCHECK
#else
#include "base/logging.h" #include "base/logging.h"
#define PLATFORM_DCHECK DCHECK
#endif
namespace media { namespace media {
...@@ -77,22 +70,22 @@ cdm::Buffer* VideoFrameImpl::FrameBuffer() { ...@@ -77,22 +70,22 @@ cdm::Buffer* VideoFrameImpl::FrameBuffer() {
void VideoFrameImpl::SetPlaneOffset(cdm::VideoFrame::VideoPlane plane, void VideoFrameImpl::SetPlaneOffset(cdm::VideoFrame::VideoPlane plane,
uint32_t offset) { uint32_t offset) {
PLATFORM_DCHECK(plane < kMaxPlanes); DCHECK(plane < kMaxPlanes);
plane_offsets_[plane] = offset; plane_offsets_[plane] = offset;
} }
uint32_t VideoFrameImpl::PlaneOffset(VideoPlane plane) { uint32_t VideoFrameImpl::PlaneOffset(VideoPlane plane) {
PLATFORM_DCHECK(plane < kMaxPlanes); DCHECK(plane < kMaxPlanes);
return plane_offsets_[plane]; return plane_offsets_[plane];
} }
void VideoFrameImpl::SetStride(VideoPlane plane, uint32_t stride) { void VideoFrameImpl::SetStride(VideoPlane plane, uint32_t stride) {
PLATFORM_DCHECK(plane < kMaxPlanes); DCHECK(plane < kMaxPlanes);
strides_[plane] = stride; strides_[plane] = stride;
} }
uint32_t VideoFrameImpl::Stride(VideoPlane plane) { uint32_t VideoFrameImpl::Stride(VideoPlane plane) {
PLATFORM_DCHECK(plane < kMaxPlanes); DCHECK(plane < kMaxPlanes);
return strides_[plane]; return strides_[plane];
} }
......
...@@ -9,16 +9,10 @@ ...@@ -9,16 +9,10 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "media/cdm/api/content_decryption_module.h"
#if !defined(USE_PPAPI_CDM_ADAPTER)
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "media/base/media_export.h" // nogncheck #include "media/base/media_export.h"
#include "media/cdm/api/content_decryption_module.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#define MEDIA_CDM_EXPORT MEDIA_EXPORT
#else
#define MEDIA_CDM_EXPORT
#endif
namespace media { namespace media {
...@@ -42,7 +36,7 @@ class DecryptedBlockImpl : public cdm::DecryptedBlock { ...@@ -42,7 +36,7 @@ class DecryptedBlockImpl : public cdm::DecryptedBlock {
DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl); DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl);
}; };
class MEDIA_CDM_EXPORT VideoFrameImpl : public cdm::VideoFrame { class MEDIA_EXPORT VideoFrameImpl : public cdm::VideoFrame {
public: public:
VideoFrameImpl(); VideoFrameImpl();
~VideoFrameImpl() override; ~VideoFrameImpl() override;
...@@ -61,7 +55,6 @@ class MEDIA_CDM_EXPORT VideoFrameImpl : public cdm::VideoFrame { ...@@ -61,7 +55,6 @@ class MEDIA_CDM_EXPORT VideoFrameImpl : public cdm::VideoFrame {
void SetTimestamp(int64_t timestamp) final; void SetTimestamp(int64_t timestamp) final;
int64_t Timestamp() const final; int64_t Timestamp() const final;
#if !defined(USE_PPAPI_CDM_ADAPTER)
// Create a media::VideoFrame based on the data contained in this object. // Create a media::VideoFrame based on the data contained in this object.
// |natural_size| is the visible portion of the video frame, and is // |natural_size| is the visible portion of the video frame, and is
// provided separately as it comes from the configuration, not the CDM. // provided separately as it comes from the configuration, not the CDM.
...@@ -73,7 +66,6 @@ class MEDIA_CDM_EXPORT VideoFrameImpl : public cdm::VideoFrame { ...@@ -73,7 +66,6 @@ class MEDIA_CDM_EXPORT VideoFrameImpl : public cdm::VideoFrame {
// - |frame_buffer_| will be NULL (now owned by returned media::VideoFrame). // - |frame_buffer_| will be NULL (now owned by returned media::VideoFrame).
virtual scoped_refptr<media::VideoFrame> TransformToVideoFrame( virtual scoped_refptr<media::VideoFrame> TransformToVideoFrame(
gfx::Size natural_size) = 0; gfx::Size natural_size) = 0;
#endif
protected: protected:
// The video buffer format. // The video buffer format.
......
...@@ -10,32 +10,19 @@ ...@@ -10,32 +10,19 @@
#include <string> #include <string>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "media/base/media_switches.h"
#include "media/cdm/api/content_decryption_module.h" #include "media/cdm/api/content_decryption_module.h"
#include "media/cdm/supported_cdm_versions.h" #include "media/cdm/supported_cdm_versions.h"
#if defined(USE_PPAPI_CDM_ADAPTER)
// When building the ppapi adapter do not include any non-trivial base/ headers.
#include "ppapi/cpp/logging.h" // nogncheck
#define PLATFORM_DCHECK PP_DCHECK
#else
#include "base/feature_list.h"
#include "base/logging.h"
#include "media/base/media_switches.h" // nogncheck
#define PLATFORM_DCHECK DCHECK
#endif
namespace media { namespace media {
namespace { namespace {
bool IsExperimentalCdmInterfaceSupported() { bool IsExperimentalCdmInterfaceSupported() {
#if defined(USE_PPAPI_CDM_ADAPTER)
// No new CDM interface will be supported using pepper CDM.
return false;
#else
return base::FeatureList::IsEnabled(media::kSupportExperimentalCdmInterface); return base::FeatureList::IsEnabled(media::kSupportExperimentalCdmInterface);
#endif
} }
bool IsEncryptionSchemeSupportedByLegacyCdms( bool IsEncryptionSchemeSupportedByLegacyCdms(
...@@ -322,7 +309,7 @@ class CdmWrapperImpl : public CdmWrapper { ...@@ -322,7 +309,7 @@ class CdmWrapperImpl : public CdmWrapper {
} }
private: private:
CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) { PLATFORM_DCHECK(cdm_); } CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) { DCHECK(cdm_); }
CdmInterface* cdm_; CdmInterface* cdm_;
...@@ -505,14 +492,13 @@ CdmWrapper* CdmWrapper::Create(CreateCdmFunc create_cdm_func, ...@@ -505,14 +492,13 @@ CdmWrapper* CdmWrapper::Create(CreateCdmFunc create_cdm_func,
// TODO(xhwang): Static assert these at compile time. // TODO(xhwang): Static assert these at compile time.
const int kMinVersion = cdm::ContentDecryptionModule_8::kVersion; const int kMinVersion = cdm::ContentDecryptionModule_8::kVersion;
const int kMaxVersion = cdm::ContentDecryptionModule_10::kVersion; const int kMaxVersion = cdm::ContentDecryptionModule_10::kVersion;
PLATFORM_DCHECK(!IsSupportedCdmInterfaceVersion(kMinVersion - 1)); DCHECK(!IsSupportedCdmInterfaceVersion(kMinVersion - 1));
for (int version = kMinVersion; version <= kMaxVersion; ++version) for (int version = kMinVersion; version <= kMaxVersion; ++version)
PLATFORM_DCHECK(IsSupportedCdmInterfaceVersion(version)); DCHECK(IsSupportedCdmInterfaceVersion(version));
PLATFORM_DCHECK(!IsSupportedCdmInterfaceVersion(kMaxVersion + 1)); DCHECK(!IsSupportedCdmInterfaceVersion(kMaxVersion + 1));
// Try to create the CDM using the latest CDM interface version. // Try to create the CDM using the latest CDM interface version.
// This is only attempted if requested. For pepper plugins, this is done // This is only attempted if requested.
// at compile time. For mojo, it is done using a media feature setting.
CdmWrapper* cdm_wrapper = nullptr; CdmWrapper* cdm_wrapper = nullptr;
// TODO(xhwang): Check whether we can use static loops to simplify this code. // TODO(xhwang): Check whether we can use static loops to simplify this code.
...@@ -551,6 +537,4 @@ static_assert(cdm::ContentDecryptionModule::kVersion == ...@@ -551,6 +537,4 @@ static_assert(cdm::ContentDecryptionModule::kVersion ==
} // namespace media } // namespace media
#undef PLATFORM_DCHECK
#endif // MEDIA_CDM_CDM_WRAPPER_H_ #endif // MEDIA_CDM_CDM_WRAPPER_H_
# Since media/ does not depend on anything in media/cdm/library_cdm/, these
# extra dependencies are okay.
include_rules = [
"+ppapi/c",
"+ppapi/cpp",
"+ppapi/utility",
]
This diff is collapsed.
// Copyright 2013 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_CDM_LIBRARY_CDM_CDM_FILE_IO_IMPL_H_
#define MEDIA_CDM_LIBRARY_CDM_CDM_FILE_IO_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <string>
#include <vector>
#include "base/macros.h"
#include "media/cdm/api/content_decryption_module.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/private/isolated_file_system_private.h"
#include "ppapi/utility/completion_callback_factory.h"
namespace media {
// Due to PPAPI limitations, all functions must be called on the main thread.
//
// Implementation notes about states:
// 1, When a method is called in an invalid state (e.g. Read() before Open() is
// called, Write() before Open() finishes or Open() after Open()), kError
// will be returned. The state of |this| will not change.
// 2, When the file is opened by another CDM instance, or when we call Read()/
// Write() during a pending Read()/Write(), kInUse will be returned. The
// state of |this| will not change.
// 3, When a pepper operation failed (either synchronously or asynchronously),
// kError will be returned. The state of |this| will be set to ERROR.
// 4. Any operation in ERROR state will end up with kError.
class CdmFileIOImpl : public cdm::FileIO {
public:
// A class that helps release |file_lock_map_|.
// There should be only one instance of ResourceTracker in a process. Also,
// ResourceTracker should outlive all CdmFileIOImpl instances.
class ResourceTracker {
public:
ResourceTracker();
~ResourceTracker();
private:
DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
};
// After the first successful file read, call |first_file_read_cb| to report
// the file size. |first_file_read_cb| takes one parameter: the file size in
// bytes.
CdmFileIOImpl(cdm::FileIOClient* client,
PP_Instance pp_instance,
const pp::CompletionCallback& first_file_read_cb);
// cdm::FileIO implementation.
void Open(const char* file_name, uint32_t file_name_size) override;
void Read() override;
void Write(const uint8_t* data, uint32_t data_size) override;
void Close() override;
private:
// TODO(xhwang): Introduce more detailed states for UMA logging if needed.
enum State {
STATE_UNOPENED,
STATE_OPENING_FILE_SYSTEM,
STATE_FILE_SYSTEM_OPENED,
STATE_READING,
STATE_WRITING,
STATE_CLOSED,
STATE_ERROR
};
enum ErrorType {
OPEN_WHILE_IN_USE,
READ_WHILE_IN_USE,
WRITE_WHILE_IN_USE,
OPEN_ERROR,
READ_ERROR,
WRITE_ERROR
};
// Always use Close() to release |this| object.
~CdmFileIOImpl() override;
// |file_id_| -> |is_file_lock_acquired_| map.
// Design detail:
// - We never erase an entry from this map.
// - Pros: When the same file is read or written repeatedly, we don't need to
// insert/erase the entry repeatedly, which is expensive.
// - Cons: If there are a lot of one-off files used, this map will be
// unnecessarily large. But this should be a rare case.
// - Ideally we could use unordered_map for this. But unordered_set is only
// available in C++11.
typedef std::map<std::string, bool> FileLockMap;
// File lock map shared by all CdmFileIOImpl objects to prevent read/write
// race. A CdmFileIOImpl object tries to acquire a lock before opening a
// file. If the file open failed, the lock is released. Otherwise, the
// CdmFileIOImpl object holds the lock until Close() is called.
// TODO(xhwang): Investigate the following cases and make sure we are good:
// - This assumes all CDM instances run in the same process for a given file
// system.
// - When multiple CDM instances are running in different profiles (e.g.
// normal/incognito window, multiple profiles), we may be overlocking.
static FileLockMap* file_lock_map_;
// Sets |file_id_|. Returns false if |file_id_| cannot be set (e.g. origin URL
// cannot be fetched).
bool SetFileID();
// Acquires the file lock. Returns true if the lock is successfully acquired.
// After the lock is acquired, other cdm::FileIO objects in the same process
// and in the same origin will get kInUse when trying to open the same file.
bool AcquireFileLock();
// Releases the file lock so that the file can be opened by other cdm::FileIO
// objects.
void ReleaseFileLock();
// Helper functions for Open().
void OpenFileSystem();
void OnFileSystemOpened(int32_t result, pp::FileSystem file_system);
// Helper functions for Read().
void OpenFileForRead();
void OnFileOpenedForRead(int32_t result);
void ReadFile();
void OnFileRead(int32_t bytes_read);
// Helper functions for Write(). We always write data to a temporary file,
// then rename the temporary file to the target file. This can prevent data
// corruption if |this| is Close()'ed while waiting for writing to complete.
// However, if Close() is called after OpenTempFileForWrite() but before
// RenameTempFile(), we may still end up with an empty, partially written or
// fully written temporary file in the file system. This temporary file will
// be truncated next time OpenTempFileForWrite() is called.
void OpenTempFileForWrite();
void OnTempFileOpenedForWrite(int32_t result);
void WriteTempFile();
void OnTempFileWritten(int32_t bytes_written);
// Note: pp::FileRef::Rename() actually does a "move": if the target file
// exists, Rename() will succeed and the target file will be overwritten.
// See PepperInternalFileRefBackend::Rename() for implementation detail.
void RenameTempFile();
void OnTempFileRenamed(int32_t result);
// Reset |this| to a clean state.
void Reset();
// For real open/read/write errors, Reset() and set the |state_| to ERROR.
// Calls client_->OnXxxxComplete with kError or kInUse asynchronously. In some
// cases we could actually call them synchronously, but since these errors
// shouldn't happen in normal cases, we are not optimizing such cases.
void OnError(ErrorType error_type);
// Callback to notify client of error asynchronously.
void NotifyClientOfError(int32_t result, ErrorType error_type);
State state_;
// Non-owning pointer.
cdm::FileIOClient* const client_;
const pp::InstanceHandle pp_instance_handle_;
// Format: /<requested_file_name>
std::string file_name_;
// A string ID that uniquely identifies a file in the user's profile.
// It consists of the origin of the document URL (including scheme, host and
// port, delimited by colons) and the |file_name_|.
// For example: http:example.com:8080/foo_file.txt
std::string file_id_;
pp::IsolatedFileSystemPrivate isolated_file_system_;
pp::FileSystem file_system_;
// Shared between read and write. During read, |file_ref_| refers to the real
// file to read data from. During write, it refers to the temporary file to
// write data into.
pp::FileIO file_io_;
pp::FileRef file_ref_;
// A temporary buffer to hold (partial) data to write or the data that has
// been read. The size of |io_buffer_| is always "bytes to write" or "bytes to
// read". Use "char" instead of "unit8_t" because PPB_FileIO uses char* for
// binary data read and write.
std::vector<char> io_buffer_;
// Offset into the file for reading/writing data. When writing data to the
// file, this is also the offset to the |io_buffer_|.
size_t io_offset_;
// Buffer to hold all read data requested. This buffer is passed to |client_|
// when read completes.
std::vector<char> cumulative_read_buffer_;
bool first_file_read_reported_;
// Callback to report the file size in bytes after the first successful read.
pp::CompletionCallback first_file_read_cb_;
pp::CompletionCallbackFactory<CdmFileIOImpl> callback_factory_;
DISALLOW_COPY_AND_ASSIGN(CdmFileIOImpl);
};
} // namespace media
#endif // MEDIA_CDM_LIBRARY_CDM_CDM_FILE_IO_IMPL_H_
// Copyright 2013 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.
// Only compile this file in debug build. This gives us one more level of
// protection that if the linker tries to link in strings/symbols appended to
// "DLOG() <<" in release build (which it shouldn't), we'll get "undefined
// reference" errors.
#include "media/cdm/library_cdm/cdm_logging.h"
#include "build/build_config.h"
#if defined(OS_WIN)
#include <io.h>
#include <windows.h>
#elif defined(OS_MACOSX)
#include <mach-o/dyld.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#elif defined(OS_POSIX)
#include <sys/syscall.h>
#include <time.h>
#endif
#if defined(OS_POSIX)
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <iomanip>
#include <iostream>
namespace media {
#if !defined(NDEBUG)
namespace {
// Helper functions to wrap platform differences.
int32_t CurrentProcessId() {
#if defined(OS_WIN)
return GetCurrentProcessId();
#elif defined(OS_POSIX)
return getpid();
#endif
}
int32_t CurrentThreadId() {
// Pthreads doesn't have the concept of a thread ID, so we have to reach down
// into the kernel.
#if defined(OS_LINUX)
return syscall(__NR_gettid);
#elif defined(OS_ANDROID)
return gettid();
#elif defined(OS_SOLARIS)
return pthread_self();
#elif defined(OS_POSIX)
return reinterpret_cast<int64_t>(pthread_self());
#elif defined(OS_WIN)
return static_cast<int32_t>(::GetCurrentThreadId());
#endif
}
uint64_t TickCount() {
#if defined(OS_WIN)
return GetTickCount();
#elif defined(OS_MACOSX)
return mach_absolute_time();
#elif defined(OS_POSIX)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t absolute_micro = static_cast<int64_t>(ts.tv_sec) * 1000000 +
static_cast<int64_t>(ts.tv_nsec) / 1000;
return absolute_micro;
#endif
}
} // namespace
CdmLogMessage::CdmLogMessage(const char* file, int line) {
std::string filename(file);
size_t last_slash_pos = filename.find_last_of("\\/");
if (last_slash_pos != std::string::npos)
filename = filename.substr(last_slash_pos + 1);
stream_ << '[';
// Process and thread ID.
stream_ << CurrentProcessId() << ':';
stream_ << CurrentThreadId() << ':';
// Time and tick count.
time_t t = time(NULL);
struct tm local_time = {0};
#ifdef _MSC_VER
localtime_s(&local_time, &t);
#else
localtime_r(&t, &local_time);
#endif
struct tm* tm_time = &local_time;
stream_ << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon
<< std::setw(2) << tm_time->tm_mday << '/' << std::setw(2)
<< tm_time->tm_hour << std::setw(2) << tm_time->tm_min << std::setw(2)
<< tm_time->tm_sec << ':';
stream_ << TickCount() << ':';
// File name.
stream_ << filename << "(" << line << ")] ";
}
CdmLogMessage::~CdmLogMessage() {
// Use std::cout explicitly for the line break. This limits the use of this
// class only to the definition of DLOG() (which also uses std::cout).
//
// This appends "std::endl" after all other messages appended to DLOG(),
// which relies on the C++ standard ISO/IEC 14882:1998(E) $12.2.3:
// "Temporary objects are destroyed as the last step in evaluating the
// full-expression (1.9) that (lexically) contains the point where they were
// created."
std::cout << std::endl;
}
#endif // !defined(NDEBUG)
std::ostream& CdmLogStream::stream() {
return std::cout;
}
} // namespace media
// Copyright 2013 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.
// This file defines useful logging macros/methods for CDM adapter.
#ifndef MEDIA_CDM_LIBRARY_CDM_CDM_LOGGING_H_
#define MEDIA_CDM_LIBRARY_CDM_CDM_LOGGING_H_
#include <ostream>
#include <sstream>
#include <string>
namespace media {
namespace {
// The following classes/macros are adapted from base/logging.h.
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
class LogMessageVoidify {
public:
LogMessageVoidify() {}
// This has to be an operator with a precedence lower than << but
// higher than ?:
void operator&(std::ostream&) {}
};
} // namespace
// This class is used to avoid having to include <iostream> in this file.
class CdmLogStream {
public:
CdmLogStream() {}
// Retrieves the stream that we write to. This header cannot depend on
// <iostream> because that will add static initializers to all files that
// include this header. See https://crbug.com/94794.
std::ostream& stream();
};
// This class serves two purposes:
// (1) It adds common headers to the log message, e.g. timestamp, process ID.
// (2) It adds a line break at the end of the log message.
// This class is copied and modified from base/logging.* but is quite different
// in terms of how things work. This class is designed to work only with the
// CDM_DLOG() defined below and should not be used for other purposes.
class CdmLogMessage {
public:
CdmLogMessage(const char* file, int line);
~CdmLogMessage();
std::string message() { return stream_.str(); }
private:
std::ostringstream stream_;
};
// Helper macro which avoids evaluating the arguments to a stream if
// the condition doesn't hold.
#define CDM_LAZY_STREAM(stream, condition) \
!(condition) ? (void)0 : LogMessageVoidify() & (stream)
#if defined(NDEBUG)
// Logging is disabled for the release builds, theoretically the compiler should
// take care of removing the references to CdmLogMessage but it's not always the
// case when some specific optimizations are turned on (like PGO). Update the
// macro to make sure that we don't try to do any logging or to refer to
// CdmLogMessage in release.
#define CDM_DLOG_IS_ON() false
#define CDM_DLOG() CDM_LAZY_STREAM(CdmLogStream().stream(), CDM_DLOG_IS_ON())
#else
#define CDM_DLOG_IS_ON() true
#define CDM_DLOG() \
CDM_LAZY_STREAM(CdmLogStream().stream(), CDM_DLOG_IS_ON()) \
<< CdmLogMessage(__FILE__, __LINE__).message()
#endif
} // namespace media
#endif // MEDIA_CDM_LIBRARY_CDM_CDM_LOGGING_H_
// Copyright 2013 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.
//
// This is a copy of base/linked_ptr.h with CHECKS/DCHECKS replaced with
// PP_DCHECKs.
//
// A "smart" pointer type with reference tracking. Every pointer to a
// particular object is kept on a circular linked list. When the last pointer
// to an object is destroyed or reassigned, the object is deleted.
//
// Used properly, this deletes the object when the last reference goes away.
// There are several caveats:
// - Like all reference counting schemes, cycles lead to leaks.
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
// - Every time a pointer is released, the entire list of pointers to that
// object is traversed. This class is therefore NOT SUITABLE when there
// will often be more than two or three pointers to a particular object.
// - References are only tracked as long as linked_ptr<> objects are copied.
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
// will happen (double deletion).
//
// A good use of this class is storing object references in STL containers.
// You can safely put linked_ptr<> in a vector<>.
// Other uses may not be as good.
//
// Note: If you use an incomplete type with linked_ptr<>, the class
// *containing* linked_ptr<> must have a constructor and destructor (even
// if they do nothing!).
//
// Thread Safety:
// A linked_ptr is NOT thread safe. Copying a linked_ptr object is
// effectively a read-write operation.
//
// Alternative: to linked_ptr is shared_ptr, which
// - is also two pointers in size (8 bytes for 32 bit addresses)
// - is thread safe for copying and deletion
// - supports weak_ptrs
#ifndef MEDIA_CDM_LIBRARY_CDM_LINKED_PTR_H_
#define MEDIA_CDM_LIBRARY_CDM_LINKED_PTR_H_
#include "ppapi/cpp/logging.h"
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
// So, it needs to be possible for different types of linked_ptr to participate
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() { next_ = this; }
// Join an existing circle.
void join(linked_ptr_internal const* ptr) {
next_ = ptr->next_;
ptr->next_ = this;
}
// Leave whatever circle we're part of. Returns true iff we were the
// last member of the circle. Once this is done, you can join() another.
bool depart() {
if (next_ == this)
return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this)
p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U>
linked_ptr(linked_ptr<U> const& ptr) {
copy(&ptr);
}
linked_ptr(linked_ptr const& ptr) {
PP_DCHECK(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U>
linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
operator T*() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
// Release ownership of the pointed object and returns it.
// Sole ownership by this linked_ptr object is required.
T* release() {
bool last = link_.depart();
PP_DCHECK(last);
(void)last;
T* v = value_;
value_ = NULL;
return v;
}
bool operator==(const T* p) const { return value_ == p; }
bool operator!=(const T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart())
delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
template <typename U>
void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template <typename T>
inline bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
}
template <typename T>
inline bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
#endif // MEDIA_CDM_LIBRARY_CDM_LINKED_PTR_H_
This diff is collapsed.
# Copyright 2015 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("//build/config/compiler/compiler.gni")
# This template defines a CDM adapter target. Just use this as you would a
# normal target and everything should work correctly.
template("ppapi_cdm_adapter") {
if (is_mac || is_linux) {
_target_type = "loadable_module"
} else {
_target_type = "shared_library"
}
target(_target_type, target_name) {
# Don't filter sources list again.
set_sources_assignment_filter([])
cflags = []
sources = []
ldflags = []
libs = []
forward_variables_from(invoker, "*")
defines += [ "USE_PPAPI_CDM_ADAPTER" ]
deps += [
"//build/config:exe_and_shlib_deps",
"//media/cdm:cdm_api",
"//ppapi/cpp",
]
sources += [
"//media/cdm/cdm_helpers.cc",
"//media/cdm/cdm_helpers.h",
"//media/cdm/cdm_wrapper.h",
"//media/cdm/library_cdm/cdm_file_io_impl.cc",
"//media/cdm/library_cdm/cdm_file_io_impl.h",
"//media/cdm/library_cdm/cdm_logging.cc",
"//media/cdm/library_cdm/cdm_logging.h",
"//media/cdm/library_cdm/linked_ptr.h",
"//media/cdm/library_cdm/ppapi_cdm_adapter.cc",
"//media/cdm/library_cdm/ppapi_cdm_adapter.h",
"//media/cdm/library_cdm/ppapi_cdm_buffer.cc",
"//media/cdm/library_cdm/ppapi_cdm_buffer.h",
"//media/cdm/supported_cdm_versions.cc",
"//media/cdm/supported_cdm_versions.h",
]
if (is_mac) {
ldflags += [
# Not to strip important symbols by -Wl,-dead_strip.
"-Wl,-exported_symbol,_PPP_GetInterface",
"-Wl,-exported_symbol,_PPP_InitializeModule",
"-Wl,-exported_symbol,_PPP_ShutdownModule",
]
output_extension = "plugin"
} else if (is_posix) {
cflags += [ "-fvisibility=hidden" ]
# Required for clock_gettime()
libs += [ "rt" ]
}
if (is_linux) {
# CDM adapter depends on a CDM in component and non-component builds.
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
if (use_lld) {
# TODO(crbug.com/795158) LLD warns about libwidevinecdm.so
configs -= [ "//build/config/compiler:default_fatal_linker_warnings" ]
}
}
# TODO(jschuh) crbug.com/167187
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
}
}
This diff is collapsed.
// Copyright 2013 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/cdm/library_cdm/ppapi_cdm_buffer.h"
#include <algorithm>
#include "ppapi/cpp/core.h"
#include "ppapi/cpp/module.h"
namespace media {
// static
PpbBuffer* PpbBuffer::Create(const pp::Buffer_Dev& buffer,
uint32_t buffer_id,
PpbBufferAllocator* allocator) {
PP_DCHECK(buffer.data());
PP_DCHECK(buffer.size());
PP_DCHECK(buffer_id);
PP_DCHECK(allocator);
return new PpbBuffer(buffer, buffer_id, allocator);
}
void PpbBuffer::Destroy() {
delete this;
}
uint32_t PpbBuffer::Capacity() const {
return buffer_.size();
}
uint8_t* PpbBuffer::Data() {
return static_cast<uint8_t*>(buffer_.data());
}
void PpbBuffer::SetSize(uint32_t size) {
PP_DCHECK(size <= Capacity());
if (size > Capacity()) {
size_ = 0;
return;
}
size_ = size;
}
uint32_t PpbBuffer::Size() const {
return size_;
}
pp::Buffer_Dev PpbBuffer::TakeBuffer() {
PP_DCHECK(!buffer_.is_null());
pp::Buffer_Dev buffer;
std::swap(buffer, buffer_);
buffer_id_ = 0;
size_ = 0;
return buffer;
}
PpbBuffer::PpbBuffer(pp::Buffer_Dev buffer,
uint32_t buffer_id,
PpbBufferAllocator* allocator)
: buffer_(buffer), buffer_id_(buffer_id), size_(0), allocator_(allocator) {}
PpbBuffer::~PpbBuffer() {
PP_DCHECK(!buffer_id_ == buffer_.is_null());
// If still owning the |buffer_|, release it in the |allocator_|.
if (buffer_id_)
allocator_->Release(buffer_id_);
}
PpbBufferAllocator::PpbBufferAllocator(pp::Instance* instance)
: instance_(instance), next_buffer_id_(1) {}
PpbBufferAllocator::~PpbBufferAllocator() {}
cdm::Buffer* PpbBufferAllocator::Allocate(uint32_t capacity) {
PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
if (!capacity)
return NULL;
pp::Buffer_Dev buffer;
uint32_t buffer_id = 0;
// Reuse a buffer in the free list if there is one that fits |capacity|.
// Otherwise, create a new one.
FreeBufferMap::iterator found = free_buffers_.lower_bound(capacity);
if (found == free_buffers_.end()) {
// TODO(xhwang): Report statistics about how many new buffers are allocated.
buffer = AllocateNewBuffer(capacity);
if (buffer.is_null())
return NULL;
buffer_id = next_buffer_id_++;
} else {
buffer = found->second.second;
buffer_id = found->second.first;
free_buffers_.erase(found);
}
allocated_buffers_.insert(std::make_pair(buffer_id, buffer));
return PpbBuffer::Create(buffer, buffer_id, this);
}
void PpbBufferAllocator::Release(uint32_t buffer_id) {
if (!buffer_id)
return;
AllocatedBufferMap::iterator found = allocated_buffers_.find(buffer_id);
if (found == allocated_buffers_.end())
return;
pp::Buffer_Dev& buffer = found->second;
free_buffers_.insert(
std::make_pair(buffer.size(), std::make_pair(buffer_id, buffer)));
allocated_buffers_.erase(found);
}
pp::Buffer_Dev PpbBufferAllocator::AllocateNewBuffer(uint32_t capacity) {
// Always pad new allocated buffer so that we don't need to reallocate
// buffers frequently if requested sizes fluctuate slightly.
static const uint32_t kBufferPadding = 512;
// Maximum number of free buffers we can keep when allocating new buffers.
static const uint32_t kFreeLimit = 3;
// Destroy the smallest buffer before allocating a new bigger buffer if the
// number of free buffers exceeds a limit. This mechanism helps avoid ending
// up with too many small buffers, which could happen if the size to be
// allocated keeps increasing.
if (free_buffers_.size() >= kFreeLimit)
free_buffers_.erase(free_buffers_.begin());
// Creation of pp::Buffer_Dev is expensive! It involves synchronous IPC calls.
// That's why we try to avoid AllocateNewBuffer() as much as we can.
return pp::Buffer_Dev(instance_, capacity + kBufferPadding);
}
} // namespace media
// Copyright 2013 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_CDM_LIBRARY_CDM_PPAPI_CDM_BUFFER_H_
#define MEDIA_CDM_LIBRARY_CDM_PPAPI_CDM_BUFFER_H_
#include <map>
#include <utility>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "media/cdm/api/content_decryption_module.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/cpp/dev/buffer_dev.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/logging.h"
namespace media {
class PpbBufferAllocator;
// cdm::Buffer implementation that provides access to memory owned by a
// pp::Buffer_Dev.
// This class holds a reference to the Buffer_Dev throughout its lifetime.
// TODO(xhwang): Find a better name. It's confusing to have PpbBuffer,
// pp::Buffer_Dev and PPB_Buffer_Dev.
class PpbBuffer : public cdm::Buffer {
public:
static PpbBuffer* Create(const pp::Buffer_Dev& buffer,
uint32_t buffer_id,
PpbBufferAllocator* allocator);
// cdm::Buffer implementation.
void Destroy() override;
uint32_t Capacity() const override;
uint8_t* Data() override;
void SetSize(uint32_t size) override;
uint32_t Size() const override;
// Takes the |buffer_| from this class and returns it.
// Note: The caller must ensure |allocator->Release()| is called later so that
// the buffer can be reused by the allocator.
// Since pp::Buffer_Dev is ref-counted, the caller now holds one reference to
// the buffer and this class holds no reference. Note that other references
// may still exist. For example, PpbBufferAllocator always holds a reference
// to all allocated buffers.
pp::Buffer_Dev TakeBuffer();
uint32_t buffer_id() const { return buffer_id_; }
private:
PpbBuffer(pp::Buffer_Dev buffer,
uint32_t buffer_id,
PpbBufferAllocator* allocator);
~PpbBuffer() override;
pp::Buffer_Dev buffer_;
uint32_t buffer_id_;
uint32_t size_;
PpbBufferAllocator* allocator_;
DISALLOW_COPY_AND_ASSIGN(PpbBuffer);
};
class PpbBufferAllocator {
public:
explicit PpbBufferAllocator(pp::Instance* instance);
~PpbBufferAllocator();
cdm::Buffer* Allocate(uint32_t capacity);
// Releases the buffer with |buffer_id|. A buffer can be recycled after
// it is released.
void Release(uint32_t buffer_id);
private:
typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap;
typedef std::multimap<uint32_t, std::pair<uint32_t, pp::Buffer_Dev>>
FreeBufferMap;
pp::Buffer_Dev AllocateNewBuffer(uint32_t capacity);
pp::Instance* const instance_;
uint32_t next_buffer_id_;
AllocatedBufferMap allocated_buffers_;
FreeBufferMap free_buffers_;
DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator);
};
} // namespace media
#endif // MEDIA_CDM_LIBRARY_CDM_PPAPI_CDM_BUFFER_H_
...@@ -5,24 +5,16 @@ ...@@ -5,24 +5,16 @@
#ifndef MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_ #ifndef MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_
#define MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_ #define MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_
#ifdef USE_PPAPI_CDM_ADAPTER #include "media/base/media_export.h"
// When building the adapter these functions need to be local.
#define FUNCTION_EXPORT
#else
#include "media/base/media_export.h" // nogncheck
#define FUNCTION_EXPORT MEDIA_EXPORT
#endif
namespace media { namespace media {
FUNCTION_EXPORT bool IsSupportedCdmModuleVersion(int version); MEDIA_EXPORT bool IsSupportedCdmModuleVersion(int version);
FUNCTION_EXPORT bool IsSupportedCdmInterfaceVersion(int version); MEDIA_EXPORT bool IsSupportedCdmInterfaceVersion(int version);
FUNCTION_EXPORT bool IsSupportedCdmHostVersion(int version); MEDIA_EXPORT bool IsSupportedCdmHostVersion(int version);
} // namespace media } // namespace media
#undef FUNCTION_EXPORT
#endif // MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_ #endif // MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_
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