Skip to content

Commit b3e2e24

Browse files
theandi666Android (Google) Code Review
authored andcommitted
Merge "Provisional support for secure decryption of media streams."
2 parents 61bf874 + 9b8e496 commit b3e2e24

32 files changed

+940
-39
lines changed

cmds/stagefright/codec.cpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <media/stagefright/foundation/AMessage.h>
2929
#include <media/stagefright/DataSource.h>
3030
#include <media/stagefright/MediaCodec.h>
31+
#include <media/stagefright/MediaCodecList.h>
3132
#include <media/stagefright/MediaDefs.h>
3233
#include <media/stagefright/NuMediaExtractor.h>
3334
#include <gui/SurfaceComposerClient.h>
@@ -36,7 +37,9 @@ static void usage(const char *me) {
3637
fprintf(stderr, "usage: %s [-a] use audio\n"
3738
"\t\t[-v] use video\n"
3839
"\t\t[-p] playback\n"
39-
"\t\t[-S] allocate buffers from a surface\n", me);
40+
"\t\t[-S] allocate buffers from a surface\n"
41+
"\t\t[-D] decrypt input buffers\n",
42+
me);
4043

4144
exit(1);
4245
}
@@ -63,7 +66,8 @@ static int decode(
6366
const char *path,
6467
bool useAudio,
6568
bool useVideo,
66-
const android::sp<android::Surface> &surface) {
69+
const android::sp<android::Surface> &surface,
70+
bool decryptInputBuffers) {
6771
using namespace android;
6872

6973
static int64_t kTimeout = 500ll;
@@ -109,13 +113,31 @@ static int decode(
109113
state->mNumBuffersDecoded = 0;
110114
state->mIsAudio = isAudio;
111115

112-
state->mCodec = MediaCodec::CreateByType(
113-
looper, mime.c_str(), false /* encoder */);
116+
if (decryptInputBuffers && !isAudio) {
117+
static const MediaCodecList *list = MediaCodecList::getInstance();
118+
119+
ssize_t index =
120+
list->findCodecByType(mime.c_str(), false /* encoder */);
121+
122+
CHECK_GE(index, 0);
123+
124+
const char *componentName = list->getCodecName(index);
125+
126+
AString fullName = componentName;
127+
fullName.append(".secure");
128+
129+
state->mCodec = MediaCodec::CreateByComponentName(
130+
looper, fullName.c_str());
131+
} else {
132+
state->mCodec = MediaCodec::CreateByType(
133+
looper, mime.c_str(), false /* encoder */);
134+
}
114135

115136
CHECK(state->mCodec != NULL);
116137

117138
err = state->mCodec->configure(
118-
format, isVideo ? surface : NULL, 0 /* flags */);
139+
format, isVideo ? surface : NULL,
140+
decryptInputBuffers ? MediaCodec::CONFIGURE_FLAG_SECURE : 0);
119141

120142
CHECK_EQ(err, (status_t)OK);
121143

@@ -202,12 +224,24 @@ static int decode(
202224
err = extractor->getSampleTime(&timeUs);
203225
CHECK_EQ(err, (status_t)OK);
204226

227+
uint32_t bufferFlags = 0;
228+
229+
uint32_t sampleFlags;
230+
err = extractor->getSampleFlags(&sampleFlags);
231+
CHECK_EQ(err, (status_t)OK);
232+
233+
if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) {
234+
CHECK(decryptInputBuffers);
235+
236+
bufferFlags |= MediaCodec::BUFFER_FLAG_ENCRYPTED;
237+
}
238+
205239
err = state->mCodec->queueInputBuffer(
206240
index,
207241
0 /* offset */,
208242
buffer->size(),
209243
timeUs,
210-
0 /* flags */);
244+
bufferFlags);
211245

212246
CHECK_EQ(err, (status_t)OK);
213247

