summaryrefslogtreecommitdiffstats
path: root/webkit/media/crypto/ppapi/clear_key_cdm.h
blob: e5a6cc719653d208c86e9142f1665b3548376df2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WEBKIT_MEDIA_CRYPTO_PPAPI_CLEAR_KEY_CDM_H_
#define WEBKIT_MEDIA_CRYPTO_PPAPI_CLEAR_KEY_CDM_H_

#include <string>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "media/base/decryptor_client.h"
#include "media/crypto/aes_decryptor.h"
#include "webkit/media/crypto/ppapi/content_decryption_module.h"

// Enable this to use the fake decoder for testing.
// #define CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER

#if defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER)
#undef CLEAR_KEY_CDM_USE_FFMPEG_DECODER
#endif

namespace media {
class DecoderBuffer;
}

namespace webkit_media {

class FFmpegCdmVideoDecoder;

// Clear key implementation of the cdm::ContentDecryptionModule interface.
class ClearKeyCdm : public cdm::ContentDecryptionModule {
 public:
  explicit ClearKeyCdm(cdm::Allocator* allocator, cdm::CdmHost*);
  virtual ~ClearKeyCdm();

  // ContentDecryptionModule implementation.
  virtual cdm::Status GenerateKeyRequest(
      const uint8_t* init_data,
      int init_data_size,
      cdm::KeyMessage* key_request) OVERRIDE;
  virtual cdm::Status AddKey(const char* session_id,
                             int session_id_size,
                             const uint8_t* key,
                             int key_size,
                             const uint8_t* key_id,
                             int key_id_size) OVERRIDE;
  virtual cdm::Status CancelKeyRequest(const char* session_id,
                                       int session_id_size) OVERRIDE;
  virtual void TimerExpired(cdm::KeyMessage* msg, bool* populated) OVERRIDE;
  virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
                              cdm::DecryptedBlock* decrypted_block) OVERRIDE;
  virtual cdm::Status InitializeAudioDecoder(
      const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE;
  virtual cdm::Status InitializeVideoDecoder(
      const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE;
  virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE;
  virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE;
  virtual cdm::Status DecryptAndDecodeFrame(
      const cdm::InputBuffer& encrypted_buffer,
      cdm::VideoFrame* video_frame) OVERRIDE;
  virtual cdm::Status DecryptAndDecodeSamples(
      const cdm::InputBuffer& encrypted_buffer,
      cdm::Buffer* sample_buffer) OVERRIDE;

 private:
  class Client : public media::DecryptorClient {
   public:
    enum Status {
      kKeyAdded,
      kKeyError,
      kKeyMessage,
      kNeedKey
    };

    Client();
    virtual ~Client();

    Status status() { return status_; }
    const std::string& session_id() { return session_id_; }
    const uint8* key_message() { return key_message_.get(); }
    int key_message_length() { return key_message_length_; }
    const std::string& default_url() { return default_url_; }

    // Resets the Client to a clean state.
    void Reset();

    // media::DecryptorClient implementation.
    virtual void KeyAdded(const std::string& key_system,
                          const std::string& session_id) OVERRIDE;
    virtual void KeyError(const std::string& key_system,
                          const std::string& session_id,
                          media::Decryptor::KeyError error_code,
                          int system_code) OVERRIDE;
    virtual void KeyMessage(const std::string& key_system,
                            const std::string& session_id,
                            scoped_array<uint8> message,
                            int message_length,
                            const std::string& default_url) OVERRIDE;
    virtual void NeedKey(const std::string& key_system,
                         const std::string& session_id,
                         scoped_array<uint8> init_data,
                         int init_data_length) OVERRIDE;

   private:
    Status status_;
    std::string session_id_;
    scoped_array<uint8> key_message_;
    int key_message_length_;
    std::string default_url_;
  };

#if defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER)
  void GenerateFakeVideoFrame(base::TimeDelta timestamp,
                              cdm::VideoFrame* video_frame);
#endif  // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER

  Client client_;
  media::AesDecryptor decryptor_;

  // Protects the |client_| from being accessed by the |decryptor_|
  // simultaneously.
  base::Lock client_lock_;

  cdm::Allocator* const allocator_;

#if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
  scoped_ptr<FFmpegCdmVideoDecoder> video_decoder_;
#endif

#if defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER)
  cdm::Size video_size_;
#endif  // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER
};

}  // namespace webkit_media

#endif  // WEBKIT_MEDIA_CRYPTO_PPAPI_CLEAR_KEY_CDM_H_