├── COMPATIBLE
├── docs
├── img
│ ├── ocdm_scope.png
│ ├── arch_cdm_cdmi.png
│ └── arch_layer_approach.png
├── build_notes_chromium.md
└── architecture_notes_ocdm.md
├── src
├── com
│ ├── README.md
│ ├── common
│ │ ├── rpc
│ │ │ ├── opencdm_callback.x
│ │ │ ├── opencdm_callback_xdr.c
│ │ │ ├── opencdm_xdr.x
│ │ │ ├── opencdm_callback.h
│ │ │ ├── opencdm_xdr_clnt.c
│ │ │ ├── opencdm_xdr_xdr.c
│ │ │ └── opencdm_xdr.h
│ │ └── shmemsem
│ │ │ ├── shmemsem_helper.h
│ │ │ └── shmemsem_helper.cc
│ ├── cdm
│ │ ├── open_cdm_platform_com_handler_factory.h
│ │ └── rpc
│ │ │ ├── rpc_cdm_platform_handler.h
│ │ │ └── rpc_cdm_platform_handler.cc
│ └── mediaengine
│ │ └── rpc
│ │ ├── rpc_cdm_mediaengine_handler.h
│ │ └── rpc_cdm_mediaengine_handler.cc
├── README.md
├── browser
│ ├── chrome
│ │ ├── tests
│ │ │ ├── data
│ │ │ │ └── test.html
│ │ │ └── ocdm_encrypted_media_istypesupported_browsertest.cc
│ │ ├── open_cdm_chrome_common.h
│ │ ├── open_cdm.h
│ │ └── open_cdm.cc
│ └── media_open_cdm.gypi
├── common
│ └── open_cdm_common.h
├── mediaengine
│ ├── open_cdm_mediaengine_com.h
│ ├── open_cdm_mediaengine_impl.h
│ ├── open_cdm_mediaengine_factory.h
│ ├── open_cdm_mediaengine.h
│ └── open_cdm_mediaengine_impl.cc
└── cdm
│ ├── open_cdm_platform_com.h
│ ├── open_cdm_platform_factory.h
│ ├── open_cdm_platform_com_callback_receiver.h
│ ├── open_cdm_platform_common.h
│ ├── open_cdm_platform.h
│ ├── open_cdm_platform_impl.h
│ └── open_cdm_platform_impl.cc
├── tests
└── README.md
├── patch
└── add_opencdm_to_chrome_key_system.patch
├── LICENSE
└── README.md
/COMPATIBLE:
--------------------------------------------------------------------------------
1 | # Compatible Chromium
2 | v43.0.2357.81
3 |
--------------------------------------------------------------------------------
/docs/img/ocdm_scope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraunhoferfokus/open-content-decryption-module/HEAD/docs/img/ocdm_scope.png
--------------------------------------------------------------------------------
/docs/img/arch_cdm_cdmi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraunhoferfokus/open-content-decryption-module/HEAD/docs/img/arch_cdm_cdmi.png
--------------------------------------------------------------------------------
/docs/img/arch_layer_approach.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fraunhoferfokus/open-content-decryption-module/HEAD/docs/img/arch_layer_approach.png
--------------------------------------------------------------------------------
/src/com/README.md:
--------------------------------------------------------------------------------
1 | # Folder structure
2 | * *cdm*: implementation of content decryption module functionality
3 | * *common*: implementation of common helpers
4 | * *mediaengine*: implementation of media engines
--------------------------------------------------------------------------------
/src/README.md:
--------------------------------------------------------------------------------
1 | # Folder structure
2 | * *browser*: browser specific glue code
3 | * *cdm*: content decryption module c++ interfaces
4 | * *com*: implementation of the communication layer
5 | * *common*: configuration files
6 | * *mediaengine*: media engine c++ interfaces
--------------------------------------------------------------------------------
/src/browser/chrome/tests/data/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | ## How to test
2 |
3 | ### ...with Pepper Plugin for Chromium
4 |
5 | * Test setup:
6 | * ```$ cd $CHROMIUM_ROOT/src```
7 | * ```$ ln -s $HOME/opencdm/src/browser/chrome/tests/data $CHROMIUM_ROOT/src/chrome/test/data/media/drmock```
8 | * In file $CHROMIUM_ROOT/src/chrome/chrome_tests.gypi add the following to the sources section of the target browser_tests
9 |
10 | ```
11 | 'browser/media/encrypted_media_istypesupported_browsertest.cc',
12 | # OCDM tests
13 | '<(DEPTH)/media/cdm/ppapi/external_open_cdm/browser/chrome/tests/ocdm_encrypted_media_istypesupported_browsertest.cc',
14 | ```
15 |
16 | * ```$ ./build/gyp_chromium```
17 | * ```$ ninja -C out/Debug browser_tests```
18 |
19 | * Test execution:
20 | * ```$ cd $CHROMIUM_ROOT/src```
21 | * ```$ ./out/Debug/browser_tests --gtest_filter="OpenCDM*"```
22 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_callback.x:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenCDM XDR to be used for RPC communication between DRM and CDM platform counterpart
3 | * Based on EME methods and naming.
4 | */
5 |
6 | struct rpc_cb_message {
7 | char session_id <>;
8 | string message <>;
9 | string destination_url <>;
10 | };
11 |
12 | struct rpc_cb_key_status_update {
13 | char session_id <>;
14 | string message <>;
15 | };
16 |
17 |
18 | struct rpc_cb_ready {
19 | char session_id <>;
20 | };
21 |
22 |
23 | struct rpc_cb_error {
24 | char session_id <>;
25 | int error;
26 | string error_message <>;
27 | };
28 |
29 | program OPEN_CDM_CALLBACK {
30 | version OPEN_CDM_EME_5 {
31 | void ON_KEY_MESSAGE(rpc_cb_message) = 1;
32 | void ON_KEY_READY(rpc_cb_ready) = 2;
33 | void ON_KEY_ERROR(rpc_cb_error) = 3;
34 | void ON_KEY_STATUS_UPDATE(rpc_cb_key_status_update) = 4;
35 | } = 1;
36 | } = 0x66666666;
37 |
--------------------------------------------------------------------------------
/src/common/open_cdm_common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COMMON_OPEN_CDM_COMMON_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COMMON_OPEN_CDM_COMMON_H_
16 |
17 | namespace media {
18 |
19 | //const char kExternalOpenCdmKeySystem[] = "com.opencdm.mockdrm";
20 | const char kExternalOpenCdmKeySystem[] = "org.chromium.externalclearkey";
21 | const char kOpenCdmVersion[] = "1.0.0.0";
22 |
23 | } // namespace media
24 |
25 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COMMON_OPEN_CDM_COMMON_H_
26 |
--------------------------------------------------------------------------------
/src/mediaengine/open_cdm_mediaengine_com.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_COM_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_COM_H_
16 |
17 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine.h"
18 |
19 | namespace media {
20 |
21 | class OpenCdmMediaengineCom : public OpenCdmMediaengine {
22 | public:
23 | OpenCdmMediaengineCom(char *session_id_val, uint32_t session_id_len,
24 | uint8_t *auth_data_val, uint32_t auth_data_len);
25 | ~OpenCdmMediaengineCom() override {}
26 |
27 | protected:
28 | OpenCdmMediaengineCom() {}
29 | };
30 |
31 | } // namespace media
32 |
33 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_COM_H_
34 |
--------------------------------------------------------------------------------
/src/browser/chrome/open_cdm_chrome_common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | // Based on file contibuted to the Chromium project
15 | // media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h
16 | // License notice of original file:
17 |
18 | // Copyright 2013 The Chromium Authors. All rights reserved.
19 | // Use of this source code is governed by a BSD-style license that can be
20 | // found in the LICENSE file.
21 |
22 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_BROWSER_CHROME_OPEN_CDM_CHROME_COMMON_H_
23 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_BROWSER_CHROME_OPEN_CDM_CHROME_COMMON_H_
24 |
25 | #include "media/cdm/ppapi/api/content_decryption_module.h"
26 |
27 | namespace media {
28 |
29 | // Aliases for the version of the interfaces that this CDM implements.
30 | typedef cdm::ContentDecryptionModule_8 OpenCdmInterface;
31 | typedef OpenCdmInterface::Host OpenCdmHost;
32 |
33 | } // namespace media
34 |
35 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_BROWSER_CHROME_OPEN_CDM_CHROME_COMMON_H_
36 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform_com.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COM_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COM_H_
16 |
17 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_common.h"
18 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform.h"
19 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
20 |
21 | #include
22 |
23 | namespace media {
24 |
25 | enum OCDM_COM_STATE {
26 | UNINITIALIZED = 0,
27 | INITIALIZED = 1,
28 | FAULTY = 2,
29 | ABORTED = 3
30 | };
31 |
32 | class OpenCdmPlatformCom : public OpenCdmPlatform {
33 | public:
34 | ~OpenCdmPlatformCom() override{
35 | }
36 | OpenCdmPlatformCom(OpenCdmPlatformComCallbackReceiver *callback_receiver_);
37 |
38 | protected:
39 | OpenCdmPlatformCom() {
40 | }
41 |
42 | OCDM_COM_STATE com_state;
43 |
44 | private:
45 | };
46 | } // namespace media
47 |
48 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COM_H_
49 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_callback_xdr.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Please do not edit this file.
3 | * It was generated using rpcgen.
4 | */
5 |
6 | #include "opencdm_callback.h"
7 |
8 | bool_t
9 | xdr_rpc_cb_message (XDR *xdrs, rpc_cb_message *objp)
10 | {
11 |
12 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
13 | sizeof (char), (xdrproc_t) xdr_char))
14 | return FALSE;
15 | if (!xdr_string (xdrs, &objp->message, ~0))
16 | return FALSE;
17 | if (!xdr_string (xdrs, &objp->destination_url, ~0))
18 | return FALSE;
19 | return TRUE;
20 | }
21 |
22 | bool_t
23 | xdr_rpc_cb_key_status_update (XDR *xdrs, rpc_cb_key_status_update *objp)
24 | {
25 |
26 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
27 | sizeof (char), (xdrproc_t) xdr_char))
28 | return FALSE;
29 | if (!xdr_string (xdrs, &objp->message, ~0))
30 | return FALSE;
31 | return TRUE;
32 | }
33 |
34 | bool_t
35 | xdr_rpc_cb_ready (XDR *xdrs, rpc_cb_ready *objp)
36 | {
37 |
38 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
39 | sizeof (char), (xdrproc_t) xdr_char))
40 | return FALSE;
41 | return TRUE;
42 | }
43 |
44 | bool_t
45 | xdr_rpc_cb_error (XDR *xdrs, rpc_cb_error *objp)
46 | {
47 |
48 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
49 | sizeof (char), (xdrproc_t) xdr_char))
50 | return FALSE;
51 | if (!xdr_int (xdrs, &objp->error))
52 | return FALSE;
53 | if (!xdr_string (xdrs, &objp->error_message, ~0))
54 | return FALSE;
55 | return TRUE;
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/cdm/open_cdm_platform_com_handler_factory.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_CDM_OPEN_CDM_PLATFORM_COM_HANDLER_FACTORY_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_CDM_OPEN_CDM_PLATFORM_COM_HANDLER_FACTORY_H_
16 |
17 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com.h"
18 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
19 | #include "media/cdm/ppapi/external_open_cdm/com/cdm/rpc/rpc_cdm_platform_handler.h"
20 |
21 | namespace media {
22 |
23 | class OpenCdmPlatformComHandlerFactory {
24 | public:
25 | static OpenCdmPlatformCom *Create(
26 | OpenCdmPlatformComCallbackReceiver *callback_receiver_);
27 | };
28 |
29 | /*
30 | * returns raw pointer to be platform and type independent, can be converted
31 | * to smart pointer on successful creation.
32 | */
33 | OpenCdmPlatformCom *OpenCdmPlatformComHandlerFactory::Create(
34 | OpenCdmPlatformComCallbackReceiver *callback_receiver_) {
35 | return new RpcCdmPlatformHandler(callback_receiver_);
36 | }
37 | } // namespace media
38 |
39 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_CDM_OPEN_CDM_PLATFORM_COM_HANDLER_FACTORY_H_
40 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform_factory.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_FACTORY_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_FACTORY_H_
16 |
17 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform.h"
18 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_impl.h"
19 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
20 |
21 | namespace media {
22 |
23 | class OpenCdmPlatformInterfaceFactory {
24 | public:
25 | static OpenCdmPlatform *Create(
26 | OpenCdmPlatformComCallbackReceiver *callback_receiver_);
27 | };
28 |
29 | /*
30 | * returns raw pointer to be platform and type independent, can be converted
31 | * to smart pointer on successful creation.
32 | */
33 | OpenCdmPlatform *OpenCdmPlatformInterfaceFactory::Create(
34 | OpenCdmPlatformComCallbackReceiver *callback_receiver_) {
35 | // TODO(ska): decide on *CdmImpl by means of platform (unix...)
36 | // and available key systems for given key_system
37 | return new OpenCdmPlatformImpl(callback_receiver_);
38 | }
39 | } // namespace media
40 |
41 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_FACTORY_H_
42 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform_com_callback_receiver.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COM_CALLBACK_RECEIVER_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COM_CALLBACK_RECEIVER_H_
16 |
17 | #include
18 |
19 | namespace media {
20 |
21 | /*
22 | * This interface serves as receiver interface for callbacks that are
23 | * necessary to be handled by the platform caller.
24 | */
25 | class OpenCdmPlatformComCallbackReceiver {
26 | public:
27 | // according to EME
28 |
29 | virtual void ErrorCallback(OpenCdmPlatformSessionId platform_session_id,
30 | uint32_t sys_err, std::string err_msg) = 0;
31 | virtual void MessageCallback(OpenCdmPlatformSessionId platform_session_id,
32 | std::string message,
33 | std::string destination_url) = 0;
34 | virtual void OnKeyStatusUpdateCallback(OpenCdmPlatformSessionId platform_session_id,
35 | std::string message) = 0;
36 | // TODO(ska): message should be uint8_t*
37 | virtual void ReadyCallback(OpenCdmPlatformSessionId platform_session_id) = 0;
38 |
39 | virtual ~OpenCdmPlatformComCallbackReceiver() {
40 | }
41 | protected:
42 | OpenCdmPlatformComCallbackReceiver() {
43 | }
44 | };
45 | } // namespace media
46 |
47 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COM_CALLBACK_RECEIVER_H_
48 |
--------------------------------------------------------------------------------
/patch/add_opencdm_to_chrome_key_system.patch:
--------------------------------------------------------------------------------
1 | diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
2 | index 63d4734..5f04240 100644
3 | --- a/chrome/renderer/media/chrome_key_systems.cc
4 | +++ b/chrome/renderer/media/chrome_key_systems.cc
5 | @@ -48,6 +48,38 @@ static bool IsPepperCdmAvailable(
6 | return is_available;
7 | }
8 |
9 | +// External Open CDM.
10 | +static void AddExternalOpenCdm(
11 | + std::vector* concrete_key_systems) {
12 | + static const char kExternalOpenCdmKeySystem[] =
13 | + "com.opencdm.mockdrm";
14 | + static const char kExternalOpenCdmPepperType[] =
15 | + "application/x-ppapi-open-cdm";
16 | +
17 | + std::vector additional_param_names;
18 | + std::vector additional_param_values;
19 | + if (!IsPepperCdmAvailable(kExternalOpenCdmPepperType,
20 | + &additional_param_names,
21 | + &additional_param_values)) {
22 | + return;
23 | + }
24 | +
25 | + KeySystemInfo info;
26 | + info.key_system = kExternalOpenCdmKeySystem;
27 | + info.supported_codecs |= media::EME_CODEC_WEBM_ALL;
28 | + info.supported_init_data_types |= media::kInitDataTypeMaskWebM;
29 | + #if defined (USE_PROPRIETARY_CODECS)
30 | + info.supported_codecs |= media::EME_CODEC_MP4_ALL;
31 | + info.supported_init_data_types |= media::kInitDataTypeMaskCenc;
32 | + #endif
33 | +
34 | +
35 | + info.pepper_type = kExternalOpenCdmPepperType;
36 | +
37 | + concrete_key_systems->push_back(info);
38 | +}
39 | +
40 | +
41 | // External Clear Key (used for testing).
42 | static void AddExternalClearKey(
43 | std::vector* concrete_key_systems) {
44 | @@ -216,7 +248,7 @@ static void AddPepperBasedWidevine(
45 | void AddChromeKeySystems(std::vector* key_systems_info) {
46 | #if defined(ENABLE_PEPPER_CDMS)
47 | AddExternalClearKey(key_systems_info);
48 | -
49 | + AddExternalOpenCdm(key_systems_info);
50 | #if defined(WIDEVINE_CDM_AVAILABLE)
51 | AddPepperBasedWidevine(key_systems_info);
52 | #endif // defined(WIDEVINE_CDM_AVAILABLE)
53 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_xdr.x:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenCDM XDR to be used for RPC communication between CDM and DRM platform counterpart
3 | * Based on EME methods and naming.
4 | */
5 |
6 | /*
7 | * REQUEST DATA TYPES
8 | */
9 |
10 | struct rpc_request_is_type_supported {
11 | char key_system <>;
12 | char mime_type <>;
13 | };
14 |
15 | struct rpc_request_mediakeys {
16 | char key_system <>;
17 | };
18 |
19 | struct rpc_request_callback_info {
20 | char hostname <>;
21 | uint64_t prog_num;
22 | uint32_t prog_version;
23 | };
24 |
25 | struct rpc_request_create_session {
26 | char init_data_type <>;
27 | uint8_t init_data <>;
28 | rpc_request_callback_info callback_info;
29 | };
30 |
31 | struct rpc_request_load_session {
32 | char session_id <>;
33 | };
34 |
35 | struct rpc_request_session_update {
36 | char session_id <>;
37 | uint8_t key <>;
38 | };
39 |
40 | struct rpc_request_session_release {
41 | char session_id <>;
42 | };
43 |
44 | struct rpc_request_mediaengine_data {
45 | char session_id <>;
46 | uint8_t auth_data <>;
47 | int32_t id_exchange_shmem;
48 | int32_t id_exchange_sem;
49 | };
50 |
51 | /*
52 | * RESPONSE DATA TYPES
53 | */
54 |
55 | struct rpc_response_generic {
56 | int platform_val;
57 | };
58 |
59 | struct rpc_response_create_session {
60 | int platform_val;
61 | char session_id <>;
62 | };
63 |
64 | program OPEN_CDM {
65 | version OPEN_CDM_EME_5 {
66 | rpc_response_generic RPC_OPEN_CDM_IS_TYPE_SUPPORTED(rpc_request_is_type_supported) = 1;
67 | rpc_response_generic RPC_OPEN_CDM_MEDIAKEYS(rpc_request_mediakeys) = 2;
68 | rpc_response_create_session RPC_OPEN_CDM_MEDIAKEYS_CREATE_SESSION(rpc_request_create_session) = 3;
69 | rpc_response_generic RPC_OPEN_CDM_MEDIAKEYS_LOAD_SESSION(rpc_request_load_session) = 4;
70 | rpc_response_generic RPC_OPEN_CDM_MEDIAKEYSESSION_UPDATE(rpc_request_session_update) = 5;
71 | rpc_response_generic RPC_OPEN_CDM_MEDIAKEYSESSION_RELEASE(rpc_request_session_release) = 6;
72 | rpc_response_generic RPC_OPEN_CDM_MEDIAENGINE(rpc_request_mediaengine_data) = 7;
73 | } = 1;
74 | } = 0x61135687; /* FAMEFHG */
75 |
--------------------------------------------------------------------------------
/src/mediaengine/open_cdm_mediaengine_impl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_IMPL_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_IMPL_H_
16 |
17 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine.h"
18 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine_com.h"
19 | #include
20 | #include
21 | #include "media/cdm/ppapi/external_open_cdm/com/common/shmemsem/shmemsem_helper.h"
22 |
23 | namespace media {
24 |
25 | /**
26 | * MediaEngineSession serves as an interface between a platform's mediaengine
27 | * and the CDMi. It is established as soon as EME signals 'keyAdded'.
28 | * RPC and shared memory are used for communication.
29 | * Secure channel decryption is not included.
30 | */
31 | class OpenCdmMediaengineImpl : public OpenCdmMediaengine {
32 | public:
33 | OpenCdmMediaengineImpl(char *session_id_val, uint32_t session_id_len);
34 | OpenCdmMediaengineImpl(char *session_id_val, uint32_t session_id_len,
35 | uint8_t *auth_data_val, uint32_t auth_data_len);
36 |
37 | // synchronous decryption
38 | DecryptResponse Decrypt(const uint8_t *pbIv, uint32_t cbIv,
39 | const uint8_t *pbData, uint32_t cbData,
40 | uint8_t *out, uint32_t &out_size) override;
41 |
42 | ~OpenCdmMediaengineImpl() override;
43 | private:
44 | OpenCdmMediaengineCom *media_engine_com_;
45 | };
46 |
47 | } // namespace media
48 |
49 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_IMPL_H_
50 |
--------------------------------------------------------------------------------
/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_MEDIAENGINE_RPC_RPC_CDM_MEDIAENGINE_HANDLER_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_MEDIAENGINE_RPC_RPC_CDM_MEDIAENGINE_HANDLER_H_
16 |
17 | #include
18 | #include
19 |
20 | #include "media/cdm/ppapi/external_open_cdm/com/common/shmemsem/shmemsem_helper.h"
21 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine_com.h"
22 |
23 | namespace media {
24 |
25 | /**
26 | * MediaEngineSession serves as an interface between a platform's mediaengine
27 | * and the CDMi. It is established as soon as EME signals 'keyAdded'.
28 | * RPC and shared memory are used for communication.
29 | * Secure channel decryption is not included.
30 | */
31 | class RpcCdmMediaengineHandler : public OpenCdmMediaengineCom {
32 | public:
33 | RpcCdmMediaengineHandler(char *session_id_val, uint32_t session_id_len,
34 | uint8_t *auth_data_val, uint32_t auth_data_len);
35 | DecryptResponse Decrypt(const uint8_t *pbIv, uint32_t cbIv,
36 | const uint8_t *pbData, uint32_t cbData,
37 | uint8_t *out, uint32_t &out_size) override;
38 | //TODO (sph): make out const
39 | ~RpcCdmMediaengineHandler() override;
40 |
41 | private:
42 | MediaEngineSessionId sessionId;
43 |
44 | CLIENT *rpcClient;
45 |
46 | // shared memory
47 | shmem_info *shMemInfo;
48 | int idXchngShMem;
49 | int idXchngSem;
50 | };
51 |
52 | } // namespace media
53 |
54 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_MEDIAENGINE_RPC_RPC_CDM_MEDIAENGINE_HANDLER_H_
55 |
--------------------------------------------------------------------------------
/src/com/common/shmemsem/shmemsem_helper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | /*
15 | * based on Keith Gaughan - Shared Memory and Semaphores - March 22, 2003
16 | */
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #ifndef SHMEM_SEM_HELPER
27 | #define SHMEM_SEM_HELPER
28 |
29 | #if !defined(__GNU_LIBRARY__) || defined(_SEM_SEMUN_UNDEFINED)
30 | union semun {
31 | int val; // value for SETVAL
32 | struct semid_ds* buf; // buffer for IPC_STAT, IPC_SET
33 | unsigned short* array; // array for GETALL, SETALL
34 | struct seminfo* __buf; // buffer for IPC_INFO
35 | };
36 | #endif
37 |
38 | /*
39 | * FAMIUM SPECIFIC
40 | */
41 |
42 | // static info exchange shmem
43 | struct shmem_info {
44 | int32_t idSidShMem;
45 | int32_t idIvShMem;
46 | int32_t idSampleShMem;
47 | int32_t idSubsampleDataShMem;
48 | uint32_t sidSize;
49 | uint32_t ivSize;
50 | uint32_t sampleSize;
51 | uint32_t subsampleDataSize;
52 | };
53 |
54 | enum {
55 | SEM_XCHNG_PUSH,
56 | SEM_XCHNG_DECRYPT,
57 | SEM_XCHNG_PULL
58 | };
59 |
60 | /*
61 | * GENERAL SHARED MEM AND SEMAPHORES
62 | */
63 |
64 | // Declarations for wrapper functions...line
65 | int AllocateSharedMemory(int n);
66 | void* MapSharedMemory(int id);
67 | void* MapExistingSharedMemory(int id, void* existingAddr);
68 | int DetachExistingSharedMemory(void* existingAddr);
69 | int CreateSemaphoreSet(int n, unsigned short* vals);
70 | void DeleteSemaphoreSet(int id);
71 | void LockSemaphore(int id, int i);
72 | void UnlockSemaphore(int id, int i);
73 |
74 | #endif // SHMEM_SEM_HELPER
75 |
--------------------------------------------------------------------------------
/src/mediaengine/open_cdm_mediaengine_factory.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_FACTORY_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_FACTORY_H_
16 |
17 | #include
18 |
19 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine.h"
20 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine_impl.h"
21 |
22 | #include "media/cdm/ppapi/cdm_logging.h"
23 |
24 | namespace media {
25 |
26 | //const std::string open_cdm_key_system = "com.opencdm.mockdrm";
27 | const std::string open_cdm_key_system = "org.chromium.externalclearkey";
28 |
29 | // TODO(ska): outsource the mapping of key system string
30 | // to mediaengine and platform implementations
31 |
32 | class OpenCdmMediaengineFactory {
33 | public:
34 | static OpenCdmMediaengine *Create(std::string key_system,
35 | OpenCdmPlatformSessionId session_id);
36 | };
37 |
38 | /*
39 | * returns raw pointer to be platform and type independent, can be converted
40 | * to smart pointer on successful creation.
41 | */
42 | OpenCdmMediaengine *OpenCdmMediaengineFactory::Create(
43 | std::string key_system, OpenCdmPlatformSessionId session_id) {
44 | if (key_system == open_cdm_key_system) {
45 | CDM_DLOG() << "Instantiate OpenCdmMediaengineImpl!";
46 | return new OpenCdmMediaengineImpl(session_id.session_id,
47 | session_id.session_id_len);
48 | } else {
49 | CDM_DLOG() << "Failed to create MediaEngine";
50 | return NULL;
51 | }
52 | }
53 | } // namespace media
54 |
55 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_FACTORY_H_
56 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform_common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COMMON_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COMMON_H_
16 |
17 | #include
18 | #include "base/basictypes.h"
19 |
20 | namespace media {
21 |
22 | // TODO(sph): PLATFORM_CALL_STATE should not be CDMi, but EME-specific
23 | enum PLATFORM_CALL_STATE {
24 | PLATFORM_CALL_SUCCESS = 0,
25 | PLATFORM_CALL_FAIL = 1,
26 | PLATFORM_CALL_NOACTION = 2,
27 | PLATFORM_CALL_NEEDKEY = 3
28 | };
29 |
30 | struct PlatformResponse {
31 | PLATFORM_CALL_STATE platform_response;
32 | int32 sys_err;
33 | };
34 |
35 | struct OpenCdmPlatformSessionId {
36 | char *session_id; // TODO(ska): uint16_t oder uint8_t ? CDMi: 16
37 | uint32_t session_id_len;
38 | };
39 |
40 | struct MediaKeysResponse : public PlatformResponse {
41 | };
42 | struct MediaKeysCreateSessionResponse : public PlatformResponse {
43 | OpenCdmPlatformSessionId session_id;
44 | };
45 | struct MediaKeysLoadSessionResponse : public PlatformResponse {
46 | };
47 | struct MediaKeySessionUpdateResponse : public PlatformResponse {
48 | };
49 | struct MediaKeySessionReleaseResponse : public PlatformResponse {
50 | };
51 |
52 | class DecryptReadyStateKeeper {
53 | public:
54 | virtual ~DecryptReadyStateKeeper();
55 | static DecryptReadyStateKeeper *getInstance();
56 |
57 | void lockDecryptSem();
58 | void unlockDecryptSem();
59 | void lockInitSem();
60 | void unlockInitSem();
61 | private:
62 | DecryptReadyStateKeeper();
63 | static DecryptReadyStateKeeper *instance;
64 |
65 | int idDecryptReadySem;
66 | int _instance_id;
67 | };
68 |
69 | } // namespace media
70 |
71 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_COMMON_H_
72 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_H_
16 |
17 | #include
18 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_common.h"
19 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
20 |
21 | namespace media {
22 |
23 | class OpenCdmPlatform {
24 | public:
25 | // NEW EME based interface
26 | // on errors tear down media keys and media key session objects
27 |
28 | // EME equivalent: new MediaKeys()
29 | virtual MediaKeysResponse MediaKeys(std::string key_system) = 0;
30 |
31 | // EME equivalent: media_keys_.createSession()
32 | virtual MediaKeysCreateSessionResponse MediaKeysCreateSession(
33 | const std::string& init_data_type, const uint8_t* init_data,
34 | int init_data_length) = 0;
35 |
36 | // EME equivalent: media_keys_.loadSession()
37 | virtual MediaKeysLoadSessionResponse MediaKeysLoadSession(
38 | char *session_id_val, uint32_t session_id_len) = 0;
39 |
40 | // EME equivalent: media_key_session_.update()
41 | virtual MediaKeySessionUpdateResponse MediaKeySessionUpdate(
42 | const uint8 *pbKey, uint32 cbKey, char *session_id_val,
43 | uint32_t session_id_len) = 0;
44 |
45 | // EME equivalent: media_key_session_.release()
46 | virtual MediaKeySessionReleaseResponse MediaKeySessionRelease(
47 | char *session_id_val, uint32_t session_id_len) = 0;
48 |
49 |
50 | virtual ~OpenCdmPlatform() {
51 | }
52 | OpenCdmPlatform(OpenCdmPlatformComCallbackReceiver *callback_receiver_);
53 |
54 | protected:
55 | OpenCdmPlatform() {
56 | }
57 | };
58 | } // namespace media
59 |
60 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_H_
61 |
--------------------------------------------------------------------------------
/src/mediaengine/open_cdm_mediaengine.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_H_
16 |
17 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_common.h"
18 |
19 | namespace media {
20 |
21 | struct MediaEngineSessionResponse : public PlatformResponse {
22 | uint8_t *pbEncryptedSessionKey;
23 | uint32_t cbEncryptedSessionKey;
24 | };
25 |
26 | struct DecryptResponse : public PlatformResponse {
27 | uint8_t *pbResponseData;
28 | uint32_t cbResponseData;
29 | };
30 |
31 | /*
32 | * used for encrypting the DRM-decrypted content to ensure a secure
33 | * transmission between CDMi and CDM mediaengine
34 | */
35 | struct MediaEngineSessionKey {
36 | uint8_t *key;
37 | uint32_t keyLen;
38 | };
39 |
40 | struct MediaEngineSessionId {
41 | char *id;
42 | uint32_t idLen;
43 | };
44 |
45 | /* Extended EME: // REVIEW(ska): need better explanation for this
46 | * MediaKeys
47 | * 1*|
48 | * |
49 | * N*|
50 | * MediaKeySession 1*----1* MediaEngineSession
51 | */
52 |
53 | /* MediaEngineSession is interface only */
54 | class OpenCdmMediaengine {
55 | public:
56 | OpenCdmMediaengine(char *session_id_val, uint32_t session_id_len,
57 | uint8_t * auth_data_val, uint32_t auth_data_len);
58 | virtual ~OpenCdmMediaengine() {
59 | }
60 |
61 | virtual DecryptResponse Decrypt(const uint8_t *pbIv, uint32_t cbIv,
62 | const uint8_t *pbData, uint32_t cbData,
63 | uint8_t *out, uint32_t &out_size) = 0;
64 |
65 | protected:
66 | OpenCdmMediaengine(char *session_id_val, uint32_t session_id_len);
67 | OpenCdmMediaengine() {
68 | }
69 | };
70 |
71 | } // namespace media
72 |
73 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_MEDIAENGINE_OPEN_CDM_MEDIAENGINE_H_
74 |
--------------------------------------------------------------------------------
/docs/build_notes_chromium.md:
--------------------------------------------------------------------------------
1 | # Build notes for Chromium
2 |
3 | Chromium supports three types of CDMs:
4 |
5 | * Internal from source (Clear Key, which is implemented internally by aes_decryptor.cc)
6 | * Pepper-based CDMs (used for desktop and Chrome OS)
7 | * Platform-based (e.g. Android using MediaDrm APIs)
8 |
9 | Source: [David Dorwin, Feb 2014](https://groups.google.com/a/chromium.org/d/msg/chromium-dev/exotX6Nf_z0/UtMi4a2sLncJ)
10 |
11 | ## Pepper Plugin API (PPAPI) integration notes
12 |
13 | *Tested with version:*
14 | MAJOR=37
15 | MINOR=0
16 | BUILD= **2041**
17 | PATCH=6
18 |
19 | ## Configuration
20 |
21 | Make sure to have the following gyp variables set before building.
22 | Easiest way is to place a ```~/.gyp/include.gypi``` with contents:
23 | ```
24 | {
25 | 'variables': {
26 | 'ffmpeg_branding': 'Chrome',
27 | 'proprietary_codecs': 1,
28 | 'enable_pepper_cdms': 1
29 | }
30 | }
31 | ```
32 |
33 | ## Code hooks
34 |
35 | To make the CDM available in the chromium build the key system needs to be
36 | registered in the file ```$CHROMIUM_ROOT/src/chrome/renderer/media/chrome_key_systems.cc```
37 |
38 | Similar as for the function ```AddExternalClearKey``` the new key system needs
39 | to be registered by adding and calling the following function:
40 |
41 | ```
42 | // External Open CDM.
43 | static void AddExternalOpenCdm(
44 | std::vector* concrete_key_systems) {
45 | static const char kExternalOpenCdmKeySystem[] =
46 | "com.opencdm.mockdrm";
47 | static const char kExternalOpenCdmPepperType[] =
48 | "application/x-ppapi-open-cdm";
49 |
50 | std::vector additional_param_names;
51 | std::vector additional_param_values;
52 | if (!IsPepperCdmAvailable(kExternalOpenCdmPepperType,
53 | &additional_param_names,
54 | &additional_param_values)) {
55 | return;
56 | }
57 |
58 | KeySystemInfo info(kExternalOpenCdmKeySystem);
59 |
60 | #if defined(USE_PROPRIETARY_CODECS)
61 | info.supported_codecs |= content::EME_CODEC_MP4_ALL;
62 | #endif // defined(USE_PROPRIETARY_CODECS)
63 |
64 | info.pepper_type = kExternalOpenCdmPepperType;
65 |
66 | concrete_key_systems->push_back(info);
67 | }
68 | ```
69 |
70 | Finally, add the following call into the ```AddChromeKeySystems``` function
71 | subsequent the check if Pepper CDMs are enabled:
72 |
73 | ```
74 | if defined(ENABLE_PEPPER_CDMS)
75 | AddExternalClearKey(key_systems_info);
76 | AddExternalOpenCdm(key_systems_info);
77 | ```
--------------------------------------------------------------------------------
/src/mediaengine/open_cdm_mediaengine_impl.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine_impl.h"
15 | #include "media/cdm/ppapi/external_open_cdm/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h"
16 |
17 | #include "media/cdm/ppapi/cdm_logging.h"
18 |
19 | namespace media {
20 |
21 | OpenCdmMediaengineImpl::OpenCdmMediaengineImpl(char *session_id_val,
22 | uint32_t session_id_len) {
23 | media_engine_com_ = new RpcCdmMediaengineHandler(session_id_val,
24 | session_id_len, 0, 0);
25 | CDM_DLOG() << "Created new media engine impl ";
26 | }
27 |
28 | OpenCdmMediaengineImpl::OpenCdmMediaengineImpl(char *session_id_val,
29 | uint32_t session_id_len,
30 | uint8_t *auth_data_val,
31 | uint32_t auth_data_len) {
32 | // create media engine session
33 | media_engine_com_ = new RpcCdmMediaengineHandler(session_id_val,
34 | session_id_len,
35 | auth_data_val,
36 | auth_data_len);
37 | }
38 |
39 | OpenCdmMediaengineImpl::~OpenCdmMediaengineImpl() {
40 | CDM_DLOG() << "OpenCdmMediaengineImpl destruct!";
41 | }
42 |
43 | DecryptResponse OpenCdmMediaengineImpl::Decrypt(const uint8_t *pbIv,
44 | uint32_t cbIv,
45 | const uint8_t *pbData,
46 | uint32_t cbData, uint8_t *out,
47 | uint32_t &out_size) {
48 | printf("_------ Decrypt \n");
49 | CDM_DLOG() << "OpenCdmMediaengineImpl::Decrypt: ";
50 | DecryptResponse response;
51 |
52 | response = media_engine_com_->Decrypt(pbIv, cbIv, pbData, cbData, out,
53 | out_size);
54 |
55 | return response;
56 | }
57 |
58 | } // namespace media
59 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Fraunhofer FOKUS
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | ---------------------------------------------------------------------------
24 |
25 | Chromium specific parts of the implementation are based on code
26 | contributed to the Chromium project with following copyright notice:
27 |
28 | // Copyright 2014 The Chromium Authors. All rights reserved.
29 | //
30 | // Redistribution and use in source and binary forms, with or without
31 | // modification, are permitted provided that the following conditions are
32 | // met:
33 | //
34 | // * Redistributions of source code must retain the above copyright
35 | // notice, this list of conditions and the following disclaimer.
36 | // * Redistributions in binary form must reproduce the above
37 | // copyright notice, this list of conditions and the following disclaimer
38 | // in the documentation and/or other materials provided with the
39 | // distribution.
40 | // * Neither the name of Google Inc. nor the names of its
41 | // contributors may be used to endorse or promote products derived from
42 | // this software without specific prior written permission.
43 | //
44 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
47 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
48 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform_impl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_IMPL_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_IMPL_H_
16 |
17 | #include
18 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_common.h"
19 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
20 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform.h"
21 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com.h"
22 |
23 | namespace media {
24 |
25 | class OpenCdmPlatformImpl : public OpenCdmPlatform,
26 | public OpenCdmPlatformComCallbackReceiver {
27 | public:
28 | // NEW EME based interface
29 | // on errors tear down media keys and media key session objects
30 |
31 | // EME equivalent: new MediaKeys()
32 | MediaKeysResponse MediaKeys(std::string key_system) override;
33 |
34 | // EME equivalent: media_keys_.createSession()
35 | MediaKeysCreateSessionResponse MediaKeysCreateSession(
36 | const std::string& init_data_type, const uint8_t* init_data,
37 | int init_data_length) override;
38 |
39 | // EME equivalent: media_keys_.loadSession()
40 | MediaKeysLoadSessionResponse MediaKeysLoadSession(
41 | char *session_id_val, uint32_t session_id_len) override;
42 |
43 | // EME equivalent: media_key_session_.update()
44 | MediaKeySessionUpdateResponse MediaKeySessionUpdate(
45 | const uint8 *pbKey, uint32 cbKey, char *session_id_val,
46 | uint32_t session_id_len) override;
47 |
48 | // EME equivalent: media_key_session_.release()
49 | MediaKeySessionReleaseResponse MediaKeySessionRelease(
50 | char *session_id_val, uint32_t session_id_len) override;
51 |
52 | // OpenCdmComCallbackReceiver inheritance
53 | void ErrorCallback(OpenCdmPlatformSessionId platform_session_id,
54 | uint32_t sys_err, std::string err_msg) override;
55 | void MessageCallback(OpenCdmPlatformSessionId platform_session_id,
56 | std::string message,
57 | std::string destination_url) override;
58 | void OnKeyStatusUpdateCallback(OpenCdmPlatformSessionId platform_session_id,
59 | std::string message) override;
60 | void ReadyCallback(OpenCdmPlatformSessionId platform_session_id) override;
61 |
62 | ~OpenCdmPlatformImpl() override {
63 | }
64 | OpenCdmPlatformImpl(
65 | OpenCdmPlatformComCallbackReceiver *callback_receiver);
66 |
67 | private:
68 | OpenCdmPlatformComCallbackReceiver *callback_receiver_;
69 | OpenCdmPlatformCom *com_handler_;
70 | };
71 | } // namespace media
72 |
73 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_CDM_OPEN_CDM_PLATFORM_IMPL_H_
74 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_callback.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Please do not edit this file.
3 | * It was generated using rpcgen.
4 | */
5 |
6 | #ifndef _OPENCDM_CALLBACK_H_RPCGEN
7 | #define _OPENCDM_CALLBACK_H_RPCGEN
8 |
9 | #include
10 |
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 |
17 | struct rpc_cb_message {
18 | struct {
19 | u_int session_id_len;
20 | char *session_id_val;
21 | } session_id;
22 | char *message;
23 | char *destination_url;
24 | };
25 | typedef struct rpc_cb_message rpc_cb_message;
26 |
27 | struct rpc_cb_key_status_update {
28 | struct {
29 | u_int session_id_len;
30 | char *session_id_val;
31 | } session_id;
32 | char *message;
33 | };
34 | typedef struct rpc_cb_key_status_update rpc_cb_key_status_update;
35 |
36 | struct rpc_cb_ready {
37 | struct {
38 | u_int session_id_len;
39 | char *session_id_val;
40 | } session_id;
41 | };
42 | typedef struct rpc_cb_ready rpc_cb_ready;
43 |
44 | struct rpc_cb_error {
45 | struct {
46 | u_int session_id_len;
47 | char *session_id_val;
48 | } session_id;
49 | int error;
50 | char *error_message;
51 | };
52 | typedef struct rpc_cb_error rpc_cb_error;
53 |
54 | #define OPEN_CDM_CALLBACK 0x66666666
55 | #define OPEN_CDM_EME_5 1
56 |
57 | #if defined(__STDC__) || defined(__cplusplus)
58 | #define ON_KEY_MESSAGE 1
59 | extern void * on_key_message_1(rpc_cb_message *, CLIENT *);
60 | extern void * on_key_message_1_svc(rpc_cb_message *, struct svc_req *);
61 | #define ON_KEY_READY 2
62 | extern void * on_key_ready_1(rpc_cb_ready *, CLIENT *);
63 | extern void * on_key_ready_1_svc(rpc_cb_ready *, struct svc_req *);
64 | #define ON_KEY_ERROR 3
65 | extern void * on_key_error_1(rpc_cb_error *, CLIENT *);
66 | extern void * on_key_error_1_svc(rpc_cb_error *, struct svc_req *);
67 | #define ON_KEY_STATUS_UPDATE 4
68 | extern void * on_key_status_update_1(rpc_cb_key_status_update *, CLIENT *);
69 | extern void * on_key_status_update_1_svc(rpc_cb_key_status_update *, struct svc_req *);
70 | extern int open_cdm_callback_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
71 |
72 | #else /* K&R C */
73 | #define ON_KEY_MESSAGE 1
74 | extern void * on_key_message_1();
75 | extern void * on_key_message_1_svc();
76 | #define ON_KEY_READY 2
77 | extern void * on_key_ready_1();
78 | extern void * on_key_ready_1_svc();
79 | #define ON_KEY_ERROR 3
80 | extern void * on_key_error_1();
81 | extern void * on_key_error_1_svc();
82 | #define ON_KEY_STATUS_UPDATE 4
83 | extern void * on_key_status_update_1();
84 | extern void * on_key_status_update_1_svc();
85 | extern int open_cdm_callback_1_freeresult ();
86 | #endif /* K&R C */
87 |
88 | /* the xdr functions */
89 |
90 | #if defined(__STDC__) || defined(__cplusplus)
91 | extern bool_t xdr_rpc_cb_message (XDR *, rpc_cb_message*);
92 | extern bool_t xdr_rpc_cb_key_status_update (XDR *, rpc_cb_key_status_update*);
93 | extern bool_t xdr_rpc_cb_ready (XDR *, rpc_cb_ready*);
94 | extern bool_t xdr_rpc_cb_error (XDR *, rpc_cb_error*);
95 |
96 | #else /* K&R C */
97 | extern bool_t xdr_rpc_cb_message ();
98 | extern bool_t xdr_rpc_cb_key_status_update ();
99 | extern bool_t xdr_rpc_cb_ready ();
100 | extern bool_t xdr_rpc_cb_error ();
101 |
102 | #endif /* K&R C */
103 |
104 | #ifdef __cplusplus
105 | }
106 | #endif
107 |
108 | #endif /* !_OPENCDM_CALLBACK_H_RPCGEN */
109 |
--------------------------------------------------------------------------------
/src/com/cdm/rpc/rpc_cdm_platform_handler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_CDM_RPC_RPC_CDM_PLATFORM_HANDLER_H_
15 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_CDM_RPC_RPC_CDM_PLATFORM_HANDLER_H_
16 |
17 | #include
18 | #include
19 |
20 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_common.h"
21 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com.h"
22 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
23 | #include "media/cdm/ppapi/external_open_cdm/com/common/rpc/opencdm_callback.h"
24 |
25 | namespace media {
26 |
27 | class RpcCdmPlatformHandler : public OpenCdmPlatformCom {
28 | public:
29 | // NEW EME based interface
30 | // on errors tear down media keys and media key session objects
31 |
32 | // EME equivalent: new MediaKeys()
33 | MediaKeysResponse MediaKeys(std::string key_system) override;
34 |
35 | // EME equivalent: media_keys_.createSession()
36 | MediaKeysCreateSessionResponse MediaKeysCreateSession(
37 | const std::string& init_data_type, const uint8_t* init_data,
38 | int init_data_length) override;
39 |
40 | // EME equivalent: media_keys_.loadSession()
41 | MediaKeysLoadSessionResponse MediaKeysLoadSession(
42 | char *session_id_val, uint32_t session_id_len) override;
43 |
44 | // EME equivalent: media_key_session_.update()
45 | MediaKeySessionUpdateResponse MediaKeySessionUpdate(
46 | const uint8 *pbKey, uint32 cbKey, char *session_id_val,
47 | uint32_t session_id_len) override;
48 |
49 | // EME equivalent: media_key_session_.release()
50 | MediaKeySessionReleaseResponse MediaKeySessionRelease(
51 | char *session_id_val, uint32_t session_id_len) override;
52 |
53 | ~RpcCdmPlatformHandler() override {
54 | }
55 | RpcCdmPlatformHandler(OpenCdmPlatformComCallbackReceiver *callback_receiver);
56 |
57 | // RPC specific behavior
58 | static void * DelegateRpcInit(void *call_params);
59 | static void DelegateRpcCallback(struct svc_req *rqstp,
60 | register SVCXPRT *transp);
61 | static void OnMessage1SvcDelegate(rpc_cb_message *kmm,
62 | struct svc_req *rqstp, RpcCdmPlatformHandler *p_instance);
63 | static void OnReady1SvcDelegate(rpc_cb_ready *keyready_param,
64 | struct svc_req *rqstp, RpcCdmPlatformHandler *p_instance);
65 | static void OnError1SvcDelegate(rpc_cb_error *err_param,
66 | struct svc_req *rqstp, RpcCdmPlatformHandler *p_instance);
67 | static void OnKeyStatusUpdate1SvcDelegate(
68 | rpc_cb_key_status_update *kmm, struct svc_req *rqstp,
69 | RpcCdmPlatformHandler *p_instance);
70 |
71 | private:
72 | OpenCdmPlatformComCallbackReceiver *callback_receiver_;
73 | // TODO(ska): remove, when this gets available in callbacks
74 |
75 | void *RpcInitPrivate(void *thread_parm);
76 | void RpcCallbackPrivate(struct svc_req *rqstp, register SVCXPRT *transp);
77 | void OnMessage1Svc(rpc_cb_message *, struct svc_req *);
78 | void OnReady1Svc(rpc_cb_ready *, struct svc_req *);
79 | void OnError1Svc(rpc_cb_error *err_param, struct svc_req *rqstp);
80 |
81 | std::string rpc_server_host;
82 | CLIENT *rpc_client;
83 | int rpc_prog;
84 | };
85 | } // namespace media
86 |
87 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COM_CDM_RPC_RPC_CDM_PLATFORM_HANDLER_H_
88 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_xdr_clnt.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Please do not edit this file.
3 | * It was generated using rpcgen.
4 | */
5 |
6 | #include /* for memset */
7 | #include "opencdm_xdr.h"
8 |
9 | /* Default timeout can be changed using clnt_control() */
10 | static struct timeval TIMEOUT = { 25, 0 };
11 |
12 | rpc_response_generic *
13 | rpc_open_cdm_is_type_supported_1(rpc_request_is_type_supported *argp, CLIENT *clnt)
14 | {
15 | static rpc_response_generic clnt_res;
16 |
17 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
18 | if (clnt_call (clnt, RPC_OPEN_CDM_IS_TYPE_SUPPORTED,
19 | (xdrproc_t) xdr_rpc_request_is_type_supported, (caddr_t) argp,
20 | (xdrproc_t) xdr_rpc_response_generic, (caddr_t) &clnt_res,
21 | TIMEOUT) != RPC_SUCCESS) {
22 | return (NULL);
23 | }
24 | return (&clnt_res);
25 | }
26 |
27 | rpc_response_generic *
28 | rpc_open_cdm_mediakeys_1(rpc_request_mediakeys *argp, CLIENT *clnt)
29 | {
30 | static rpc_response_generic clnt_res;
31 |
32 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
33 | if (clnt_call (clnt, RPC_OPEN_CDM_MEDIAKEYS,
34 | (xdrproc_t) xdr_rpc_request_mediakeys, (caddr_t) argp,
35 | (xdrproc_t) xdr_rpc_response_generic, (caddr_t) &clnt_res,
36 | TIMEOUT) != RPC_SUCCESS) {
37 | return (NULL);
38 | }
39 | return (&clnt_res);
40 | }
41 |
42 | rpc_response_create_session *
43 | rpc_open_cdm_mediakeys_create_session_1(rpc_request_create_session *argp, CLIENT *clnt)
44 | {
45 | static rpc_response_create_session clnt_res;
46 |
47 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
48 | if (clnt_call (clnt, RPC_OPEN_CDM_MEDIAKEYS_CREATE_SESSION,
49 | (xdrproc_t) xdr_rpc_request_create_session, (caddr_t) argp,
50 | (xdrproc_t) xdr_rpc_response_create_session, (caddr_t) &clnt_res,
51 | TIMEOUT) != RPC_SUCCESS) {
52 | return (NULL);
53 | }
54 | return (&clnt_res);
55 | }
56 |
57 | rpc_response_generic *
58 | rpc_open_cdm_mediakeys_load_session_1(rpc_request_load_session *argp, CLIENT *clnt)
59 | {
60 | static rpc_response_generic clnt_res;
61 |
62 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
63 | if (clnt_call (clnt, RPC_OPEN_CDM_MEDIAKEYS_LOAD_SESSION,
64 | (xdrproc_t) xdr_rpc_request_load_session, (caddr_t) argp,
65 | (xdrproc_t) xdr_rpc_response_generic, (caddr_t) &clnt_res,
66 | TIMEOUT) != RPC_SUCCESS) {
67 | return (NULL);
68 | }
69 | return (&clnt_res);
70 | }
71 |
72 | rpc_response_generic *
73 | rpc_open_cdm_mediakeysession_update_1(rpc_request_session_update *argp, CLIENT *clnt)
74 | {
75 | static rpc_response_generic clnt_res;
76 |
77 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
78 | if (clnt_call (clnt, RPC_OPEN_CDM_MEDIAKEYSESSION_UPDATE,
79 | (xdrproc_t) xdr_rpc_request_session_update, (caddr_t) argp,
80 | (xdrproc_t) xdr_rpc_response_generic, (caddr_t) &clnt_res,
81 | TIMEOUT) != RPC_SUCCESS) {
82 | return (NULL);
83 | }
84 | return (&clnt_res);
85 | }
86 |
87 | rpc_response_generic *
88 | rpc_open_cdm_mediakeysession_release_1(rpc_request_session_release *argp, CLIENT *clnt)
89 | {
90 | static rpc_response_generic clnt_res;
91 |
92 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
93 | if (clnt_call (clnt, RPC_OPEN_CDM_MEDIAKEYSESSION_RELEASE,
94 | (xdrproc_t) xdr_rpc_request_session_release, (caddr_t) argp,
95 | (xdrproc_t) xdr_rpc_response_generic, (caddr_t) &clnt_res,
96 | TIMEOUT) != RPC_SUCCESS) {
97 | return (NULL);
98 | }
99 | return (&clnt_res);
100 | }
101 |
102 | rpc_response_generic *
103 | rpc_open_cdm_mediaengine_1(rpc_request_mediaengine_data *argp, CLIENT *clnt)
104 | {
105 | static rpc_response_generic clnt_res;
106 |
107 | memset((char *)&clnt_res, 0, sizeof(clnt_res));
108 | if (clnt_call (clnt, RPC_OPEN_CDM_MEDIAENGINE,
109 | (xdrproc_t) xdr_rpc_request_mediaengine_data, (caddr_t) argp,
110 | (xdrproc_t) xdr_rpc_response_generic, (caddr_t) &clnt_res,
111 | TIMEOUT) != RPC_SUCCESS) {
112 | return (NULL);
113 | }
114 | return (&clnt_res);
115 | }
116 |
--------------------------------------------------------------------------------
/src/cdm/open_cdm_platform_impl.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_impl.h"
15 | #include "media/cdm/ppapi/external_open_cdm/com/cdm/open_cdm_platform_com_handler_factory.h"
16 | #include "media/cdm/ppapi/cdm_logging.h"
17 |
18 | namespace media {
19 |
20 | OpenCdmPlatformImpl::OpenCdmPlatformImpl(
21 | OpenCdmPlatformComCallbackReceiver *callback_receiver)
22 | : callback_receiver_(callback_receiver) {
23 | CDM_DLOG() << "new OpenCdmPlatformCdmiImpl instance";
24 | com_handler_ = OpenCdmPlatformComHandlerFactory::Create(this);
25 | }
26 |
27 | MediaKeysResponse OpenCdmPlatformImpl::MediaKeys(std::string key_system) {
28 | CDM_DLOG() << "OpenCdmPlatformCdmiImpl::MediaKeys";
29 | MediaKeysResponse response = com_handler_->MediaKeys(key_system);
30 |
31 | return response;
32 | }
33 |
34 | MediaKeysCreateSessionResponse OpenCdmPlatformImpl::MediaKeysCreateSession(
35 | const std::string& init_data_type, const uint8_t* init_data,
36 | int init_data_length) {
37 | CDM_DLOG() << "OpenCdmPlatformCdmiImpl::MediaKeysCreateSession";
38 | MediaKeysCreateSessionResponse response;
39 |
40 | response = com_handler_->MediaKeysCreateSession(init_data_type, init_data,
41 | init_data_length);
42 |
43 | return response;
44 | }
45 |
46 | MediaKeysLoadSessionResponse OpenCdmPlatformImpl::MediaKeysLoadSession(
47 | char *session_id_val, uint32_t session_id_len) {
48 | CDM_DLOG() << "OpenCdmPlatformCdmiImpl::MediaKeysLoadSession";
49 | MediaKeysLoadSessionResponse response;
50 |
51 | response = com_handler_->MediaKeysLoadSession(session_id_val, session_id_len);
52 |
53 | return response;
54 | }
55 |
56 | MediaKeySessionUpdateResponse OpenCdmPlatformImpl::MediaKeySessionUpdate(
57 | const uint8 *pbKey, uint32 cbKey, char *session_id_val,
58 | uint32_t session_id_len) {
59 | CDM_DLOG() << "OpenCdmPlatformCdmiImpl::MediaKeySessionUpdate";
60 | MediaKeySessionUpdateResponse response;
61 |
62 | response = com_handler_->MediaKeySessionUpdate(pbKey, cbKey, session_id_val,
63 | session_id_len);
64 |
65 | return response;
66 | }
67 |
68 | MediaKeySessionReleaseResponse OpenCdmPlatformImpl::MediaKeySessionRelease(
69 | char *session_id_val, uint32_t session_id_len) {
70 | CDM_DLOG() << "OpenCdmPlatformCdmiImpl::MediaKeySessionRelease";
71 | MediaKeySessionReleaseResponse response;
72 |
73 | response = com_handler_->MediaKeySessionRelease(session_id_val,
74 | session_id_len);
75 |
76 | return response;
77 | }
78 |
79 | // OpenCdmComCallbackReceiver inheritance
80 | void OpenCdmPlatformImpl::ErrorCallback(
81 | OpenCdmPlatformSessionId platform_session_id, uint32_t sys_err,
82 | std::string err_msg) {
83 | callback_receiver_->ErrorCallback(platform_session_id, sys_err, err_msg);
84 | }
85 |
86 | void OpenCdmPlatformImpl::MessageCallback(
87 | OpenCdmPlatformSessionId platform_session_id, std::string message,
88 | std::string destination_url) {
89 | callback_receiver_->MessageCallback(platform_session_id, message,
90 | destination_url);
91 | }
92 |
93 | void OpenCdmPlatformImpl::OnKeyStatusUpdateCallback(
94 | OpenCdmPlatformSessionId platform_session_id, std::string message
95 | ) {
96 | callback_receiver_->OnKeyStatusUpdateCallback(platform_session_id, message);
97 | }
98 | void OpenCdmPlatformImpl::ReadyCallback(
99 | OpenCdmPlatformSessionId platform_session_id) {
100 | callback_receiver_->ReadyCallback(platform_session_id);
101 | }
102 |
103 | } // namespace media
104 |
--------------------------------------------------------------------------------
/src/com/common/shmemsem/shmemsem_helper.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | /*
15 | * based on Keith Gaughan - Shared Memory and Semaphores - March 22, 2003
16 | */
17 | #include "media/cdm/ppapi/external_open_cdm/com/common/shmemsem/shmemsem_helper.h"
18 |
19 | /**
20 | * Allocates a shared memory segment.
21 | *
22 | * @param n Size (in bytes) of chunk to allocate.
23 | * @return Id of shared memory chunk.
24 | */
25 | int AllocateSharedMemory(int n)
26 | {
27 | assert(n > 0); // Idiot-proof the call.
28 | return shmget(IPC_PRIVATE, n, IPC_CREAT | SHM_R | SHM_W);
29 | }
30 |
31 | /**
32 | * Maps a shared memory segment onto our address space.
33 | *
34 | * @param id Shared memory block to map.
35 | * @return Address of mapped block.
36 | */
37 | void* MapSharedMemory(int id)
38 | {
39 | void* addr;
40 | assert(id != 0); // Idiot-proof the call.
41 | addr = shmat(id, NULL, 0); // Attach the segment...
42 | shmctl(id, IPC_RMID, NULL); // ...and mark it destroyed.
43 | return addr;
44 | }
45 |
46 | /**
47 | * Maps a shared memory segment onto our address space.
48 | *
49 | * @param id Shared memory block to map.
50 | * @param existingAddr Adress of memory block to be shared.
51 | * @return Address of mapped block.
52 | */
53 | void* MapExistingSharedMemory(int id, void* existingAddr)
54 | {
55 | void* addr;
56 | assert(id != 0); // Idiot-proof the call.
57 | addr = shmat(id, existingAddr, 0); // Attach the segment...
58 | shmctl(id, IPC_RMID, NULL); // ...and mark it destroyed.
59 | return addr;
60 | }
61 |
62 | /**
63 | * Detaches a shared memory segment
64 | *
65 | * @param id Shared memory block to map.
66 | * @param existingAddr Adress of memory block to be shared.
67 | * @return Address of mapped block.
68 | */
69 | int DetachExistingSharedMemory(void* existingAddr)
70 | {
71 | int id = shmdt(existingAddr); // Detach the segment...
72 | return id;
73 | }
74 |
75 | /**
76 | * Creates a new semaphore set.
77 | *
78 | * @param n Number of semaphores in set.
79 | * @param vals Default values to start off with.
80 | * @return Id of semaphore set.
81 | */
82 | int CreateSemaphoreSet(int n, unsigned short* vals)
83 | {
84 | union semun arg;
85 | int id;
86 | assert(n > 0); // You need at least one!
87 | assert(vals != NULL); // And they need initialising!
88 | id = semget(IPC_PRIVATE, n, SHM_R | SHM_W);
89 | arg.array = vals;
90 | //int ctl = semctl(id, 0, SETALL, arg);
91 | semctl(id, 0, SETALL, arg);
92 | return id;
93 | }
94 |
95 | /**
96 | * Frees up the given semaphore set.
97 | *
98 | * @param id Id of the semaphore group.
99 | */
100 | void DeleteSemaphoreSet(int id)
101 | {
102 | if (semctl(id, 0, IPC_RMID, 0) == -1)
103 | {
104 | perror("Error releasing semaphore!");
105 | exit(EXIT_FAILURE);
106 | }
107 | }
108 |
109 | /**
110 | * Locks a semaphore within a semaphore set.
111 | *
112 | * @param id Semaphore set it belongs to.
113 | * @param i Actual semaphore to lock.
114 | *
115 | * @note If it’s already locked, you’re put to sleep.
116 | */
117 | void LockSemaphore(int id, int i)
118 | {
119 | struct sembuf sb;
120 | sb.sem_num = i;
121 | sb.sem_op = -1;
122 | sb.sem_flg = SEM_UNDO;
123 | semop(id, &sb, 1);
124 | }
125 |
126 | /**
127 | * Unlocks a semaphore within a semaphore set.
128 | *
129 | * @param id Semaphore set it belongs to.
130 | * @param i Actual semaphore to unlock.
131 | */
132 | void UnlockSemaphore(int id, int i)
133 | {
134 | struct sembuf sb;
135 | sb.sem_num = i;
136 | sb.sem_op = 1;
137 | sb.sem_flg = SEM_UNDO;
138 | semop(id, &sb, 1);
139 | }
140 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_xdr_xdr.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Please do not edit this file.
3 | * It was generated using rpcgen.
4 | */
5 |
6 | #include "opencdm_xdr.h"
7 |
8 | bool_t
9 | xdr_rpc_request_is_type_supported (XDR *xdrs, rpc_request_is_type_supported *objp)
10 | {
11 |
12 | if (!xdr_array (xdrs, (char **)&objp->key_system.key_system_val, (u_int *) &objp->key_system.key_system_len, ~0,
13 | sizeof (char), (xdrproc_t) xdr_char))
14 | return FALSE;
15 | if (!xdr_array (xdrs, (char **)&objp->mime_type.mime_type_val, (u_int *) &objp->mime_type.mime_type_len, ~0,
16 | sizeof (char), (xdrproc_t) xdr_char))
17 | return FALSE;
18 | return TRUE;
19 | }
20 |
21 | bool_t
22 | xdr_rpc_request_mediakeys (XDR *xdrs, rpc_request_mediakeys *objp)
23 | {
24 |
25 | if (!xdr_array (xdrs, (char **)&objp->key_system.key_system_val, (u_int *) &objp->key_system.key_system_len, ~0,
26 | sizeof (char), (xdrproc_t) xdr_char))
27 | return FALSE;
28 | return TRUE;
29 | }
30 |
31 | bool_t
32 | xdr_rpc_request_callback_info (XDR *xdrs, rpc_request_callback_info *objp)
33 | {
34 |
35 | if (!xdr_array (xdrs, (char **)&objp->hostname.hostname_val, (u_int *) &objp->hostname.hostname_len, ~0,
36 | sizeof (char), (xdrproc_t) xdr_char))
37 | return FALSE;
38 | if (!xdr_uint64_t (xdrs, &objp->prog_num))
39 | return FALSE;
40 | if (!xdr_uint32_t (xdrs, &objp->prog_version))
41 | return FALSE;
42 | return TRUE;
43 | }
44 |
45 | bool_t
46 | xdr_rpc_request_create_session (XDR *xdrs, rpc_request_create_session *objp)
47 | {
48 |
49 | if (!xdr_array (xdrs, (char **)&objp->init_data_type.init_data_type_val, (u_int *) &objp->init_data_type.init_data_type_len, ~0,
50 | sizeof (char), (xdrproc_t) xdr_char))
51 | return FALSE;
52 | if (!xdr_array (xdrs, (char **)&objp->init_data.init_data_val, (u_int *) &objp->init_data.init_data_len, ~0,
53 | sizeof (uint8_t), (xdrproc_t) xdr_uint8_t))
54 | return FALSE;
55 | if (!xdr_rpc_request_callback_info (xdrs, &objp->callback_info))
56 | return FALSE;
57 | return TRUE;
58 | }
59 |
60 | bool_t
61 | xdr_rpc_request_load_session (XDR *xdrs, rpc_request_load_session *objp)
62 | {
63 |
64 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
65 | sizeof (char), (xdrproc_t) xdr_char))
66 | return FALSE;
67 | return TRUE;
68 | }
69 |
70 | bool_t
71 | xdr_rpc_request_session_update (XDR *xdrs, rpc_request_session_update *objp)
72 | {
73 |
74 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
75 | sizeof (char), (xdrproc_t) xdr_char))
76 | return FALSE;
77 | if (!xdr_array (xdrs, (char **)&objp->key.key_val, (u_int *) &objp->key.key_len, ~0,
78 | sizeof (uint8_t), (xdrproc_t) xdr_uint8_t))
79 | return FALSE;
80 | return TRUE;
81 | }
82 |
83 | bool_t
84 | xdr_rpc_request_session_release (XDR *xdrs, rpc_request_session_release *objp)
85 | {
86 |
87 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
88 | sizeof (char), (xdrproc_t) xdr_char))
89 | return FALSE;
90 | return TRUE;
91 | }
92 |
93 | bool_t
94 | xdr_rpc_request_mediaengine_data (XDR *xdrs, rpc_request_mediaengine_data *objp)
95 | {
96 |
97 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
98 | sizeof (char), (xdrproc_t) xdr_char))
99 | return FALSE;
100 | if (!xdr_array (xdrs, (char **)&objp->auth_data.auth_data_val, (u_int *) &objp->auth_data.auth_data_len, ~0,
101 | sizeof (uint8_t), (xdrproc_t) xdr_uint8_t))
102 | return FALSE;
103 | if (!xdr_int32_t (xdrs, &objp->id_exchange_shmem))
104 | return FALSE;
105 | if (!xdr_int32_t (xdrs, &objp->id_exchange_sem))
106 | return FALSE;
107 | return TRUE;
108 | }
109 |
110 | bool_t
111 | xdr_rpc_response_generic (XDR *xdrs, rpc_response_generic *objp)
112 | {
113 |
114 | if (!xdr_int (xdrs, &objp->platform_val))
115 | return FALSE;
116 | return TRUE;
117 | }
118 |
119 | bool_t
120 | xdr_rpc_response_create_session (XDR *xdrs, rpc_response_create_session *objp)
121 | {
122 |
123 | if (!xdr_int (xdrs, &objp->platform_val))
124 | return FALSE;
125 | if (!xdr_array (xdrs, (char **)&objp->session_id.session_id_val, (u_int *) &objp->session_id.session_id_len, ~0,
126 | sizeof (char), (xdrproc_t) xdr_char))
127 | return FALSE;
128 | return TRUE;
129 | }
130 |
--------------------------------------------------------------------------------
/docs/architecture_notes_ocdm.md:
--------------------------------------------------------------------------------
1 | # Architecture notes OCDM
2 |
3 | As described in the main [README.md](../README.md) file, the scope of OCDM includes the CDM itself and the communication interfaces for CDM and media engine.
4 |
5 | 
6 |
7 | In order to support multiple browser environments and multiple DRM platforms at the same time the architecture of the OCDM has been designed using three different abstraction layers. This is described in the [3-layer architecture section](#3-layer architecture).
8 |
9 | The architecture can be extended with a CDMi component to allow for an interoperable DRM architecture on platform level as well. There is also a corresponding OCDMi GitHub project available. How OCDM can be used with together with the OCDMi and CDMi compatible DRM systems is described in [CDM and CDMi](#CDM and CDMi).
10 |
11 | ## 3-layer architecture
12 |
13 | Besides the division into the two components, CDM and media engine, OCDM is divided into three logical layers: browser glue, core and communication. The OCDM implementation is strictly bound to these layers by specific interfaces, which enables flexible exchange of a specific layer implementation with another one.
14 |
15 | 
16 |
17 | Within the repository the browser glue code can be found at [src/browser/](../src/browser/). This glue code is used to talk to the component implementations of CDM and media engine. It dependends on the browser-specific EME implementation and might also be the responsible to link the CDM and media engine instance. A PPAPI specific glue implementation for Chromium can be found in the OCDM repositoy at [src/browser/chrome/](../src/browser/chrome/). This implements the Chrome-defined CDM interface and uses the OCDM core CDM component to forward the calls to a proper communication mechanism.
18 | Implementations for other browser environments just need to implement the EME-based interfaces according to their environment and use the core components accordingly.
19 |
20 | The core component implementations are located at [src/cdm/](../src/cdm/) resp. [src/mediaengine/](../src/mediaengine/). Both are implemented to mediate the calls from the browser layer via the communication channel to the DRM platform. If no modifications are necessary to be done at this stage of processing the components can be used and instantiated as is. If a DRM system needs specific modifications the core components can either be exchanged or extended according to the needs.
21 |
22 | The communication mechanisms are encapsulated by a communication interface and placed in [src/com/](../src/com/) for CDM [src/com/cdm/](../src/com/cdm/) and resp. [src/com/mediaengine/](../src/com/mediaengine/). The current OCDM implementation currently supports Unix RPC and shared memory. Other communication implementations can easily be added by using the communication interface without changes in the core layer and browser glue layer.
23 |
24 | ## CDM and CDMi
25 |
26 | Content Decryption Module interface (CDMi) is an open specification that encapsulates DRM platform specific calls with a common interface. As this is an open specified interface, CDM implementations can use it to communicate with any DRM system that exposes a CDMi.
27 |
28 | In addition to the OCDM repository we published a [OCDMi implementation](https://github.com/fraunhoferfokus/open-content-decryption-module-cdmi). The OCDMi can be used to implement an own CDMi-flavoured DRM platform service. It also has a mock implementation that works out of the box in combination with OCDM to demonstrate the usage and encourage own implemenations.
29 |
30 | 
31 |
32 | The OCDMi implementation is designed, similar to the OCDM, using a 3-layer approach but upside down. The communication layer holds CDMi core components that mediate calls to the DRM system glue code layer. For further details please refer to the [OCDMi repository](https://github.com/fraunhoferfokus/open-content-decryption-module-cdmi).
33 |
34 | As shown in the figure above the connection between OCDM and OCDMi works using the communication mechanism in both components. The RPC mechanism used in OCDM is compatible with the RPC interface used by OCDMi. To change the communication mechanism the only change that needs to be done is creating an addditional implementation in the communication layer for both components.
--------------------------------------------------------------------------------
/src/browser/media_open_cdm.gypi:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Fraunhofer FOKUS
3 | #
4 | # Licensed under the MIT License (the "License");
5 | # you may not use this file except in compliance with the License.
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS,
9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | # See the License for the specific language governing permissions and
11 | # limitations under the License.
12 | #
13 |
14 | # Based on file contibuted to the Chromium project
15 | # media/media_cdm.gypi
16 | # License notice of original file:
17 |
18 | # Copyright 2013 The Chromium Authors. All rights reserved.
19 | # Use of this source code is governed by a BSD-style license that can be
20 | # found in the LICENSE file.
21 |
22 | {
23 | 'variables': {
24 | 'conditions': [
25 | ['OS == "android"', {
26 | # Android doesn't use ffmpeg.
27 | 'use_ffmpeg%': 0,
28 | }, { # 'OS != "android"'
29 | 'use_ffmpeg%': 1,
30 | }],
31 | ],
32 | },
33 | 'conditions': [
34 | ['enable_pepper_cdms==1', {
35 | 'targets': [
36 | {
37 | 'target_name': 'opencdm',
38 | 'type': 'none',
39 | 'conditions': [
40 | ['use_ffmpeg == 1' , {
41 | 'defines': ['OCDM_USE_FFMPEG_DECODER', 'CLEAR_KEY_CDM_USE_FFMPEG_DECODER'],
42 | 'dependencies': [
43 | '<(DEPTH)/third_party/ffmpeg/ffmpeg.gyp:ffmpeg',
44 | ],
45 | 'sources': [
46 | '<(DEPTH)/media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.cc',
47 | '<(DEPTH)/media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h',
48 | ],
49 | }],
50 | ['use_ffmpeg == 1' , {
51 | 'sources': [
52 | '<(DEPTH)/media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.cc',
53 | '<(DEPTH)/media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.h',
54 | ],
55 | }],
56 | ['os_posix == 1 and OS != "mac" and enable_pepper_cdms==1', {
57 | 'type': 'loadable_module', # Must be in PRODUCT_DIR for ASAN bot.
58 | }],
59 | ['(OS == "mac" or OS == "win") and enable_pepper_cdms==1', {
60 | 'type': 'shared_library',
61 | }],
62 | ['OS == "mac"', {
63 | 'xcode_settings': {
64 | 'DYLIB_INSTALL_NAME_BASE': '@loader_path',
65 | },
66 | }]
67 | ],
68 | 'defines': ['CDM_IMPLEMENTATION'],
69 | 'dependencies': [
70 | 'media',
71 | '../url/url.gyp:url_lib',
72 | # Include the following for media::AudioBus.
73 | 'shared_memory_support',
74 | '<(DEPTH)/base/base.gyp:base',
75 | ],
76 | 'sources': [
77 | '<(DEPTH)/media/cdm/ppapi/cdm_logging.cc',
78 | '<(DEPTH)/media/cdm/ppapi/cdm_logging.h',
79 | '../com/common/rpc/opencdm_xdr.h',
80 | '../com/common/rpc/opencdm_xdr_clnt.c',
81 | '../com/common/rpc/opencdm_xdr_xdr.c',
82 | '../com/common/rpc/opencdm_callback.h',
83 | '../com/common/rpc/opencdm_callback_xdr.c',
84 | '../cdm/open_cdm_platform_common.h',
85 | '../cdm/open_cdm_platform.h',
86 | '../cdm/open_cdm_platform_com.h',
87 | '../cdm/open_cdm_platform_factory.h',
88 | '../cdm/open_cdm_platform_com_callback_receiver.h',
89 | '../cdm/open_cdm_platform_impl.cc',
90 | '../cdm/open_cdm_platform_impl.h',
91 | '../com/cdm/open_cdm_platform_com_handler_factory.h',
92 | '../com/cdm/rpc/rpc_cdm_platform_handler.h',
93 | '../com/cdm/rpc/rpc_cdm_platform_handler.cc',
94 | '../com/common/shmemsem/shmemsem_helper.cc',
95 | '../com/common/shmemsem/shmemsem_helper.h',
96 | '../mediaengine/open_cdm_mediaengine.h',
97 | '../mediaengine/open_cdm_mediaengine_com.h',
98 | '../mediaengine/open_cdm_mediaengine_factory.h',
99 | '../mediaengine/open_cdm_mediaengine_impl.cc',
100 | '../mediaengine/open_cdm_mediaengine_impl.h',
101 | '../com/mediaengine/rpc/rpc_cdm_mediaengine_handler.cc',
102 | '../com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h',
103 | '../browser/chrome/open_cdm.cc',
104 | '../browser/chrome/open_cdm.h',
105 | '../browser/chrome/open_cdm_chrome_common.h',
106 | '../common/open_cdm_common.h',
107 | '<(DEPTH)/media/cdm/ppapi/external_clear_key/cdm_video_decoder.cc',
108 | '<(DEPTH)/media/cdm/ppapi/external_clear_key/cdm_video_decoder.h',
109 | ],
110 | # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
111 | 'msvs_disabled_warnings': [ 4267, ],
112 | },
113 | {
114 | 'target_name': 'opencdmadapter',
115 | 'type': 'none',
116 | # Check whether the plugin's origin URL is valid.
117 | 'defines': ['CHECK_DOCUMENT_URL'],
118 | 'dependencies': [
119 | '<(DEPTH)/ppapi/ppapi.gyp:ppapi_cpp',
120 | '<(DEPTH)/media/media_cdm_adapter.gyp:cdmadapter',
121 | 'opencdm',
122 | ],
123 | 'conditions': [
124 | ['os_posix == 1 and OS != "mac" and enable_pepper_cdms==1', {
125 | # Because opencdm has type 'loadable_module' (see comments),
126 | # we must explicitly specify this dependency.
127 | 'libraries': [
128 | # Built by opencdm.
129 | '<(PRODUCT_DIR)/libopencdm.so',
130 | ],
131 | }],
132 | ],
133 | },
134 | ],
135 | }],
136 | ],
137 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Open Content Decryption Module
2 |
3 | The Open Content Decryption Module (OCDM) is a Content Decryption Module (CDM) according to W3C EME [1] specification to be used with HTML5 based browser environments and ecosystems [5]. The implementation enables DRM interoperability.
4 | OCDM is built with a modular concept in mind to be easily extendible and flexible. The open source code already provides support for the CDMi specification [4], which essentially requires the CDM to use the operating system's native RPC mechanisms to forward EME calls to the CDMi.
5 | Furthermore, the media sample transmission between a browser decoupled media engine and the CDMi can be secured via a DRM-specific authenticated interface. The CDMi itself contains most CDM logic and is a c++ wrapper for the embedded platform DRM.
6 |
7 | Fraunhofer FOKUS has developed the Open Content Decryption Module (OCDM) according to W3C EME specification to be used with HTML5 based browser environments. The implementation enables DRM interoperability. We would be happy to see a broad adoption of our implementation and encourage contributions. A first e2e implementation has been done testing with a Microsoft PlayReady CDMi implementation.
8 |
9 | ## Introduction / Purpose / Why this?
10 |
11 | * Interoperable HTML5 based protected video delivery
12 | * DRM interoperability
13 | * CENC, DASH
14 | * Plugin based integration (Pepper Plugin API)
15 | * CDMi allows open source browsers to support DRM without licensing it
16 | * e2e tested with Microsoft PlayReady DRM system
17 |
18 | ## Scope
19 |
20 | OCDM is developed according to W3C EME. This leads to a architecture as shown in the figure below, which consists of a Web application, a browser and a DRM platform layer. The browser as mediator between Web application and DRM platform exposes the EME and contains a CDM. The Web application is connected to the browser via EME. EME is mapped by the browser to a CDM and the CDM communicates to the DRM platform.
21 |
22 | As EME is modelling only the license retrieval and management, there is a second component that needs to talk to the DRM platform. In many cases, mainly in embedded environments, the media engine is separate from the browser and used by the browser as external renderer. In this case the media engine probably needs to authenticate itself at the DRM platform for handling and decoding of protected media data.
23 |
24 | 
25 |
26 | On the one hand, the OCDM's scope includes the generic CDM and its communication interfaces to the DRM platform. On the other hand, there are separate media engine communication interfaces to the DRM platform. OCDM contains sample implementations for the RPC communication mechanism, but is designed highly modular to be easily extended with other communication mechanisms.
27 |
28 | For detailed internals of the OCDM architecture please refer to the [architecture notes](./docs/architecture_notes_ocdm.md).
29 |
30 | ## References
31 |
32 | * [1] W3C Encrypted Media Extensions https://w3c.github.io/encrypted-media
33 | * [2] Interoperability Digital Rights Management and the Web https://scrivito-public.s3-eu-west-1.amazonaws.com/fokus/64257f12b90b464b/64a4d370cf46918585d0276caa858eae/FAME_Interoperability_Digital_Rights_Management_and_the_Web_flyer.pdf
34 | * [3] MSE-EME Reference Platform Documentation https://html5.cablelabs.com/mse-eme/doc/overview.html
35 | * [4] Content Decryption Module Interface Specification http://download.microsoft.com/download/E/A/4/EA470677-6C3C-4AFE-8A86-A196ADFD0F78/Content%20Decryption%20Module%20Interface%20Specification.pdf
36 | * [5] Fraunhofer FOKUS FAMIUM DRM http://www.fokus.fraunhofer.de/go/drm
37 |
38 | ## Supported Browsers and Platforms
39 |
40 | Currently OCDM development is compatible with following Web browers:
41 |
42 | * Chromium / CEF
43 | * Linux
44 | * Opera SDK
45 | * Linux
46 |
47 | For more details see the [milestones](https://github.com/fraunhoferfokus/open-content-decryption-module/milestones) page.
48 |
49 | ## How to build
50 |
51 | ### ...as Pepper Plugin for Chromium
52 | * clone this repository, e.g. into $HOME/opencdm
53 | * create the following symbolic link
54 | * ```$ ln -s $HOME/opencdm/src $CHROMIUM_ROOT/src/media/cdm/ppapi/external_open_cdm```
55 | * add include into the ```$CHROMIUM_ROOT/src/media/media.gyp``` file to contain this:
56 | ```
57 | 'includes': [
58 | 'media_cdm.gypi',
59 | './cdm/ppapi/external_open_cdm/browser/media_open_cdm.gypi'
60 | ]
61 | ```
62 | * apply changes by generating the project files
63 | * ```$ cd $CHROMIUM_ROOT/src```
64 | * ```$ build/gyp_chromium```
65 | * build the following target (please follow *[Build notes for Chromium](docs/build_notes_chromium.md)* section before building)
66 | * ```$ ninja -C out/Debug opencdmadapter```
67 |
68 | ## How to run
69 | * integrate OCDM with your browser
70 | * example to be found in src/browser folder
71 | * setup communication to DRM system
72 | * sample code for this is provided in the separate [Open Content Decryption Module CDMi](https://github.com/fraunhoferfokus/open-content-decryption-module-cdmi) repository
73 |
74 | In practice the Pepper Plugin API based OCDM implementation can be launched as follows:
75 |
76 | ```
77 | ./out/Debug/chrome --register-pepper-plugins="out/Debug/libopencdmadapter.so;application/x-ppapi-open-cdm"
78 | ```
79 |
80 | ## Folder Structure
81 |
82 | Navigate the folders and see the readme files for further information.
83 |
84 | ## How to contribute
85 |
86 | See the [wiki](https://github.com/fraunhoferfokus/open-content-decryption-module/wiki) for information on how to contribute to this project.
87 |
88 | ## Known Issues / Comments
89 |
90 | This is a preliminary version of OCDM. Please file any issues or comments.
91 |
92 | * Chromium sandbox: Currently Chromium needs to be started with the --no-sandbox flag because of the current RPC mechanism.
93 | * Multiple session support is current work in progress.
94 | * Code needs more review from the community (e.g. memory allocation, appropriate data types).
95 |
96 | For more details see the [milestones](https://github.com/fraunhoferfokus/open-content-decryption-module/milestones) page.
97 |
--------------------------------------------------------------------------------
/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #include
15 | #include "media/cdm/ppapi/external_open_cdm/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h"
16 | #include "media/cdm/ppapi/cdm_logging.h"
17 | #include "media/cdm/ppapi/external_open_cdm/com/common/rpc/opencdm_xdr.h"
18 |
19 | namespace media {
20 |
21 | std::string rpcServer = "localhost";
22 | // TODO(ska): outsource to config
23 |
24 | RpcCdmMediaengineHandler::RpcCdmMediaengineHandler(char *session_id_val,
25 | uint32_t session_id_len,
26 | uint8_t *auth_data_val,
27 | uint32_t auth_data_len) {
28 | CDM_DLOG() << "RpcCdmMediaengineHandler::RpcCdmMediaengineHandler";
29 |
30 | sessionId.id = new char[session_id_len];
31 | memcpy(sessionId.id, session_id_val, session_id_len);
32 | // TODO(ska): do we need this memcpy?
33 | sessionId.id = session_id_val;
34 | sessionId.idLen = session_id_len;
35 |
36 | if ((rpcClient = clnt_create(rpcServer.c_str(), OPEN_CDM, OPEN_CDM_EME_5,
37 | "tcp")) == NULL) {
38 | clnt_pcreateerror(rpcServer.c_str());
39 | CDM_DLOG() << "rpcclient creation failed: " << rpcServer.c_str();
40 | } else {
41 | CDM_DLOG() << "RpcCdmMediaengineHandler connected to server";
42 | }
43 |
44 | rpc_response_generic *rpc_response;
45 | rpc_request_mediaengine_data rpc_param;
46 | rpc_param.session_id.session_id_val = session_id_val;
47 | rpc_param.session_id.session_id_len = session_id_len;
48 | rpc_param.auth_data.auth_data_val = auth_data_val;
49 | rpc_param.auth_data.auth_data_len = auth_data_len;
50 |
51 | // TODO(ska): need to check == 0?
52 | // if (idXchngShMem == 0) {
53 | idXchngShMem = AllocateSharedMemory(sizeof(shmem_info));
54 | if (idXchngShMem < 0) {
55 | CDM_DLOG() << "idXchngShMem AllocateSharedMemory failed!";
56 | }
57 | // }
58 | shMemInfo = reinterpret_cast(MapSharedMemory(idXchngShMem));
59 |
60 | // SHARED MEMORY and SEMAPHORE INITIALIZATION
61 | shMemInfo->idSidShMem = 0;
62 | this->shMemInfo->idIvShMem = 0;
63 | this->shMemInfo->idSampleShMem = 0;
64 | this->shMemInfo->idSubsampleDataShMem = 0;
65 | this->shMemInfo->sidSize = 1;
66 | this->shMemInfo->ivSize = 2;
67 | this->shMemInfo->sampleSize = 3;
68 | this->shMemInfo->subsampleDataSize = 4;
69 |
70 | unsigned short vals[3];
71 | vals[SEM_XCHNG_PUSH] = 1;
72 | vals[SEM_XCHNG_DECRYPT] = 0;
73 | vals[SEM_XCHNG_PULL] = 0;
74 | // if (idXchngSem == 0) {
75 | idXchngSem = CreateSemaphoreSet(3, vals);
76 | if (idXchngSem < 0) {
77 | CDM_DLOG() << "idXchngSem CreateSemaphoreSet failed!";
78 | }
79 | // }
80 |
81 | rpc_param.id_exchange_shmem = idXchngShMem;
82 | rpc_param.id_exchange_sem = idXchngSem;
83 |
84 | if ((rpc_response = rpc_open_cdm_mediaengine_1(&rpc_param, rpcClient))
85 | == NULL) {
86 | CDM_DLOG() << "engine session failed: " << rpcServer.c_str();
87 | clnt_perror(rpcClient, rpcServer.c_str());
88 | exit(5);
89 | } else {
90 | CDM_DLOG() << "engine session creation called";
91 | }
92 |
93 | CDM_DLOG() << "create media engine session platform response: "
94 | << rpc_response->platform_val;
95 | }
96 |
97 | RpcCdmMediaengineHandler::~RpcCdmMediaengineHandler() {
98 | CDM_DLOG() << "RpcCdmMediaengineHandler destruct!";
99 | // TODO(ska): is shared memory cleaned up correctly?
100 | // DeleteSemaphoreSet(idXchngSem);
101 | idXchngSem = 0;
102 | idXchngShMem = 0;
103 | }
104 |
105 | DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv,
106 | uint32_t cbIv,
107 | const uint8_t *pbData,
108 | uint32_t cbData, uint8_t *out,
109 | uint32_t &out_size) {
110 | printf("Decrypt-------\n");
111 | CDM_DLOG() << "RpcCdmMediaengineHandler::Decrypt: ";
112 | DecryptResponse response;
113 | response.platform_response = PLATFORM_CALL_SUCCESS;
114 | response.sys_err = 0;
115 | // TODO(sph): real decryptresponse values need to
116 | // be written to sharedmem as well
117 |
118 | LockSemaphore(idXchngSem, SEM_XCHNG_PUSH);
119 | CDM_DLOG() << "LOCKed push lock";
120 |
121 | cbIv = (cbIv != 8) ? 8 : cbIv;
122 | shMemInfo->idIvShMem = AllocateSharedMemory(cbIv);
123 | shMemInfo->ivSize = cbIv;
124 |
125 | uint8_t *pIvShMem = reinterpret_cast(MapSharedMemory(
126 | shMemInfo->idIvShMem));
127 | memcpy(pIvShMem, pbIv, cbIv);
128 | // delete[] pbIv;
129 |
130 | shMemInfo->idSampleShMem = AllocateSharedMemory(cbData);
131 | shMemInfo->sampleSize = cbData;
132 | uint8_t *pSampleShMem = reinterpret_cast(MapSharedMemory(
133 | shMemInfo->idSampleShMem));
134 |
135 | memcpy(pSampleShMem, pbData, cbData);
136 | // delete[] pbData;
137 |
138 | shMemInfo->idSubsampleDataShMem = 0;
139 | shMemInfo->subsampleDataSize = 0;
140 | CDM_DLOG() << "data ready to decrypt";
141 | UnlockSemaphore(idXchngSem, SEM_XCHNG_DECRYPT);
142 | CDM_DLOG() << "WAIT for pull lock";
143 | LockSemaphore(idXchngSem, SEM_XCHNG_PULL);
144 | CDM_DLOG() << "LOCKed pull lock";
145 | // process clear data
146 |
147 | memcpy(out, pSampleShMem, cbData);
148 | out_size = cbData;
149 |
150 | CDM_DLOG() << "RUN fired!";
151 | UnlockSemaphore(idXchngSem, SEM_XCHNG_PUSH);
152 | CDM_DLOG() << "UNLOCKed push lock";
153 |
154 | // clean up current shared mems for sample data
155 | int err = DetachExistingSharedMemory(pIvShMem);
156 | CDM_DLOG() << "detached iv shmem " << shMemInfo->idIvShMem << ": " << err;
157 | err = DetachExistingSharedMemory(pSampleShMem);
158 | CDM_DLOG() << "detached sample shmem " << shMemInfo->idSampleShMem << ": "
159 | << err;
160 |
161 | return response;
162 | }
163 |
164 |
165 | } // namespace media
166 |
--------------------------------------------------------------------------------
/src/com/common/rpc/opencdm_xdr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Please do not edit this file.
3 | * It was generated using rpcgen.
4 | */
5 |
6 | #ifndef _OPENCDM_XDR_H_RPCGEN
7 | #define _OPENCDM_XDR_H_RPCGEN
8 |
9 | #include
10 |
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 |
17 | struct rpc_request_is_type_supported {
18 | struct {
19 | u_int key_system_len;
20 | char *key_system_val;
21 | } key_system;
22 | struct {
23 | u_int mime_type_len;
24 | char *mime_type_val;
25 | } mime_type;
26 | };
27 | typedef struct rpc_request_is_type_supported rpc_request_is_type_supported;
28 |
29 | struct rpc_request_mediakeys {
30 | struct {
31 | u_int key_system_len;
32 | char *key_system_val;
33 | } key_system;
34 | };
35 | typedef struct rpc_request_mediakeys rpc_request_mediakeys;
36 |
37 | struct rpc_request_callback_info {
38 | struct {
39 | u_int hostname_len;
40 | char *hostname_val;
41 | } hostname;
42 | uint64_t prog_num;
43 | uint32_t prog_version;
44 | };
45 | typedef struct rpc_request_callback_info rpc_request_callback_info;
46 |
47 | struct rpc_request_create_session {
48 | struct {
49 | u_int init_data_type_len;
50 | char *init_data_type_val;
51 | } init_data_type;
52 | struct {
53 | u_int init_data_len;
54 | uint8_t *init_data_val;
55 | } init_data;
56 | rpc_request_callback_info callback_info;
57 | };
58 | typedef struct rpc_request_create_session rpc_request_create_session;
59 |
60 | struct rpc_request_load_session {
61 | struct {
62 | u_int session_id_len;
63 | char *session_id_val;
64 | } session_id;
65 | };
66 | typedef struct rpc_request_load_session rpc_request_load_session;
67 |
68 | struct rpc_request_session_update {
69 | struct {
70 | u_int session_id_len;
71 | char *session_id_val;
72 | } session_id;
73 | struct {
74 | u_int key_len;
75 | uint8_t *key_val;
76 | } key;
77 | };
78 | typedef struct rpc_request_session_update rpc_request_session_update;
79 |
80 | struct rpc_request_session_release {
81 | struct {
82 | u_int session_id_len;
83 | char *session_id_val;
84 | } session_id;
85 | };
86 | typedef struct rpc_request_session_release rpc_request_session_release;
87 |
88 | struct rpc_request_mediaengine_data {
89 | struct {
90 | u_int session_id_len;
91 | char *session_id_val;
92 | } session_id;
93 | struct {
94 | u_int auth_data_len;
95 | uint8_t *auth_data_val;
96 | } auth_data;
97 | int32_t id_exchange_shmem;
98 | int32_t id_exchange_sem;
99 | };
100 | typedef struct rpc_request_mediaengine_data rpc_request_mediaengine_data;
101 |
102 | struct rpc_response_generic {
103 | int platform_val;
104 | };
105 | typedef struct rpc_response_generic rpc_response_generic;
106 |
107 | struct rpc_response_create_session {
108 | int platform_val;
109 | struct {
110 | u_int session_id_len;
111 | char *session_id_val;
112 | } session_id;
113 | };
114 | typedef struct rpc_response_create_session rpc_response_create_session;
115 |
116 | #define OPEN_CDM 0x61135687
117 | #define OPEN_CDM_EME_5 1
118 |
119 | #if defined(__STDC__) || defined(__cplusplus)
120 | #define RPC_OPEN_CDM_IS_TYPE_SUPPORTED 1
121 | extern rpc_response_generic * rpc_open_cdm_is_type_supported_1(rpc_request_is_type_supported *, CLIENT *);
122 | extern rpc_response_generic * rpc_open_cdm_is_type_supported_1_svc(rpc_request_is_type_supported *, struct svc_req *);
123 | #define RPC_OPEN_CDM_MEDIAKEYS 2
124 | extern rpc_response_generic * rpc_open_cdm_mediakeys_1(rpc_request_mediakeys *, CLIENT *);
125 | extern rpc_response_generic * rpc_open_cdm_mediakeys_1_svc(rpc_request_mediakeys *, struct svc_req *);
126 | #define RPC_OPEN_CDM_MEDIAKEYS_CREATE_SESSION 3
127 | extern rpc_response_create_session * rpc_open_cdm_mediakeys_create_session_1(rpc_request_create_session *, CLIENT *);
128 | extern rpc_response_create_session * rpc_open_cdm_mediakeys_create_session_1_svc(rpc_request_create_session *, struct svc_req *);
129 | #define RPC_OPEN_CDM_MEDIAKEYS_LOAD_SESSION 4
130 | extern rpc_response_generic * rpc_open_cdm_mediakeys_load_session_1(rpc_request_load_session *, CLIENT *);
131 | extern rpc_response_generic * rpc_open_cdm_mediakeys_load_session_1_svc(rpc_request_load_session *, struct svc_req *);
132 | #define RPC_OPEN_CDM_MEDIAKEYSESSION_UPDATE 5
133 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_update_1(rpc_request_session_update *, CLIENT *);
134 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_update_1_svc(rpc_request_session_update *, struct svc_req *);
135 | #define RPC_OPEN_CDM_MEDIAKEYSESSION_RELEASE 6
136 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_release_1(rpc_request_session_release *, CLIENT *);
137 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_release_1_svc(rpc_request_session_release *, struct svc_req *);
138 | #define RPC_OPEN_CDM_MEDIAENGINE 7
139 | extern rpc_response_generic * rpc_open_cdm_mediaengine_1(rpc_request_mediaengine_data *, CLIENT *);
140 | extern rpc_response_generic * rpc_open_cdm_mediaengine_1_svc(rpc_request_mediaengine_data *, struct svc_req *);
141 | extern int open_cdm_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
142 |
143 | #else /* K&R C */
144 | #define RPC_OPEN_CDM_IS_TYPE_SUPPORTED 1
145 | extern rpc_response_generic * rpc_open_cdm_is_type_supported_1();
146 | extern rpc_response_generic * rpc_open_cdm_is_type_supported_1_svc();
147 | #define RPC_OPEN_CDM_MEDIAKEYS 2
148 | extern rpc_response_generic * rpc_open_cdm_mediakeys_1();
149 | extern rpc_response_generic * rpc_open_cdm_mediakeys_1_svc();
150 | #define RPC_OPEN_CDM_MEDIAKEYS_CREATE_SESSION 3
151 | extern rpc_response_create_session * rpc_open_cdm_mediakeys_create_session_1();
152 | extern rpc_response_create_session * rpc_open_cdm_mediakeys_create_session_1_svc();
153 | #define RPC_OPEN_CDM_MEDIAKEYS_LOAD_SESSION 4
154 | extern rpc_response_generic * rpc_open_cdm_mediakeys_load_session_1();
155 | extern rpc_response_generic * rpc_open_cdm_mediakeys_load_session_1_svc();
156 | #define RPC_OPEN_CDM_MEDIAKEYSESSION_UPDATE 5
157 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_update_1();
158 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_update_1_svc();
159 | #define RPC_OPEN_CDM_MEDIAKEYSESSION_RELEASE 6
160 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_release_1();
161 | extern rpc_response_generic * rpc_open_cdm_mediakeysession_release_1_svc();
162 | #define RPC_OPEN_CDM_MEDIAENGINE 7
163 | extern rpc_response_generic * rpc_open_cdm_mediaengine_1();
164 | extern rpc_response_generic * rpc_open_cdm_mediaengine_1_svc();
165 | extern int open_cdm_1_freeresult ();
166 | #endif /* K&R C */
167 |
168 | /* the xdr functions */
169 |
170 | #if defined(__STDC__) || defined(__cplusplus)
171 | extern bool_t xdr_rpc_request_is_type_supported (XDR *, rpc_request_is_type_supported*);
172 | extern bool_t xdr_rpc_request_mediakeys (XDR *, rpc_request_mediakeys*);
173 | extern bool_t xdr_rpc_request_callback_info (XDR *, rpc_request_callback_info*);
174 | extern bool_t xdr_rpc_request_create_session (XDR *, rpc_request_create_session*);
175 | extern bool_t xdr_rpc_request_load_session (XDR *, rpc_request_load_session*);
176 | extern bool_t xdr_rpc_request_session_update (XDR *, rpc_request_session_update*);
177 | extern bool_t xdr_rpc_request_session_release (XDR *, rpc_request_session_release*);
178 | extern bool_t xdr_rpc_request_mediaengine_data (XDR *, rpc_request_mediaengine_data*);
179 | extern bool_t xdr_rpc_response_generic (XDR *, rpc_response_generic*);
180 | extern bool_t xdr_rpc_response_create_session (XDR *, rpc_response_create_session*);
181 |
182 | #else /* K&R C */
183 | extern bool_t xdr_rpc_request_is_type_supported ();
184 | extern bool_t xdr_rpc_request_mediakeys ();
185 | extern bool_t xdr_rpc_request_callback_info ();
186 | extern bool_t xdr_rpc_request_create_session ();
187 | extern bool_t xdr_rpc_request_load_session ();
188 | extern bool_t xdr_rpc_request_session_update ();
189 | extern bool_t xdr_rpc_request_session_release ();
190 | extern bool_t xdr_rpc_request_mediaengine_data ();
191 | extern bool_t xdr_rpc_response_generic ();
192 | extern bool_t xdr_rpc_response_create_session ();
193 |
194 | #endif /* K&R C */
195 |
196 | #ifdef __cplusplus
197 | }
198 | #endif
199 |
200 | #endif /* !_OPENCDM_XDR_H_RPCGEN */
201 |
--------------------------------------------------------------------------------
/src/browser/chrome/open_cdm.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | // Based on file contibuted to the Chromium project
15 | // media/cdm/ppapi/external_clear_key/clear_key_cdm.h
16 | // License notice of original file:
17 |
18 | // Copyright 2013 The Chromium Authors. All rights reserved.
19 | // Use of this source code is governed by a BSD-style license that can be
20 | // found in the LICENSE file.
21 |
22 | #ifndef MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_BROWSER_CHROME_OPEN_CDM_H_
23 | #define MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_BROWSER_CHROME_OPEN_CDM_H_
24 |
25 | #include
26 | #include
27 | #include "base/basictypes.h" // needed for media::MediaKeys::Exception
28 | #include "base/containers/scoped_ptr_hash_map.h"
29 | #include "base/memory/ref_counted.h"
30 | #include "base/memory/scoped_ptr.h"
31 | #include "base/synchronization/lock.h"
32 | #include "media/base/decryptor.h"
33 | #include "media/base/media_export.h"
34 | #include "media/base/media_keys.h"
35 | #include "media/base/decoder_buffer.h"
36 |
37 | #include "media/cdm/ppapi/external_open_cdm/browser/chrome/open_cdm_chrome_common.h"
38 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform.h"
39 | #include "media/cdm/ppapi/external_open_cdm/cdm/open_cdm_platform_com_callback_receiver.h"
40 | #include "media/cdm/ppapi/external_open_cdm/mediaengine/open_cdm_mediaengine.h"
41 |
42 | #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h"
43 | #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.h"
44 | #include "media/cdm/ppapi/external_clear_key/cdm_video_decoder.h"
45 |
46 | #include "map"
47 |
48 | namespace media {
49 |
50 | class OpenCdm : public OpenCdmInterface,
51 | public OpenCdmPlatformComCallbackReceiver {
52 | public:
53 | OpenCdm(OpenCdmHost* host, const std::string& key_system);
54 | ~OpenCdm() override;
55 |
56 | // OpenDecryptor MediaKeys implementation
57 | void Initialize(bool allow_distinctive_identifier,
58 | bool allow_persistent_state) override;
59 | void CreateSessionAndGenerateRequest(uint32 promise_id,
60 | cdm::SessionType session_type,
61 | cdm::InitDataType init_data_type,
62 | const uint8* init_data,
63 | uint32 init_data_size) override;
64 |
65 | void LoadSession(uint32 promise_id,
66 | cdm::SessionType session_type,
67 | const char* web_session_id,
68 | uint32_t web_session_id_length) override;
69 |
70 | void CloseSession(uint32 promise_id,
71 | const char* web_session_id,
72 | uint32_t web_session_id_length) override;
73 |
74 | void UpdateSession(uint32 promise_id,
75 | const char* web_session_id,
76 | uint32_t web_session_id_length,
77 | const uint8* response,
78 | uint32 response_size) override;
79 |
80 | void RemoveSession(uint32 promise_id,
81 | const char* web_session_id,
82 | uint32_t web_session_id_length) override;
83 |
84 | void SetServerCertificate(uint32 promise_id,
85 | const uint8_t* server_certificate_data,
86 | uint32_t server_certificate_data_size)
87 | override;
88 | void TimerExpired(void* context) override;
89 |
90 | cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
91 | cdm::DecryptedBlock* decrypted_block) override;
92 | cdm::Status InitializeAudioDecoder(
93 | const cdm::AudioDecoderConfig& audio_decoder_config) override;
94 | cdm::Status InitializeVideoDecoder(
95 | const cdm::VideoDecoderConfig& video_decoder_config) override;
96 | void DeinitializeDecoder(cdm::StreamType decoder_type) override;
97 | void ResetDecoder(cdm::StreamType decoder_type) override;
98 | cdm::Status DecryptAndDecodeFrame(
99 | const cdm::InputBuffer& encrypted_buffer,
100 | cdm::VideoFrame* me)
101 | override;
102 | cdm::Status DecryptAndDecodeSamples(
103 | const cdm::InputBuffer& encrypted_buffer, cdm::AudioFrames* audio_frames)
104 | override;
105 | void Destroy() override;
106 | void OnPlatformChallengeResponse(
107 | const cdm::PlatformChallengeResponse& response) override;
108 |
109 | void OnQueryOutputProtectionStatus(
110 | cdm::QueryResult result,
111 | uint32_t link_mask,
112 | uint32_t output_protection_mask) override;
113 |
114 | private:
115 | OpenCdmHost* host_;
116 | OpenCdmMediaengine *media_engine_;
117 | scoped_ptr platform_;
118 | std::map session_id_map;
119 |
120 | // Todo: remove this. It is from old CDM
121 | void ReadyCallback(OpenCdmPlatformSessionId platform_session_id) override;
122 |
123 | void ErrorCallback(OpenCdmPlatformSessionId platform_session_id,
124 | uint32_t sys_err, std::string err_msg) override;
125 | void MessageCallback(OpenCdmPlatformSessionId platform_session_id,
126 | std::string message,
127 | std::string destination_url) override;
128 |
129 | void OnKeyStatusUpdateCallback(OpenCdmPlatformSessionId platform_session_id,
130 | std::string message) override;
131 |
132 | // ContentDecryptionModule callbacks.
133 | void OnSessionMessage(const std::string& web_session_id,
134 | MediaKeys::MessageType message_type,
135 | const std::vector& message,
136 | const GURL& legacy_destination_url);
137 |
138 | void OnSessionKeysUpdate(const std::string& web_session_id,
139 | bool has_additional_usable_key,
140 | CdmKeysInfo keys_info);
141 | void OnSessionClosed(const std::string& web_session_id);
142 |
143 | // Handle the success/failure of a promise. These methods are responsible for
144 | // calling |host_| to resolve or reject the promise.
145 | void OnSessionCreated(uint32 promise_id, const std::string& web_session_id);
146 | void OnSessionLoaded(uint32 promise_id, const std::string& web_session_id);
147 | void OnPromiseResolved(uint32 promise_id);
148 | void OnPromiseFailed(uint32 promise_id, MediaKeys::Exception exception_code,
149 | uint32 system_code, const std::string& error_message);
150 |
151 | // Prepares next renewal message and sets a timer for it.
152 | void ScheduleNextRenewal();
153 |
154 |
155 | // Prepares next heartbeat message and sets a timer for it.
156 | void ScheduleNextHeartBeat();
157 |
158 | // Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|.
159 | // Returns cdm::kSuccess if decryption succeeded. The decrypted result is
160 | // put in |decrypted_buffer|. If |encrypted_buffer| is empty, the
161 | // |decrypted_buffer| is set to an empty (EOS) buffer.
162 | // Returns cdm::kNoKey if no decryption key was available. In this case
163 | // |decrypted_buffer| should be ignored by the caller.
164 | // Returns cdm::kDecryptError if any decryption error occurred. In this case
165 | // |decrypted_buffer| should be ignored by the caller.
166 | cdm::Status DecryptToMediaDecoderBuffer(
167 | const cdm::InputBuffer& encrypted_buffer,
168 | scoped_refptr* decrypted_buffer);
169 |
170 | const std::string key_system_;
171 | std::string last_session_id_;
172 | cdm::StreamType last_stream_type_;
173 | cdm::Status audio_decoder_state_;
174 | cdm::Status video_decoder_state_;
175 |
176 | virtual OpenCdmPlatformSessionId GetPlatformSessionId(
177 | const std::string& web_session_id);
178 | virtual std::string GetChromeSessionId(
179 | OpenCdmPlatformSessionId platform_session_id);
180 |
181 | // Timer delay in milliseconds for the next host_->SetTimer() call.
182 | int64 timer_delay_ms_;
183 |
184 | // Indicates whether a renewal timer has been set to prevent multiple timers
185 | // from running.
186 | bool renewal_timer_set_;
187 |
188 | std::string next_renewal_message_;
189 | #if defined(OCDM_USE_FFMPEG_DECODER)
190 | scoped_ptr audio_decoder_;
191 | scoped_ptr video_decoder_;
192 | #endif // OPEN_CDM_USE_FFMPEG_DECODER
193 | };
194 |
195 | } // namespace media
196 |
197 | #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_BROWSER_CHROME_OPEN_CDM_H_
198 |
--------------------------------------------------------------------------------
/src/browser/chrome/tests/ocdm_encrypted_media_istypesupported_browsertest.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | // Based on file contibuted to the Chromium project
15 | // chrome/browser/media/encrypted_media_istypesupported_browsertest.cc
16 | // License notice of original file:
17 |
18 | // Copyright 2013 The Chromium Authors. All rights reserved.
19 | // Use of this source code is governed by a BSD-style license that can be
20 | // found in the LICENSE file.
21 |
22 | #include
23 | #include
24 |
25 | #include "base/base_switches.h"
26 | #include "base/command_line.h"
27 | #include "base/files/file_path.h"
28 | #include "base/path_service.h"
29 | #include "base/strings/utf_string_conversions.h"
30 | #include "chrome/browser/ui/browser.h"
31 | #include "chrome/browser/ui/tabs/tab_strip_model.h"
32 | #include "chrome/common/chrome_paths.h"
33 | #include "chrome/test/base/in_process_browser_test.h"
34 | #include "chrome/test/base/ui_test_utils.h"
35 | #include "content/public/common/content_switches.h"
36 | #include "content/public/test/browser_test_utils.h"
37 | #include "url/gurl.h"
38 |
39 | #if defined(OS_ANDROID)
40 | #error This file needs to be updated to run on Android.
41 | #endif
42 |
43 | #if defined(USE_PROPRIETARY_CODECS)
44 | #define EXPECT_PROPRIETARY EXPECT_TRUE
45 | #else
46 | #define EXPECT_PROPRIETARY EXPECT_FALSE
47 | #endif
48 |
49 | // Expectations for OpenCDM.
50 | #define EXPECT_OCDM EXPECT_TRUE
51 | #define EXPECT_OCDMPROPRIETARY EXPECT_PROPRIETARY
52 |
53 | namespace chrome {
54 |
55 | #if defined(ENABLE_PEPPER_CDMS)
56 |
57 | const char kOpenCDM[] = "com.opencdm.mockdrm";
58 | const char kOpenCDMParentOnly[] = "com.opencdm";
59 | const char kOpenCDMParentOnlyPeriod[] = "com.opencdm.";
60 | const char kOpenCDMTldPeriod[] = "com.";
61 | const char kOpenCDMTld[] = "com";
62 | const char kOpenCDMCaseSensitive[] = "com.opencdm.MoCkDrM";
63 | const char kOpenCDMNonExisting[] = "com.opencdm.foo";
64 | const char kOpenCDMChild[] = "com.opencdm.mockdrm.foo";
65 | const char kOpenCDMExtraChar[] = "com.opencdm.mockdrmZ";
66 | const char kOpenCDMLessChar[] = "com.opencdm.mockdr";
67 | const char kPepperTypeForKeySystem[] = "application/x-ppapi-open-cdm";
68 | const char kFilePathLiteral[] = "#OpenCDM#1.0.0.0;";
69 |
70 | // TODO(xhwang): Simplify this test! See http://crbug.com/367158
71 |
72 | class OpenCDMEncryptedMediaIsTypeSupportedBaseTest :
73 | public InProcessBrowserTest {
74 | protected:
75 | OpenCDMEncryptedMediaIsTypeSupportedBaseTest()
76 | : is_test_page_loaded_(false), is_pepper_cdm_registered_(false) {
77 | vp8_codec_.push_back("vp8");
78 |
79 | vp80_codec_.push_back("vp8.0");
80 |
81 | vp9_codec_.push_back("vp9");
82 |
83 | vp90_codec_.push_back("vp9.0");
84 |
85 | vorbis_codec_.push_back("vorbis");
86 |
87 | vp8_and_vorbis_codecs_.push_back("vp8");
88 | vp8_and_vorbis_codecs_.push_back("vorbis");
89 |
90 | vp9_and_vorbis_codecs_.push_back("vp9");
91 | vp9_and_vorbis_codecs_.push_back("vorbis");
92 |
93 | avc1_codec_.push_back("avc1");
94 |
95 | avc1_extended_codec_.push_back("avc1.4D400C");
96 |
97 | avc1_dot_codec_.push_back("avc1.");
98 |
99 | avc2_codec_.push_back("avc2");
100 |
101 | avc3_codec_.push_back("avc3");
102 |
103 | avc3_extended_codec_.push_back("avc3.64001f");
104 |
105 | aac_codec_.push_back("mp4a");
106 |
107 | avc1_and_aac_codecs_.push_back("avc1");
108 | avc1_and_aac_codecs_.push_back("mp4a");
109 |
110 | unknown_codec_.push_back("foo");
111 |
112 | mixed_codecs_.push_back("vorbis");
113 | mixed_codecs_.push_back("avc1");
114 | }
115 |
116 | typedef std::vector CodecVector;
117 |
118 | const CodecVector& no_codecs() const { return no_codecs_; }
119 | const CodecVector& vp8_codec() const { return vp8_codec_; }
120 | const CodecVector& vp80_codec() const { return vp80_codec_; }
121 | const CodecVector& vp9_codec() const { return vp9_codec_; }
122 | const CodecVector& vp90_codec() const { return vp90_codec_; }
123 | const CodecVector& vorbis_codec() const { return vorbis_codec_; }
124 | const CodecVector& vp8_and_vorbis_codecs() const {
125 | return vp8_and_vorbis_codecs_;
126 | }
127 | const CodecVector& vp9_and_vorbis_codecs() const {
128 | return vp9_and_vorbis_codecs_;
129 | }
130 | const CodecVector& avc1_codec() const { return avc1_codec_; }
131 | const CodecVector& avc1_extended_codec() const {
132 | return avc1_extended_codec_;
133 | }
134 | const CodecVector& avc1_dot_codec() const { return avc1_dot_codec_; }
135 | const CodecVector& avc2_codec() const { return avc2_codec_; }
136 | const CodecVector& avc3_codec() const { return avc3_codec_; }
137 | const CodecVector& avc3_extended_codec() const {
138 | return avc3_extended_codec_;
139 | }
140 | const CodecVector& aac_codec() const { return aac_codec_; }
141 | const CodecVector& avc1_and_aac_codecs() const {
142 | return avc1_and_aac_codecs_;
143 | }
144 | const CodecVector& unknown_codec() const { return unknown_codec_; }
145 | const CodecVector& mixed_codecs() const { return mixed_codecs_; }
146 |
147 | // Update the command line to load |adapter_name| for
148 | // |pepper_type_for_key_system|.
149 | void RegisterPepperCdm(CommandLine* command_line,
150 | const std::string& adapter_name,
151 | const std::string& pepper_type_for_key_system,
152 | bool expect_adapter_exists = true) {
153 | DCHECK(!is_pepper_cdm_registered_)
154 | << "RegisterPepperCdm() can only be called once.";
155 | is_pepper_cdm_registered_ = true;
156 |
157 | // Append the switch to register the appropriate adapter.
158 | base::FilePath plugin_dir;
159 | EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
160 | base::FilePath plugin_lib = plugin_dir.AppendASCII(adapter_name);
161 | EXPECT_EQ(expect_adapter_exists, base::PathExists(plugin_lib));
162 | base::FilePath::StringType pepper_plugin = plugin_lib.value();
163 | pepper_plugin.append(FILE_PATH_LITERAL(kFilePathLiteral));
164 | #if defined(OS_WIN)
165 | pepper_plugin.append(base::ASCIIToWide(pepper_type_for_key_system));
166 | #else
167 | pepper_plugin.append(pepper_type_for_key_system);
168 | #endif
169 | command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
170 | pepper_plugin);
171 | // TODO(mla): remove after communication to cdmi is possible
172 | // from within the sandbox
173 | command_line->AppendSwitch(switches::kNoSandbox);
174 | // TODO(mla): swich needed until unprefixed EME version available
175 | command_line->AppendSwitch(switches::kEnableEncryptedMedia);
176 | }
177 |
178 | void LoadTestPage() {
179 | // Load the test page needed. IsConcreteSupportedKeySystem() needs some
180 | // JavaScript and a video loaded in order to work.
181 | if (!is_test_page_loaded_) {
182 | ASSERT_TRUE(test_server()->Start());
183 | GURL gurl = test_server()->GetURL(
184 | "files/media/drmock/test.html");
185 | ui_test_utils::NavigateToURL(browser(), gurl);
186 | is_test_page_loaded_ = true;
187 | }
188 | }
189 |
190 | bool IsConcreteSupportedKeySystem(const std::string& key) {
191 | std::string command(
192 | "window.domAutomationController.send(MediaKeys_isTypeSupported('");
193 | command.append(key);
194 | command.append("'));");
195 |
196 | // testKeySystemInstantiation() is a JavaScript function which needs to
197 | // be loaded.
198 | LoadTestPage();
199 |
200 | std::string result;
201 | EXPECT_TRUE(content::ExecuteScriptAndExtractString(
202 | browser()->tab_strip_model()->GetActiveWebContents(),
203 | command,
204 | &result));
205 | CHECK(result == "success" || result == "NotSupportedError") << result;
206 | return (result == "success");
207 | }
208 |
209 | bool IsSupportedKeySystemWithMediaMimeType(const std::string& type,
210 | const CodecVector& codecs,
211 | const std::string& keySystem) {
212 | std::string command("document.createElement('video').canPlayType(");
213 | if (type.empty()) {
214 | // Simple case, pass "null" as first argument.
215 | command.append("null");
216 | DCHECK(codecs.empty());
217 | } else {
218 | command.append("'");
219 | command.append(type);
220 | if (!codecs.empty()) {
221 | command.append("; codecs=\"");
222 | for (CodecVector::const_iterator it = codecs.begin();
223 | it != codecs.end();
224 | ++it) {
225 | command.append(*it);
226 | command.append(",");
227 | }
228 | command.replace(command.length() - 1, 1, "\"");
229 | }
230 | command.append("'");
231 | }
232 | command.append(",'");
233 | command.append(keySystem);
234 | command.append("')");
235 |
236 | std::string result;
237 | EXPECT_TRUE(content::ExecuteScriptAndExtractString(
238 | browser()->tab_strip_model()->GetActiveWebContents(),
239 | "window.domAutomationController.send(" + command + ");",
240 | &result));
241 | return (result == "maybe" || result == "probably");
242 | }
243 |
244 | private:
245 | const CodecVector no_codecs_;
246 | CodecVector vp8_codec_;
247 | CodecVector vp80_codec_;
248 | CodecVector vp9_codec_;
249 | CodecVector vp90_codec_;
250 | CodecVector vorbis_codec_;
251 | CodecVector vp8_and_vorbis_codecs_;
252 | CodecVector vp9_and_vorbis_codecs_;
253 | CodecVector avc1_codec_;
254 | CodecVector avc1_extended_codec_;
255 | CodecVector avc1_dot_codec_;
256 | CodecVector avc2_codec_;
257 | CodecVector avc3_codec_;
258 | CodecVector avc3_extended_codec_;
259 | CodecVector aac_codec_;
260 | CodecVector avc1_and_aac_codecs_;
261 | CodecVector unknown_codec_;
262 | CodecVector mixed_codecs_;
263 | bool is_test_page_loaded_;
264 | bool is_pepper_cdm_registered_;
265 | };
266 |
267 | // For PPAPI OpenCDM tests, ensure that the OpenCDM adapter is loaded.
268 | class OpenCDMEncryptedMediaIsTypeSupportedTest
269 | : public OpenCDMEncryptedMediaIsTypeSupportedBaseTest {
270 |
271 | protected:
272 | virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
273 | // Platform-specific filename relative to the chrome executable.
274 | const char adapter_file_name[] =
275 | #if defined(OS_MACOSX)
276 | "opencdmadapter.plugin";
277 | #elif defined(OS_WIN)
278 | "opencdmadapter.dll";
279 | #elif defined(OS_POSIX)
280 | "libopencdmadapter.so";
281 | #endif
282 |
283 | const std::string pepper_name(kPepperTypeForKeySystem);
284 | RegisterPepperCdm(command_line, adapter_file_name, pepper_name);
285 | }
286 |
287 | };
288 |
289 | // Registers OpenCDM with the wrong path (filename).
290 | class OpenCDMEncryptedMediaIsTypeSupportedRegisteredWithWrongPathTest
291 | : public OpenCDMEncryptedMediaIsTypeSupportedBaseTest {
292 | protected:
293 | virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
294 | RegisterPepperCdm(command_line,
295 | "libopencdmadapterwrongname.so",
296 | kPepperTypeForKeySystem,
297 | false);
298 | }
299 | };
300 |
301 | //
302 | // OpenCDM Tests
303 | //
304 |
305 | // When defined(ENABLE_PEPPER_CDMS), this also tests the Pepper CDM check.
306 | IN_PROC_BROWSER_TEST_F(OpenCDMEncryptedMediaIsTypeSupportedTest,
307 | OpenCDM_Basic) {
308 | EXPECT_OCDM(IsConcreteSupportedKeySystem(kOpenCDM));
309 | EXPECT_OCDM(IsSupportedKeySystemWithMediaMimeType(
310 | "video/mp4", no_codecs(), kOpenCDM));
311 | }
312 |
313 | IN_PROC_BROWSER_TEST_F(OpenCDMEncryptedMediaIsTypeSupportedTest,
314 | OpenCDM_Parent) {
315 | // The parent should be supported but is not. See http://crbug.com/164303.
316 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMParentOnly));
317 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
318 | "video/mp4", no_codecs(), kOpenCDMParentOnly));
319 | }
320 |
321 | IN_PROC_BROWSER_TEST_F(OpenCDMEncryptedMediaIsTypeSupportedTest,
322 | OpenCDM_IsSupportedKeySystem_InvalidVariants) {
323 | // Case sensitive.
324 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMCaseSensitive));
325 | // This should fail, but currently canPlayType() converts it to lowercase.
326 | // See http://crbug.com/286036.
327 | EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
328 | "video/mp4", no_codecs(), kOpenCDMCaseSensitive));
329 |
330 | // TLDs are not allowed.
331 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMTldPeriod));
332 | EXPECT_FALSE(
333 | IsSupportedKeySystemWithMediaMimeType("video/mp4", no_codecs(), kOpenCDMTldPeriod));
334 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMTld));
335 | EXPECT_FALSE(
336 | IsSupportedKeySystemWithMediaMimeType("video/mp4", no_codecs(), kOpenCDMTld));
337 |
338 | // Extra period.
339 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMParentOnlyPeriod));
340 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
341 | "video/mp4", no_codecs(), kOpenCDMParentOnlyPeriod));
342 |
343 | // Incomplete.
344 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMLessChar));
345 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
346 | "video/mp4", no_codecs(), kOpenCDMLessChar));
347 |
348 | // Extra character.
349 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDMExtraChar));
350 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
351 | "video/mp4", no_codecs(), kOpenCDMExtraChar));
352 |
353 | // There are no child key systems for OpenCDM.
354 | EXPECT_FALSE(
355 | IsConcreteSupportedKeySystem(kOpenCDMChild));
356 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
357 | "video/mp4", no_codecs(), kOpenCDMChild));
358 | }
359 |
360 | IN_PROC_BROWSER_TEST_F(
361 | OpenCDMEncryptedMediaIsTypeSupportedTest,
362 | IsSupportedKeySystemWithMediaMimeType_OpenCDM_NoType) {
363 | // These two should be true. See http://crbug.com/164303.
364 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
365 | std::string(), no_codecs(), kOpenCDM));
366 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
367 | std::string(), no_codecs(), kOpenCDMParentOnly));
368 |
369 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
370 | std::string(), no_codecs(), kOpenCDMNonExisting));
371 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
372 | std::string(), no_codecs(), kOpenCDMChild));
373 | }
374 |
375 | IN_PROC_BROWSER_TEST_F(
376 | OpenCDMEncryptedMediaIsTypeSupportedTest,
377 | IsSupportedKeySystemWithMediaMimeType_OpenCDM_MP4) {
378 | // Valid video types.
379 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
380 | "video/mp4", no_codecs(), kOpenCDM));
381 | // The parent should be supported but is not. See http://crbug.com/164303.
382 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
383 | "video/mp4", no_codecs(), kOpenCDMParentOnly));
384 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
385 | "video/mp4", avc1_codec(), kOpenCDM));
386 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
387 | "video/mp4", avc1_and_aac_codecs(), kOpenCDM));
388 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
389 | "video/mp4", avc3_codec(), kOpenCDM));
390 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
391 | "video/mp4", aac_codec(), kOpenCDM));
392 |
393 | // Extended codecs.
394 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
395 | "video/mp4", avc1_extended_codec(), kOpenCDM));
396 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
397 | "video/mp4", avc3_extended_codec(), kOpenCDM));
398 |
399 | // Invalid codec format, but canPlayType() strips away the period.
400 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
401 | "video/mp4", avc1_dot_codec(), kOpenCDM));
402 |
403 | // Non-MP4 codecs.
404 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
405 | "video/mp4", avc2_codec(), kOpenCDM));
406 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
407 | "video/mp4", vp8_codec(), kOpenCDM));
408 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
409 | "video/mp4", unknown_codec(), kOpenCDM));
410 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
411 | "video/mp4", mixed_codecs(), kOpenCDM));
412 |
413 | // Valid audio types.
414 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
415 | "audio/mp4", no_codecs(), kOpenCDM));
416 | EXPECT_OCDMPROPRIETARY(IsSupportedKeySystemWithMediaMimeType(
417 | "audio/mp4", aac_codec(), kOpenCDM));
418 |
419 | // Non-audio codecs.
420 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
421 | "audio/mp4", avc1_codec(), kOpenCDM));
422 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
423 | "audio/mp4", avc1_and_aac_codecs(), kOpenCDM));
424 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
425 | "audio/mp4", avc3_codec(), kOpenCDM));
426 |
427 | // Non-MP4 codec.
428 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
429 | "audio/mp4", vorbis_codec(), kOpenCDM));
430 | }
431 |
432 |
433 | // Since this test fixture does not register the CDMs on the command line, the
434 | // check for the CDMs in chrome_key_systems.cc should fail, and they should not
435 | // be registered with KeySystems.
436 | IN_PROC_BROWSER_TEST_F(OpenCDMEncryptedMediaIsTypeSupportedBaseTest,
437 | PepperCDMsNotRegistered) {
438 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDM));
439 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
440 | "video/mp4", no_codecs(), kOpenCDM));
441 | }
442 |
443 | // Since this test fixture does not register the CDMs on the command line, the
444 | // check for the CDMs in chrome_key_systems.cc should fail, and they should not
445 | // be registered with KeySystems.
446 | IN_PROC_BROWSER_TEST_F(
447 | OpenCDMEncryptedMediaIsTypeSupportedRegisteredWithWrongPathTest,
448 | PepperCDMsRegisteredButAdapterNotPresent) {
449 | EXPECT_FALSE(IsConcreteSupportedKeySystem(kOpenCDM));
450 | EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
451 | "video/mp4", no_codecs(), kOpenCDM));
452 | }
453 |
454 | #endif // defined(ENABLE_PEPPER_CDMS)
455 |
456 | } // namespace chrome
457 |
--------------------------------------------------------------------------------
/src/com/cdm/rpc/rpc_cdm_platform_handler.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Fraunhofer FOKUS
3 | *
4 | * Licensed under the MIT License (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | #include
15 | #include
16 | #include