Update from Widevine
Change-Id: Ie508911ed2bff66c1fe5962f51f1a51b8f484f5a
This commit is contained in:
24
Android.mk
24
Android.mk
@@ -1,23 +1 @@
|
|||||||
LOCAL_PATH:= $(call my-dir)
|
include $(call all-subdir-makefiles)
|
||||||
|
|
||||||
ifeq ($(TARGET_ARCH),arm)
|
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := libwvm.so
|
|
||||||
LOCAL_SRC_FILES := $(LOCAL_MODULE)
|
|
||||||
LOCAL_MODULE_TAGS := optional
|
|
||||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
|
||||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
|
|
||||||
OVERRIDE_BUILT_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)
|
|
||||||
include $(BUILD_PREBUILT)
|
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := libdrmwvmplugin.so
|
|
||||||
LOCAL_SRC_FILES := $(LOCAL_MODULE)
|
|
||||||
LOCAL_MODULE_TAGS := optional
|
|
||||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
|
||||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/drm
|
|
||||||
OVERRIDE_BUILT_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)
|
|
||||||
include $(BUILD_PREBUILT)
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|||||||
6
debuglibs.sh
Executable file
6
debuglibs.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
# Run this script to install the Widevine shared libs (use debug libs) into the symbols path so
|
||||||
|
# vendor/google/tools/stack can find them.
|
||||||
|
#
|
||||||
|
#!/bin/bash
|
||||||
|
cp /master/vendor/widevine/proprietary/lib/libWVStreamControlAPI.so /master/out/target/product/stingray/symbols/system/lib/libWVStreamControlAPI.so
|
||||||
|
cp /master/vendor/widevine/proprietary/lib/libwvdrm.so /master/out/target/product/stingray/symbols/system/lib/libwvdrm.so
|
||||||
14
mkall.sh
Normal file
14
mkall.sh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd /master/vendor/widevine
|
||||||
|
mm .
|
||||||
|
cd /master/frameworks/base/drm/libdrmframework/plugins/widevine
|
||||||
|
mm .
|
||||||
|
cd /master/frameworks/base/drm/libdrmframework/plugins/widevine/test
|
||||||
|
mm .
|
||||||
|
cd /master/frameworks/base/media/libwvm
|
||||||
|
mm .
|
||||||
|
cd /master/frameworks/base/media/libwvm/test
|
||||||
|
mm .
|
||||||
|
cd /master/vendor/widevine
|
||||||
|
adb sync
|
||||||
|
|
||||||
1
proprietary/Android.mk
Normal file
1
proprietary/Android.mk
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include $(call all-subdir-makefiles)
|
||||||
35
proprietary/include/AndroidHooks.h
Normal file
35
proprietary/include/AndroidHooks.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_HOOKS_H
|
||||||
|
#define ANDROID_HOOKS_H
|
||||||
|
|
||||||
|
typedef void (*AndroidEcmCallout)(char* ecm, unsigned long size);
|
||||||
|
|
||||||
|
void AndroidSetEcmCallout(AndroidEcmCallout callout);
|
||||||
|
void AndroidProcessEcm(char* ecm, unsigned long size);
|
||||||
|
|
||||||
|
typedef int (*AndroidDecryptCallout)(char *in, char *out, int length, char *iv);
|
||||||
|
|
||||||
|
void AndroidSetDecryptCallout(AndroidDecryptCallout callout);
|
||||||
|
int AndroidDecrypt(char *in, char *out, int length, char *iv);
|
||||||
|
bool AndroidHaveKey();
|
||||||
|
|
||||||
|
typedef void (*AndroidLogCallout)(const char *msg);
|
||||||
|
void AndroidSetLogCallout(AndroidLogCallout callout);
|
||||||
|
void AndroidLogDebug(const char *msg);
|
||||||
|
|
||||||
|
#endif // ANDROID_HOOKS_H
|
||||||
66
proprietary/include/WVDRMPluginAPI.h
Normal file
66
proprietary/include/WVDRMPluginAPI.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WVMDRMPLUGIN_API_H__
|
||||||
|
#define __WVMDRMPLUGIN_API_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "WVStreamControlAPI.h"
|
||||||
|
|
||||||
|
class WVDRMPluginAPI {
|
||||||
|
public:
|
||||||
|
virtual ~WVDRMPluginAPI() {}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RIGHTS_VALID,
|
||||||
|
RIGHTS_INVALID,
|
||||||
|
RIGHTS_EXPIRED,
|
||||||
|
RIGHTS_NOT_ACQUIRED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PLAYBACK_START,
|
||||||
|
PLAYBACK_STOP,
|
||||||
|
PLAYBACK_PAUSE,
|
||||||
|
PLAYBACK_INVALID
|
||||||
|
};
|
||||||
|
|
||||||
|
static WVDRMPluginAPI *create();
|
||||||
|
static void destroy(WVDRMPluginAPI *plugin);
|
||||||
|
|
||||||
|
virtual void OpenSession() = 0;
|
||||||
|
virtual void CloseSession() = 0;
|
||||||
|
|
||||||
|
virtual bool AcquireDrmInfo(std::string &assetPath, WVCredentials &credentials,
|
||||||
|
std::string &dsPath,
|
||||||
|
const std::string &assetIdStr, const std::string &systemIdStr,
|
||||||
|
const std::string &keyIdStr,
|
||||||
|
uint32_t *assetId, uint32_t *systemId, uint32_t *keyId) = 0;
|
||||||
|
virtual bool ProcessDrmInfo(std::string &assetPath) = 0;
|
||||||
|
virtual int CheckRightsStatus(std::string &path) = 0;
|
||||||
|
virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback, uint32_t *timeRemaining, uint32_t *licenseDuration) = 0;
|
||||||
|
virtual bool SetPlaybackStatus(int playbackStatus, off64_t position) = 0;
|
||||||
|
virtual bool RemoveRights(std::string &path) = 0;
|
||||||
|
virtual bool RemoveAllRights() = 0;
|
||||||
|
virtual bool Prepare(char *data, int len) = 0;
|
||||||
|
virtual bool Operate(char *in, char *out, int len, char *iv) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// use create factory method, don't construct directly
|
||||||
|
WVDRMPluginAPI() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
1254
proprietary/include/WVStreamControlAPI.h
Normal file
1254
proprietary/include/WVStreamControlAPI.h
Normal file
File diff suppressed because it is too large
Load Diff
34
proprietary/lib/Android.mk
Normal file
34
proprietary/lib/Android.mk
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
define _add-wv-shared-lib
|
||||||
|
include $$(CLEAR_VARS)
|
||||||
|
$(if $(word 2,$1),$(error Invalid WV module name $1))
|
||||||
|
LOCAL_MODULE := $(basename $(notdir $1))
|
||||||
|
LOCAL_SRC_FILES := $1
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_MODULE_SUFFIX := $(suffix $1)
|
||||||
|
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||||
|
LOCAL_MODULE_PATH := $$(TARGET_OUT)$(abspath /lib/$(dir $1))
|
||||||
|
OVERRIDE_BUILT_MODULE_PATH := $$(TARGET_OUT_INTERMEDIATE_LIBRARIES)
|
||||||
|
include $$(BUILD_PREBUILT)
|
||||||
|
endef
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
prebuilt_wv_shared_libs := \
|
||||||
|
libwvdrm.so \
|
||||||
|
libWVStreamControlAPI.so
|
||||||
|
|
||||||
|
prebuilt_wv_modules := \
|
||||||
|
$(foreach _file,$(prebuilt_wv_shared_libs),\
|
||||||
|
$(notdir $(basename $(_file))))
|
||||||
|
|
||||||
|
LOCAL_MODULE := widevine_proprietary_libs
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_REQUIRED_MODULES := $(prebuilt_wv_modules)
|
||||||
|
include $(BUILD_PHONY_PACKAGE)
|
||||||
|
|
||||||
|
$(foreach _file,$(prebuilt_wv_shared_libs),\
|
||||||
|
$(eval $(call _add-wv-shared-lib,$(_file))))
|
||||||
|
|
||||||
|
|
||||||
BIN
proprietary/lib/libWVStreamControlAPI.so
Normal file
BIN
proprietary/lib/libWVStreamControlAPI.so
Normal file
Binary file not shown.
BIN
proprietary/lib/libwvdrm.so
Normal file
BIN
proprietary/lib/libwvdrm.so
Normal file
Binary file not shown.
27
proprietary/test/Android.mk
Normal file
27
proprietary/test/Android.mk
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES:= \
|
||||||
|
TestPlayer.cpp
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES+= \
|
||||||
|
bionic \
|
||||||
|
vendor/widevine/proprietary/include \
|
||||||
|
external/stlport/stlport \
|
||||||
|
frameworks/base/media/libwvm/include
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libstlport \
|
||||||
|
libWVStreamControlAPI \
|
||||||
|
libdrmframework \
|
||||||
|
libwvdrm \
|
||||||
|
liblog \
|
||||||
|
libutils \
|
||||||
|
libz
|
||||||
|
|
||||||
|
LOCAL_MODULE:=test-wvplayer
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
|
||||||
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
590
proprietary/test/TestPlayer.cpp
Normal file
590
proprietary/test/TestPlayer.cpp
Normal file
@@ -0,0 +1,590 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termio.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "WVDRMPluginAPI.h"
|
||||||
|
#include "WVStreamControlAPI.h"
|
||||||
|
#include "AndroidHooks.h"
|
||||||
|
|
||||||
|
#define AES_BLOCK_SIZE 16
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define DEFAULT_BLOCK_SIZE 16*1024
|
||||||
|
#define DEFAULT_PLAYBACK_BUFFER_SIZE 0*1024*1024
|
||||||
|
#define DEFAULT_START_TIME "now"
|
||||||
|
#define DEFAULT_DRM_URL "http://wstfcps005.shibboleth.tv/widevine/cypherpc/cgi-bin/GetEMMs.cgi"
|
||||||
|
#define DEFAULT_DRM_ACK_URL "http://wstfcps005.shibboleth.tv/widevine/cypherpc/cgi-bin/Ack.cgi"
|
||||||
|
|
||||||
|
#define SHOW_BITRATE 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print command line options
|
||||||
|
*/
|
||||||
|
void PrintUsage(char *prog)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <options> url\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");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WVDRMPluginAPI *sDrmPlugin = NULL;
|
||||||
|
|
||||||
|
static struct termios termattr, save_termattr;
|
||||||
|
static int ttysavefd = -1;
|
||||||
|
static enum
|
||||||
|
{
|
||||||
|
RESET, RAW, CBREAK
|
||||||
|
} ttystate = RESET;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
***************************************************************************
|
||||||
|
*
|
||||||
|
* set_tty_raw(), put the user's TTY in one-character-at-a-time mode.
|
||||||
|
*
|
||||||
|
* @returns 0 on success, -1 on failure.
|
||||||
|
*
|
||||||
|
*************************************************************************** */
|
||||||
|
int set_tty_raw(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = tcgetattr(STDIN_FILENO, &termattr);
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
printf("tcgetattr() returned %d for fildes=%d\n",i,STDIN_FILENO);
|
||||||
|
perror("");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
save_termattr = termattr;
|
||||||
|
|
||||||
|
termattr.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||||
|
termattr.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON); /* | BRKINT */
|
||||||
|
termattr.c_cflag &= ~(CSIZE | PARENB);
|
||||||
|
termattr.c_cflag |= CS8;
|
||||||
|
/* termattr.c_oflag &= ~(OPOST); */
|
||||||
|
|
||||||
|
termattr.c_cc[VMIN] = 0; /* or 0 for some Unices; see note 1 */
|
||||||
|
termattr.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
i = tcsetattr(STDIN_FILENO, TCSANOW, &termattr);
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
printf("tcsetattr() returned %d for fildes=%d\n",i,STDIN_FILENO);
|
||||||
|
perror("");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ttystate = RAW;
|
||||||
|
ttysavefd = STDIN_FILENO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return time of day in milliseconds
|
||||||
|
*/
|
||||||
|
static uint64_t get_time_in_ms()
|
||||||
|
{
|
||||||
|
uint64_t ms;
|
||||||
|
timeval t;
|
||||||
|
gettimeofday(&t, NULL);
|
||||||
|
ms = (uint64_t)(t.tv_sec) * 1000;
|
||||||
|
ms +=(uint64_t)(t.tv_usec) / 1000;
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
***************************************************************************
|
||||||
|
*
|
||||||
|
* set_tty_cooked(), restore normal TTY mode. Very important to call
|
||||||
|
* the function before exiting else the TTY won't be too usable.
|
||||||
|
*
|
||||||
|
* @returns 0 on success, -1 on failure.
|
||||||
|
*
|
||||||
|
*************************************************************************** */
|
||||||
|
int set_tty_cooked(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ttystate != CBREAK && ttystate != RAW)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
i = tcsetattr(STDIN_FILENO, TCSAFLUSH, &save_termattr);
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ttystate = RESET;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
***************************************************************************
|
||||||
|
*
|
||||||
|
* kb_getc(), if there's a typed character waiting to be read,
|
||||||
|
*
|
||||||
|
* @return character; else return 0.
|
||||||
|
*
|
||||||
|
*************************************************************************** */
|
||||||
|
unsigned char kb_getc(void)
|
||||||
|
{
|
||||||
|
unsigned char ch;
|
||||||
|
ssize_t size;
|
||||||
|
|
||||||
|
size = read(STDIN_FILENO, &ch, 1);
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Terminate()
|
||||||
|
{
|
||||||
|
WV_Terminate();
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintMessage(const char *msg)
|
||||||
|
{
|
||||||
|
printf("%s", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Program entry pointer
|
||||||
|
*
|
||||||
|
* @return 0 for success, -1 for error
|
||||||
|
*/
|
||||||
|
int main( int argc, char *argv[] )
|
||||||
|
{
|
||||||
|
int option;
|
||||||
|
|
||||||
|
string url, outputFile, startTime = DEFAULT_START_TIME;
|
||||||
|
unsigned long blockSize = DEFAULT_BLOCK_SIZE;
|
||||||
|
unsigned long playbackBufferSize = DEFAULT_PLAYBACK_BUFFER_SIZE;
|
||||||
|
bool ptsToMediaTime = false;
|
||||||
|
string drmUrl = DEFAULT_DRM_URL;
|
||||||
|
|
||||||
|
// Set up callouts
|
||||||
|
AndroidSetLogCallout(PrintMessage);
|
||||||
|
|
||||||
|
// Create DRM plugin object
|
||||||
|
sDrmPlugin = WVDRMPluginAPI::create();
|
||||||
|
if (sDrmPlugin == NULL) {
|
||||||
|
fprintf(stderr, "FATAL: failed to construct WVMDRMPluginAPI instance\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((option = getopt(argc, argv, "o:b:p:s:mD:d:")) != -1) {
|
||||||
|
switch (option) {
|
||||||
|
case 'o':
|
||||||
|
outputFile = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
if (sscanf(optarg, "%lu", &blockSize) != 1)
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (sscanf(optarg, "%lu", &playbackBufferSize) != 1)
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
startTime = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
ptsToMediaTime = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
drmUrl = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown option: '%c'\n", option);
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((argc - optind) != 1)
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
|
||||||
|
url = argv[optind];
|
||||||
|
|
||||||
|
FILE *output = NULL;
|
||||||
|
if (outputFile.size()) {
|
||||||
|
output = fopen(outputFile.c_str(), "wb");
|
||||||
|
if (!output) {
|
||||||
|
fprintf(stderr, "unable to open output file %s for writing\n", argv[2]);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This turns off some verbose printing
|
||||||
|
setenv("WV_SILENT", "true", 1);
|
||||||
|
|
||||||
|
WVStatus status = WV_Initialize( NULL );
|
||||||
|
|
||||||
|
if (status != WV_Status_OK) {
|
||||||
|
fprintf(stderr, "ERROR: WV_Initialize returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable HTTP logging if you want to debug
|
||||||
|
//WV_SetLogging(WV_Logging_HTTP);
|
||||||
|
|
||||||
|
/*
|
||||||
|
status = WV_StartBandwidthCheck( url.c_str() );
|
||||||
|
if (status != WV_Status_OK) {
|
||||||
|
fprintf(stderr, "ERROR: WV_CheckBandwidth returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long bandwidth;
|
||||||
|
do {
|
||||||
|
usleep(100000);
|
||||||
|
|
||||||
|
// The idea here is the bandwidth check is done in the background while the GUI/OSD is
|
||||||
|
// doing other things. In this example, we just wait for the result.
|
||||||
|
|
||||||
|
status = WV_GetBandwidthCheckStatus(&bandwidth);
|
||||||
|
} while (status == WV_Status_Checking_Bandwidth);
|
||||||
|
|
||||||
|
if (status == WV_Status_OK)
|
||||||
|
cout << "Bandwidth check " << bandwidth << endl;
|
||||||
|
else
|
||||||
|
cout << "Bandwidth check failed: " << status << endl;
|
||||||
|
*/
|
||||||
|
WVSession *session = 0;
|
||||||
|
WVCredentials credentials;
|
||||||
|
credentials.deviceID="SN12345ABC";
|
||||||
|
credentials.streamID="0123456789";
|
||||||
|
credentials.portal = "YouTube";
|
||||||
|
credentials.clientIP="1.1.1.1";
|
||||||
|
credentials.drmServerURL= drmUrl;
|
||||||
|
credentials.userData="";
|
||||||
|
credentials.drmAckServerURL=DEFAULT_DRM_ACK_URL;
|
||||||
|
|
||||||
|
string dsPath = "";
|
||||||
|
string assetIdStr = "";
|
||||||
|
string systemIdStr = "";
|
||||||
|
string keyIdStr = "";
|
||||||
|
uint_t assetId, systemId, keyId;
|
||||||
|
|
||||||
|
if (!sDrmPlugin->AcquireDrmInfo(url, credentials, dsPath,
|
||||||
|
assetIdStr, systemIdStr, keyIdStr,
|
||||||
|
&assetId, &systemId, &keyId)) {
|
||||||
|
fprintf(stderr, "ERROR: AcquireDrmInfo failed\n");
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sDrmPlugin->ProcessDrmInfo(url)) {
|
||||||
|
fprintf(stderr, "ERROR: ProcessDrmInfo failed\n");
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
status = WV_Setup( session, url.c_str(), "RAW/RAW/RAW;destination=getdata", credentials);
|
||||||
|
if (status != WV_Status_OK) {
|
||||||
|
fprintf(stderr, "ERROR: WV_Setup returned status %d\n", (int)status);
|
||||||
|
if (status == 408)
|
||||||
|
fprintf(stderr, "TIMEOUT: Make sure your device is powered on and has a network connection\n");
|
||||||
|
else if (status == 404)
|
||||||
|
fprintf(stderr, "ASSET NOT FOUND: Make sure the URL you provided is correct\n");
|
||||||
|
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
WVMacrovision macrovision;
|
||||||
|
bool hdcp, cit;
|
||||||
|
status = WV_Info_GetCopyProtection(session, ¯ovision, &hdcp, &cit);
|
||||||
|
switch (status) {
|
||||||
|
case WV_Status_OK:
|
||||||
|
printf("Copy protection: macrovison = %d, hdcp = %d, cit = %d\n", (int)macrovision, (int)hdcp, (int)cit);
|
||||||
|
break;
|
||||||
|
case WV_Status_Warning_Not_Available:
|
||||||
|
printf("Warning: Copy protection info not yet available\n");
|
||||||
|
status = WV_Status_OK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERROR: WV_Info_GetCopyProtection returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get audio and video config options
|
||||||
|
WVAudioType audioType;
|
||||||
|
unsigned short streamId;
|
||||||
|
unsigned short profile;
|
||||||
|
unsigned short numChannels;
|
||||||
|
unsigned long sampleFrequency;
|
||||||
|
unsigned long bitRate;
|
||||||
|
WVVideoType videoType;
|
||||||
|
unsigned short level;
|
||||||
|
unsigned short width;
|
||||||
|
unsigned short height;
|
||||||
|
float pixelAspectRatio;
|
||||||
|
float frameRate;
|
||||||
|
|
||||||
|
WV_Info_GetAudioConfiguration(session, &audioType, &streamId, &profile, &numChannels, &sampleFrequency, &bitRate);
|
||||||
|
printf("Audio type: %hu\n", audioType);
|
||||||
|
printf("Audio stream ID: %hu\n", streamId);
|
||||||
|
printf("Audio profile: %hu\n", profile);
|
||||||
|
printf("Audio channels: %hu\n", numChannels);
|
||||||
|
printf("Audio sampling freq: %lu\n", sampleFrequency);
|
||||||
|
printf("Audio bit rate: %lu\n", bitRate);
|
||||||
|
|
||||||
|
WV_Info_GetVideoConfiguration(session, &videoType, &streamId, &profile, &level, &width, &height, & pixelAspectRatio, &frameRate, &bitRate);
|
||||||
|
printf("Video type: %hu\n", videoType);
|
||||||
|
printf("Video stream ID: %hu\n", streamId);
|
||||||
|
printf("Video profile: %hu\n", profile);
|
||||||
|
printf("Video profile level: %hu\n", level);
|
||||||
|
printf("Video width: %hu\n", width);
|
||||||
|
printf("Video height: %hu\n", height);
|
||||||
|
printf("Video pixel aspect ratio: %f\n", pixelAspectRatio);
|
||||||
|
printf("Video frame rate: %f\n", frameRate);
|
||||||
|
printf("Video bit rate: %lu\n", bitRate);
|
||||||
|
|
||||||
|
float scale_used;
|
||||||
|
startTime += "-";
|
||||||
|
status = WV_Play( session, 1.0, &scale_used, startTime.c_str() );
|
||||||
|
if (status != WV_Status_OK) {
|
||||||
|
fprintf(stderr, "ERROR: WV_Play returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_ptr<uint8_t> buffer(new uint8_t[blockSize]);
|
||||||
|
size_t numBytes;
|
||||||
|
|
||||||
|
// fill playback buffer as quickly as possible
|
||||||
|
uint64_t bytesRead = 0;
|
||||||
|
while (bytesRead < playbackBufferSize) {
|
||||||
|
status = WV_GetData( session, buffer.get(), blockSize, &numBytes, 0 );
|
||||||
|
switch (status) {
|
||||||
|
case WV_Status_OK:
|
||||||
|
break;
|
||||||
|
case WV_Status_Warning_Download_Stalled:
|
||||||
|
case WV_Status_Warning_Need_Key:
|
||||||
|
fprintf(stderr, "WARNING: WV_GetData returned status %d\n", (int)status);
|
||||||
|
usleep(100000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERROR: WV_GetData returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (numBytes > 0) {
|
||||||
|
if (output)
|
||||||
|
fwrite(buffer.get(), numBytes, 1, output);
|
||||||
|
bytesRead += numBytes;
|
||||||
|
cout << "Read " << numBytes << "/" << bytesRead << " out of " << playbackBufferSize << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_tty_raw();
|
||||||
|
|
||||||
|
#if SHOW_BITRATE
|
||||||
|
unsigned long bitRates[32];
|
||||||
|
size_t numBitRates;
|
||||||
|
size_t curBitRate;
|
||||||
|
if (WV_Info_GetAdaptiveBitrates(session, bitRates, sizeof(bitRates)/sizeof(uint32_t),
|
||||||
|
&numBitRates, &curBitRate) == WV_Status_OK) {
|
||||||
|
printf("Bit Rates: ");
|
||||||
|
for (uint32_t idx = 0; idx < numBitRates; ++idx) {
|
||||||
|
if (idx == curBitRate)
|
||||||
|
printf("*%lu* ", bitRates[idx]);
|
||||||
|
else
|
||||||
|
printf("%lu ", bitRates[idx]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
string nptTime = WV_Info_GetTime(session);
|
||||||
|
int hh, mm;
|
||||||
|
float ss;
|
||||||
|
sscanf(nptTime.c_str(), "%d:%d:%f", &hh, &mm, &ss);
|
||||||
|
uint64_t startMs = (uint64_t)((hh * 3600000) + (mm * 60000) + (ss * 1000));
|
||||||
|
uint64_t curMs = startMs;
|
||||||
|
uint64_t lastMs = curMs;
|
||||||
|
uint64_t baseTime = get_time_in_ms();
|
||||||
|
int trickPlayRate = 1;
|
||||||
|
|
||||||
|
bool quit = false;
|
||||||
|
while (!quit) {
|
||||||
|
uint64_t curTime = get_time_in_ms();
|
||||||
|
uint64_t streamTimeRef = (trickPlayRate >= 0) ? (curMs - startMs) : (startMs - curMs);
|
||||||
|
uint64_t clockRef = get_time_in_ms() - baseTime;
|
||||||
|
if (trickPlayRate)
|
||||||
|
clockRef *= trickPlayRate > 0 ? trickPlayRate : -trickPlayRate;
|
||||||
|
if (clockRef > streamTimeRef) {
|
||||||
|
// time for another pull
|
||||||
|
status = WV_GetData( session, buffer.get(), blockSize, &numBytes, 0 );
|
||||||
|
switch (status) {
|
||||||
|
case WV_Status_OK:
|
||||||
|
break;
|
||||||
|
case WV_Status_End_Of_Media:
|
||||||
|
printf("END OF MEDIA %d\n", trickPlayRate);
|
||||||
|
break;
|
||||||
|
if (trickPlayRate < 0) {
|
||||||
|
WV_Play( session, 1.0, &scale_used, "00:00:00-" );
|
||||||
|
trickPlayRate = 1;
|
||||||
|
startMs = curMs;
|
||||||
|
baseTime = curTime;
|
||||||
|
} else
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
case 1001:
|
||||||
|
fprintf(stderr, "ERROR: WV_GetData returned status %d\n", (int)status);
|
||||||
|
break;
|
||||||
|
case WV_Status_Warning_Download_Stalled:
|
||||||
|
case WV_Status_Warning_Need_Key:
|
||||||
|
fprintf(stderr, "WARNING: WV_GetData returned status %d\n", (int)status);
|
||||||
|
usleep(100000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERROR: WV_GetData returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (numBytes > 0) {
|
||||||
|
if (output)
|
||||||
|
fwrite(buffer.get(), numBytes, 1, output);
|
||||||
|
bytesRead += numBytes;
|
||||||
|
nptTime = WV_Info_GetTime(session);
|
||||||
|
sscanf(nptTime.c_str(), "%d:%d:%f", &hh, &mm, &ss);
|
||||||
|
curMs = (uint64_t)((hh * 3600000) + (mm * 60000) + (ss * 1000));
|
||||||
|
if (curMs != lastMs) {
|
||||||
|
int64_t msDif = (trickPlayRate >= 0) ? (curMs - lastMs) : (lastMs - curMs);
|
||||||
|
if ((msDif < 0) || (msDif > 60000)) {
|
||||||
|
// discontinuity
|
||||||
|
startMs = curMs;
|
||||||
|
baseTime = curTime;
|
||||||
|
printf("Current time (skip): %s\n", nptTime.c_str());
|
||||||
|
} else if ((curMs / 1000) != (lastMs / 1000)) {
|
||||||
|
printf("Current time: %s\n", nptTime.c_str());
|
||||||
|
#if SHOW_BITRATE
|
||||||
|
if (WV_Info_GetAdaptiveBitrates(session, bitRates, sizeof(bitRates)/sizeof(uint32_t),
|
||||||
|
&numBitRates, &curBitRate) == WV_Status_OK) {
|
||||||
|
printf("Bit Rates: ");
|
||||||
|
for (uint32_t idx = 0; idx < numBitRates; ++idx) {
|
||||||
|
if (idx == curBitRate)
|
||||||
|
printf("*%lu* ", bitRates[idx]);
|
||||||
|
else
|
||||||
|
printf("%lu ", bitRates[idx]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
lastMs = curMs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char kbhit = kb_getc();
|
||||||
|
switch (kbhit) {
|
||||||
|
case 'g':
|
||||||
|
char seekTime[256];
|
||||||
|
set_tty_cooked();
|
||||||
|
printf("Go to time: ");
|
||||||
|
if ((scanf("%s", seekTime) == 1) && (sscanf(seekTime, "%d:%d:%f", &hh, &mm, &ss) == 3)) {
|
||||||
|
status = WV_Play(session, 1, &scale_used, string(seekTime) + "-");
|
||||||
|
if (status != WV_Status_OK) {
|
||||||
|
fprintf(stderr, "ERROR: WV_Play returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
startMs = curMs;
|
||||||
|
baseTime = curTime;
|
||||||
|
}
|
||||||
|
set_tty_raw();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
set_tty_cooked();
|
||||||
|
printf("Trick-play rate (now): ");
|
||||||
|
if (scanf("%d", &trickPlayRate) == 1) {
|
||||||
|
printf( "Got a trick play value of %d\n", trickPlayRate );
|
||||||
|
if (trickPlayRate == 0)
|
||||||
|
trickPlayRate = 1;
|
||||||
|
status = WV_Play(session, trickPlayRate, &scale_used, "now-");
|
||||||
|
if (status != WV_Status_OK) {
|
||||||
|
fprintf(stderr, "ERROR: WV_Play returned status %d\n", (int)status);
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
startMs = curMs;
|
||||||
|
baseTime = curTime;
|
||||||
|
} else {
|
||||||
|
printf( "did not get a rate\n" );
|
||||||
|
}
|
||||||
|
set_tty_raw();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
set_tty_cooked();
|
||||||
|
printf("PTS: ");
|
||||||
|
uint64_t pts;
|
||||||
|
if (scanf("%llu", (long long unsigned int*)& pts) == 1) {
|
||||||
|
string mediaTime = WV_TimestampToMediaTime(session, pts, PTS);
|
||||||
|
printf("Media Time: \"%s\"\n", mediaTime.c_str());
|
||||||
|
}
|
||||||
|
set_tty_raw();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
WV_Teardown( session );
|
||||||
|
WV_Terminate();
|
||||||
|
|
||||||
|
if (output)
|
||||||
|
fclose(output);
|
||||||
|
|
||||||
|
set_tty_cooked();
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
3
proprietary/test/kill.sh
Executable file
3
proprietary/test/kill.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
PID=`adb shell ps | grep test-wvplayer | awk '{print $2}'`
|
||||||
|
adb shell kill -9 $PID
|
||||||
12
putlibs.sh
Executable file
12
putlibs.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This is a script to install the original DRM plugins (first working stingray libs)
|
||||||
|
# on the device. You shouldn't need to use it except for troubleshooting/debugging.
|
||||||
|
|
||||||
|
adb root
|
||||||
|
sleep 2
|
||||||
|
adb remount
|
||||||
|
sleep 2
|
||||||
|
adb push libwvm.so /system/lib
|
||||||
|
adb shell mkdir -p /system/lib/drm/plugins/native
|
||||||
|
adb push libdrmwvmplugin.so /system/lib/drm/plugins/native
|
||||||
|
adb reboot
|
||||||
Binary file not shown.
Reference in New Issue
Block a user