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)
|
||||
|
||||
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
|
||||
include $(call all-subdir-makefiles)
|
||||
|
||||
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