diff --git a/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h b/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h index 948c9bb6..19d7df56 100644 --- a/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h +++ b/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h @@ -51,7 +51,7 @@ class WVDRMPluginAPI { virtual bool RegisterDrmInfo(std::string &portal, std::string &dsPath) = 0; virtual bool RegisterDrmInfo(std::string &portal, std::string &dsPath, uint32_t *status) = 0; virtual bool UnregisterDrmInfo(std::string &portal, std::string &dsPath) = 0; - virtual bool AcquireDrmInfo(std::string &assetPath, WVCredentials &credentials, + virtual bool AcquireDrmInfo(std::string &assetPath, int assetOpenFd, WVCredentials &credentials, std::string &dsPath, const std::string &systemIdStr, const std::string &assetIdStr, const std::string &keyIdStr, @@ -61,10 +61,10 @@ class WVDRMPluginAPI { virtual bool ProcessDrmInfo(std::string &assetPath, int playbackMode) = 0; virtual int CheckRightsStatus(std::string &path) = 0; - virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback, + virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback, uint32_t *timeRemaining, uint32_t *licenseDuration, std::string &lastError, - bool &allowOffline, bool &allowStreaming, + bool &allowOffline, bool &allowStreaming, bool &denyHD) = 0; virtual bool SetPlaybackStatus(int playbackStatus, off64_t position) = 0; diff --git a/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp b/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp index 7f8c6276..2f10cfc3 100644 --- a/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp +++ b/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp @@ -247,6 +247,9 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI return NULL; } + // for local files, app may provide the FD of the open file. + int assetOpenFd = atol(drmInfoRequest->get(String8("FileDescriptorKey")).string()); + std::string assetDbPath = drmInfoRequest->get(String8("WVAssetDBPathKey")).string(); //ALOGV("onAcquireDrmInfo: portal=%s, dsPath=%s", credentials.portal.c_str(), assetDbPath.c_str()); @@ -262,7 +265,7 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI uint32_t systemId, assetId, keyId; - if (!mDrmPluginImpl->AcquireDrmInfo(assetPath, credentials, assetDbPath, + if (!mDrmPluginImpl->AcquireDrmInfo(assetPath, assetOpenFd, credentials, assetDbPath, systemIdStr, assetIdStr, keyIdStr, &systemId, &assetId, &keyId)) return NULL; @@ -277,6 +280,7 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI DrmBuffer(data, length), drmInfoRequest->getMimeType()); // Sets additional drmInfo attributes + // Do not propagate FileDescriptorKey into the newDrmInfo object drmInfo->put(String8("WVAssetURIKey"), String8(assetPath.c_str())); drmInfo->put(String8("WVDRMServerKey"), String8(credentials.drmServerURL.c_str())); drmInfo->put(String8("WVAssetDbPathKey"), String8(assetDbPath.c_str())); diff --git a/proprietary/drmwvmplugin/test/TestPlugin.cpp b/proprietary/drmwvmplugin/test/TestPlugin.cpp index 8f8ba6a8..1a36313c 100644 --- a/proprietary/drmwvmplugin/test/TestPlugin.cpp +++ b/proprietary/drmwvmplugin/test/TestPlugin.cpp @@ -2,6 +2,11 @@ * Copyright (C) 2011 Google, Inc. All Rights Reserved */ +#include +#include +#include +#include +#include #include #include @@ -21,10 +26,11 @@ public: WVMDrmPluginTest() {} ~WVMDrmPluginTest() {} - void TestAsset(IDrmEngine *plugin, String8 &url); + void TestAsset(IDrmEngine *plugin, String8 &url, bool useOpenFd = false); void TestRegister(IDrmEngine *plugin); - void TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode); + void TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode, + bool useOpenFd = false); void TestCheckRightsNotAcquired(IDrmEngine *plugin, String8 &url); void TestCheckValidRights(IDrmEngine *plugin, String8 &url); void TestGetConstraints(IDrmEngine *plugin, String8 &url, int playbackMode); @@ -83,10 +89,18 @@ void WVMDrmPluginTest::Run() url = String8("widevine://seawwws001.cdn.shibboleth.tv/videos/content/bbb_ffmpeg_hc_single_480p.wvm"); TestAsset(plugin, url); - // Local asset + // Local asset using URL syntax url = String8("file:///sdcard/Widevine/inception_base_360p_single.wvm"); TestAsset(plugin, url); + // Local asset using normal file path + url = String8("/sdcard/Widevine/inception_base_360p_single.wvm"); + TestAsset(plugin, url); + + // Local asset, but also supply open file descriptor + url = String8("/sdcard/Widevine/inception_base_360p_single.wvm"); + TestAsset(plugin, url, true); + // Remote asset with query parameters url = String8("http://seawwws001.cdn.shibboleth.tv/videos/content/bbb_ffmpeg_hc_single_480p.wvm?a=b"); TestAsset(plugin, url); @@ -118,15 +132,32 @@ void WVMDrmPluginTest::TestRegister(IDrmEngine *plugin) delete info; } -void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode) +void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url, + int playbackMode, bool useOpenFd) { - cout << "WVDrmPluginTest::TestAcquireRights url=" << url << " mode=" << playbackMode << endl; + cout << "WVDrmPluginTest::TestAcquireRights url=" << url << " mode=" << + playbackMode << " useOpenFd=" << useOpenFd << endl; + + int openFd = -1; String8 mimeType("video/wvm"); DrmInfoRequest rightsAcquisitionInfo(DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, mimeType); rightsAcquisitionInfo.put(String8("WVDRMServerKey"), String8( "https://staging.shibboleth.tv/widevine/cypherpc/cgi-bin/GetEMMs.cgi")); rightsAcquisitionInfo.put(String8("WVAssetURIKey"), url); + + if (useOpenFd) { + char openFdStr[16]; + openFd = open(url.string(), O_RDONLY); + if (openFd == -1) { + cout << "error opening " << url << ":" << endl; + fprintf(stderr, "Couldn't open local asset file\n"); + exit(-1); + } + sprintf(openFdStr, "%lu", (unsigned long)openFd); + rightsAcquisitionInfo.put(String8("FileDescriptorKey"), String8(openFdStr)); + } + rightsAcquisitionInfo.put(String8("WVDeviceIDKey"), String8("device1234")); rightsAcquisitionInfo.put(String8("WVPortalKey"), String8("OEM")); if (playbackMode) { @@ -142,6 +173,10 @@ void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url, int p exit(-1); } + if (useOpenFd && (openFd != -1)) { + close(openFd); + } + DrmInfoStatus *status = plugin->processDrmInfo(0, info); if (status == NULL || status->statusCode != DrmInfoStatus::STATUS_OK) { fprintf(stderr, "processDrmInfo failed!\n"); @@ -260,33 +295,35 @@ void WVMDrmPluginTest::TestRemoveAllRights(IDrmEngine *plugin) } } -void WVMDrmPluginTest::TestAsset(IDrmEngine *plugin, String8 &url) +void WVMDrmPluginTest::TestAsset(IDrmEngine *plugin, String8 &url, + bool useOpenFd) { - cout << "WVDrmPluginTest::TestAsset url=" << url << endl; + cout << "WVDrmPluginTest::TestAsset url=" << url << + " useOpenFd=" << useOpenFd << endl; TestRegister(plugin); TestRemoveAllRights(plugin); TestCheckRightsNotAcquired(plugin, url); - TestAcquireRights(plugin, url, PlaybackMode_Default); + TestAcquireRights(plugin, url, PlaybackMode_Default, useOpenFd); TestCheckValidRights(plugin, url); TestGetConstraints(plugin, url, PlaybackMode_Any); TestRemoveRights(plugin, url); TestCheckRightsNotAcquired(plugin, url); - TestAcquireRights(plugin, url, PlaybackMode_Offline); + TestAcquireRights(plugin, url, PlaybackMode_Offline, useOpenFd); TestCheckValidRights(plugin, url); TestGetConstraints(plugin, url, PlaybackMode_Offline); TestRemoveRights(plugin, url); TestCheckRightsNotAcquired(plugin, url); - TestAcquireRights(plugin, url, PlaybackMode_Streaming); + TestAcquireRights(plugin, url, PlaybackMode_Streaming, useOpenFd); TestCheckValidRights(plugin, url); TestGetConstraints(plugin, url, PlaybackMode_Streaming); TestRemoveRights(plugin, url); TestCheckRightsNotAcquired(plugin, url); - TestAcquireRights(plugin, url, PlaybackMode_Any); + TestAcquireRights(plugin, url, PlaybackMode_Any, useOpenFd); TestCheckValidRights(plugin, url); TestGetConstraints(plugin, url, PlaybackMode_Any); TestRemoveRights(plugin, url); diff --git a/proprietary/samplePlayer/src/com/widevine/demo/WidevineDrm.java b/proprietary/samplePlayer/src/com/widevine/demo/WidevineDrm.java index 069311fd..1270853f 100644 --- a/proprietary/samplePlayer/src/com/widevine/demo/WidevineDrm.java +++ b/proprietary/samplePlayer/src/com/widevine/demo/WidevineDrm.java @@ -5,7 +5,7 @@ package com.widevine.demo; import java.util.EventListener; - +import java.io.FileInputStream; //import java.util.HashMap; import java.util.Set; @@ -122,6 +122,15 @@ public class WidevineDrm { rightsAcquisitionInfo = new DrmInfoRequest(DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO, Settings.WIDEVINE_MIME_TYPE); + if (assetUri.startsWith("/sdcard")) { + try { + FileInputStream fis = new FileInputStream(assetUri); + rightsAcquisitionInfo.put("FileDescriptorKey", fis.getFD().toString()); + } + catch (java.io.IOException e) { + logMessage("Unable to get fd for '" + assetUri + "'\n"); + } + } rightsAcquisitionInfo.put("WVDRMServerKey", Settings.DRM_SERVER_URI); rightsAcquisitionInfo.put("WVAssetURIKey", assetUri); rightsAcquisitionInfo.put("WVDeviceIDKey", Settings.DEVICE_ID); diff --git a/proprietary/streamcontrol/test/TestPlayer.cpp b/proprietary/streamcontrol/test/TestPlayer.cpp index 9bbd1df7..0af9f7f8 100644 --- a/proprietary/streamcontrol/test/TestPlayer.cpp +++ b/proprietary/streamcontrol/test/TestPlayer.cpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include #include @@ -45,12 +48,14 @@ static void Terminate(); void PrintUsage(char *prog) { printf("Usage: %s url\n", prog); + printf(" %s -L filename\n", prog); printf(" -o output_file\n"); printf(" -b block_size (default: %d)\n", DEFAULT_BLOCK_SIZE); printf(" -p playback_buffer_size (default: %d)\n", (int)DEFAULT_PLAYBACK_BUFFER_SIZE); printf(" -m print PTS -> media time\n"); printf(" -s start_time (default: %s)\n", DEFAULT_START_TIME); printf(" -d drm_url\n"); + printf(" -L open filname on local file system\n"); exit(-1); } @@ -222,33 +227,64 @@ static void CloseDrmPlugin() } } -static void AcquireRights(IDrmEngine *plugin, string url, string drmUrl) +static void AcquireRights(IDrmEngine *plugin, string url, string drmUrl, + bool isLocal) { String8 mimeType("video/wvm"); DrmInfoRequest rightsAcquisitionInfo(DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, mimeType); + + int fdNum = -1; + rightsAcquisitionInfo.put(String8("WVDRMServerKey"), String8(drmUrl.c_str())); rightsAcquisitionInfo.put(String8("WVAssetURIKey"), String8(url.c_str())); + if (isLocal) { + char fdStr[16]; + fdNum = open(url.c_str(), O_RDONLY); + if (fdNum == -1) { + fprintf(stderr, "unable to open local movie file %s for reading.\n", + url.c_str()); + close(fdNum); + Terminate(); + } + sprintf(fdStr, "%lu", (unsigned long)fdNum); + rightsAcquisitionInfo.put(String8("FileDescriptorKey"), String8(fdStr)); + } rightsAcquisitionInfo.put(String8("WVDeviceIDKey"), String8("device1234")); rightsAcquisitionInfo.put(String8("WVPortalKey"), String8("OEM")); rightsAcquisitionInfo.put(String8("WVLicenseTypeKey"), String8("1")); + // Get asset rights from DRM. If it is necessary to + // read file metadata to get the asset ID, this can take several seconds. DrmInfo *info = plugin->acquireDrmInfo(0, &rightsAcquisitionInfo); if (info == NULL) { fprintf(stderr, "acquireDrmInfo failed!\n"); + if (isLocal) { + close(fdNum); + } Terminate(); } DrmInfoStatus *status = plugin->processDrmInfo(0, info); if (status == NULL || status->statusCode != DrmInfoStatus::STATUS_OK) { fprintf(stderr, "processDrmInfo failed!\n"); + if (isLocal) { + close(fdNum); + } Terminate(); } if (plugin->checkRightsStatus(0, String8(url.c_str()), Action::DEFAULT) != RightsStatus::RIGHTS_VALID) { fprintf(stderr, "checkValidRights default action failed!\n"); + if (isLocal) { + close(fdNum); + } Terminate(); } + if (isLocal) { + close(fdNum); + } + delete status; delete info; } @@ -281,10 +317,11 @@ int main( int argc, char *argv[] ) unsigned long playbackBufferSize = DEFAULT_PLAYBACK_BUFFER_SIZE; bool ptsToMediaTime = false; string drmUrl = DEFAULT_DRM_URL; + bool isLocal = false; _ah006(PrintMessage); - while ((option = getopt(argc, argv, "o:b:p:s:mD:d:")) != -1) { + while ((option = getopt(argc, argv, "o:b:p:s:mD:d:L")) != -1) { switch (option) { case 'o': outputFile = optarg; @@ -312,6 +349,10 @@ int main( int argc, char *argv[] ) drmUrl = optarg; break; + case 'L': + isLocal = true; + break; + default: printf("unknown option: '%c'\n", option); PrintUsage(argv[0]); @@ -327,7 +368,8 @@ int main( int argc, char *argv[] ) if (outputFile.size()) { output = fopen(outputFile.c_str(), "wb"); if (!output) { - fprintf(stderr, "unable to open output file %s for writing\n", argv[2]); + fprintf(stderr, "unable to open output file %s for writing\n", + argv[2]); Terminate(); } } @@ -347,7 +389,9 @@ int main( int argc, char *argv[] ) WV_SetLogging(WV_Logging_HTTP); OpenDrmPlugin(); - AcquireRights(sDrmPlugin, url, drmUrl); + + // if isLocal is true, the url param holds a local filesystem filename + AcquireRights(sDrmPlugin, url, drmUrl, isLocal); _ah002(_cb1);