@@ -341,9 +375,10 @@ int main(int argc, char **argv) {
341375
bool useVideo = false;
342376
bool playback = false;
343377
bool useSurface = false;
378+
bool decryptInputBuffers = false;
344379

345380
int res;
346-
while ((res = getopt(argc, argv, "havpS")) >= 0) {
381+
while ((res = getopt(argc, argv, "havpSD")) >= 0) {
347382
switch (res) {
348383
case 'a':
349384
{
@@ -369,6 +404,12 @@ int main(int argc, char **argv) {
369404
break;
370405
}
371406

407+
case 'D':
408+
{
409+
decryptInputBuffers = true;
410+
break;
411+
}
412+
372413
case '?':
373414
case 'h':
374415
default:
@@ -440,7 +481,8 @@ int main(int argc, char **argv) {
440481
player->stop();
441482
player->reset();
442483
} else {
443-
decode(looper, argv[0], useAudio, useVideo, surface);
484+
decode(looper, argv[0],
485+
useAudio, useVideo, surface, decryptInputBuffers);
444486
}
445487

446488
if (playback || (useSurface && useVideo)) {

cmds/stagefright/sf2.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ struct Controller : public AHandler {
287287

288288
msg->setInt32("channel-count", numChannels);
289289
msg->setInt32("sample-rate", sampleRate);
290+
291+
int32_t isADTS;
292+
if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) {
293+
msg->setInt32("is-adts", true);
294+
}
290295
}
291296

292297
uint32_t type;

include/media/ICrypto.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <binder/IInterface.h>
18+
#include <media/stagefright/foundation/ABase.h>
19+
20+
#ifndef ANDROID_ICRYPTO_H_
21+
22+
#define ANDROID_ICRYPTO_H_
23+
24+
namespace android {
25+
26+
struct ICrypto : public IInterface {
27+
DECLARE_META_INTERFACE(Crypto);
28+
29+
virtual status_t initialize() = 0;
30+
virtual status_t terminate() = 0;
31+
32+
virtual status_t setEntitlementKey(
33+
const void *key, size_t keyLength) = 0;
34+
35+
virtual status_t setEntitlementControlMessage(
36+
const void *msg, size_t msgLength) = 0;
37+
38+
// "dstData" is in media_server's address space (but inaccessible).
39+
virtual ssize_t decryptVideo(
40+
const void *iv, size_t ivLength,
41+
const void *srcData, size_t srcDataSize,
42+
void *dstData, size_t dstDataOffset) = 0;
43+
44+
// "dstData" is in the calling process' address space.
45+
virtual ssize_t decryptAudio(
46+
const void *iv, size_t ivLength,
47+
const void *srcData, size_t srcDataSize,
48+
void *dstData, size_t dstDataSize) = 0;
49+
50+
private:
51+
DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
52+
};
53+
54+
struct BnCrypto : public BnInterface<ICrypto> {
55+
virtual status_t onTransact(
56+
uint32_t code, const Parcel &data, Parcel *reply,
57+
uint32_t flags = 0);
58+
};
59+
60+
} // namespace android
61+
62+
#endif // ANDROID_ICRYPTO_H_
63+

include/media/IMediaPlayerService.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
namespace android {
3333

34+
struct ICrypto;
3435
class IMediaRecorder;
3536
class IOMX;
3637
struct IStreamSource;
@@ -47,6 +48,7 @@ class IMediaPlayerService: public IInterface
4748
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
4849
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
4950
virtual sp<IOMX> getOMX() = 0;
51+
virtual sp<ICrypto> makeCrypto() = 0;
5052

5153
// codecs and audio devices usage tracking for the battery app
5254
enum BatteryDataBits {

include/media/stagefright/ACodec.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ struct ACodec : public AHierarchicalStateMachine {
8989
kPortIndexOutput = 1
9090
};
9191

92+
enum {
93+
kFlagIsSecure = 1,
94+
};
95+
9296
struct BufferInfo {
9397
enum Status {
9498
OWNED_BY_US,
@@ -118,6 +122,7 @@ struct ACodec : public AHierarchicalStateMachine {
118122
sp<FlushingState> mFlushingState;
119123

120124
AString mComponentName;
125+
uint32_t mFlags;
121126
uint32_t mQuirks;
122127
sp<IOMX> mOMX;
123128
IOMX::node_id mNode;
@@ -176,7 +181,8 @@ struct ACodec : public AHierarchicalStateMachine {
176181

177182
status_t setupAACCodec(
178183
bool encoder,
179-
int32_t numChannels, int32_t sampleRate, int32_t bitRate);
184+
int32_t numChannels, int32_t sampleRate, int32_t bitRate,
185+
bool isADTS);
180186

181187
status_t selectAudioPortFormat(
182188
OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);

include/media/stagefright/MediaCodec.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@ namespace android {
2727
struct ABuffer;
2828
struct ACodec;
2929
struct AMessage;
30+
struct ICrypto;
3031
struct SoftwareRenderer;
3132
struct SurfaceTextureClient;
3233

3334
struct MediaCodec : public AHandler {
3435
enum ConfigureFlags {
3536
CONFIGURE_FLAG_ENCODE = 1,
37+
CONFIGURE_FLAG_SECURE = 2,
3638
};
3739

3840
enum BufferFlags {
3941
BUFFER_FLAG_SYNCFRAME = 1,
4042
BUFFER_FLAG_CODECCONFIG = 2,
4143
BUFFER_FLAG_EOS = 4,
44+
BUFFER_FLAG_ENCRYPTED = 8,
4245
};
4346

4447
static sp<MediaCodec> CreateByType(
@@ -137,11 +140,13 @@ struct MediaCodec : public AHandler {
137140
kFlagStickyError = 8,
138141
kFlagDequeueInputPending = 16,
139142
kFlagDequeueOutputPending = 32,
143+
kFlagIsSecure = 64,
140144
};
141145

142146
struct BufferInfo {
143147
void *mBufferID;
144148
sp<ABuffer> mData;
149+
sp<ABuffer> mEncryptedData;
145150
sp<AMessage> mNotify;
146151
bool mOwnedByClient;
147152
};
@@ -165,6 +170,8 @@ struct MediaCodec : public AHandler {
165170
int32_t mDequeueOutputTimeoutGeneration;
166171
uint32_t mDequeueOutputReplyID;
167172

173+
sp<ICrypto> mCrypto;
174+
168175
MediaCodec(const sp<ALooper> &looper);
169176

170177
static status_t PostAndAwaitResponse(

include/media/stagefright/MetaData.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ enum {
128128
kKeyTextFormatData = 'text', // raw data
129129

130130
kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
131+
132+
kKeyScrambling = 'scrm', // int32_t
133+
kKeyEMM = 'emm ', // raw data
134+
kKeyECM = 'ecm ', // raw data
135+
136+
kKeyIsADTS = 'adts', // bool (int32_t)
131137
};
132138

133139
enum {

include/media/stagefright/NuMediaExtractor.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ struct MediaExtractor;
3131
struct MediaSource;
3232

3333
struct NuMediaExtractor : public RefBase {
34+
enum SampleFlags {
35+
SAMPLE_FLAG_SYNC = 1,
36+
SAMPLE_FLAG_ENCRYPTED = 2,
37+
};
38+
3439
NuMediaExtractor();
3540

3641
status_t setDataSource(const char *path);
@@ -46,6 +51,7 @@ struct NuMediaExtractor : public RefBase {
4651
status_t readSampleData(const sp<ABuffer> &buffer);
4752
status_t getSampleTrackIndex(size_t *trackIndex);
4853
status_t getSampleTime(int64_t *sampleTimeUs);
54+
status_t getSampleFlags(uint32_t *sampleFlags);
4955

5056
protected:
5157
virtual ~NuMediaExtractor();
@@ -61,7 +67,9 @@ struct NuMediaExtractor : public RefBase {
6167
status_t mFinalResult;
6268
MediaBuffer *mSample;
6369
int64_t mSampleTimeUs;
64-
uint32_t mFlags; // bitmask of "TrackFlags"
70+
uint32_t mSampleFlags;
71+
72+
uint32_t mTrackFlags; // bitmask of "TrackFlags"
6573
};
6674

6775
sp<MediaExtractor> mImpl;

include/media/stagefright/OMXCodec.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,11 @@ struct OMXCodec : public MediaSource,
238238
void setComponentRole();
239239

240240
void setAMRFormat(bool isWAMR, int32_t bitRate);
241-
status_t setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
241+
242+
status_t setAACFormat(
243+
int32_t numChannels, int32_t sampleRate, int32_t bitRate,
244+
bool isADTS);
245+
242246
void setG711Format(int32_t numChannels);
243247

244248
status_t setVideoPortFormatType(

include/media/stagefright/foundation/AString.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct AString {
7373
int compare(const AString &other) const;
7474

7575
bool startsWith(const char *prefix) const;
76+
bool endsWith(const char *suffix) const;
7677

7778
void tolower();
7879

0 commit comments

Comments
 (0)