Skip to content
This repository was archived by the owner on Jul 3, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/inspector/js/inspectorGfx.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function createPlaybackEaselHost(file) {

var easel;
function createEasel() {
Shumway.GFX.VP6Player.SWFPath = "../../utils/vp6player/vp6player.swf";
Shumway.GFX.WebGL.SHADER_ROOT = "../../src/gfx/gl/shaders/";
easel = new Easel(document.getElementById("easelContainer"));
easel.startRendering();
Expand Down
2 changes: 2 additions & 0 deletions extension/firefox/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ build: ensureoutputdir
mkdir -p $(BUILD_DIR)/content/libs
cp ../../build/libs/builtin.abc $(BUILD_DIR)/content/libs/
cp ../../build/libs/relooper.js $(BUILD_DIR)/content/libs/
cp ../../utils/vp6player/vp6player.swf $(BUILD_DIR)/content/
# Copying closure optimized shumway.js files
cp $(BUNDLES_DIR)/shumway*.js $(BUILD_DIR)/content/
cp ../../build/version/version.txt $(BUILD_DIR)/content/version.txt
Expand Down Expand Up @@ -71,6 +72,7 @@ restartless:
ln -s ../../../build/libs $(RESTARTLESS_DIR)/content/libs
ln -s ../../../build/bundles/shumway.gfx.js $(RESTARTLESS_DIR)/content/shumway.gfx.js
ln -s ../../../build/bundles/shumway.player.js $(RESTARTLESS_DIR)/content/shumway.player.js
ln -s ../../../utils/vp6player/vp6player.swf $(RESTARTLESS_DIR)/content/vp6player.swf
ln -s ../../../build/version/version.txt $(RESTARTLESS_DIR)/content/version.txt
cd $(RESTARTLESS_DIR); pwd > "$(PROFILE)/extensions/shumway@research.mozilla.org"
grep "nglayout.debug.disable_xul_cache\", true" "$(PROFILE)/prefs.js" 1>/dev/null || echo "Set create 'nglayout.debug.disable_xul_cache' boolean preference to 'true'."
Expand Down
5 changes: 5 additions & 0 deletions extension/firefox/content/ShumwayStreamConverter.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ function isShumwayEnabledFor(startupInfo) {
var url = startupInfo.url;
var baseUrl = startupInfo.baseUrl;

if (/^resource:\/\/shumway\//i.test(url)) {
// disabled for internal Shumway SWFs
return false;
}

// blacklisting well known sites with issues
if (/\.ytimg\.com\//i.test(url) /* youtube movies */ ||
/\/vui.swf\b/i.test(url) /* vidyo manager */ ||
Expand Down
1 change: 1 addition & 0 deletions src/base/remoting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ module Shumway.Remoting {
registerImage(syncId: number, symbolId: number, imageType: ImageType,
data: Uint8Array, alphaData: Uint8Array): Promise<any>;
fscommand(command: string, args: string): void;
sendVP6StreamData(url: string, data: Uint8Array): void;
}

/**
Expand Down
26 changes: 26 additions & 0 deletions src/base/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,32 @@ module Shumway {
return Random.next();
};

function formatUint16(n): string {
var s = n.toString(16);
switch (n.length) {
case 1:
return '000' + s;
case 2:
return '00' + s;
case 3:
return '0' + s;
default:
return s;
}
}

export function generateRandomUUID(): string {
var data = new Uint16Array(8);
(<any>window).crypto.getRandomValues(data);
// See rfc 4122, section 4.4
data[3] = (data[3] & 0x0FFF) | 0x4000; // time_hi_and_version bits 12-15 set to 0100
data[4] = (data[4] & 0x3FFF) | 0x8000; // clock_seq_hi_and_reserved bits 6-7 to 10
return formatUint16(data[0]) + formatUint16(data[1]) + '-' +
formatUint16(data[2]) + '-' + formatUint16(data[3]) + '-' +
formatUint16(data[4]) + '-' + formatUint16(data[5]) +
formatUint16(data[6]) + formatUint16(data[7]);
}

function polyfillWeakMap() {
if (typeof jsGlobal.WeakMap === 'function') {
return; // weak map is supported
Expand Down
106 changes: 70 additions & 36 deletions src/flash/net/NetStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ module Shumway.AVMX.AS.flash.net {
notImplemented("public flash.net.NetStream::dispose"); return;
}

_getVideoStreamURL(): string {
return this._videoStream.url;
}

play(url: string): void {
flash.media.SoundMixer._registerSoundSource(this);

Expand All @@ -183,8 +179,13 @@ module Shumway.AVMX.AS.flash.net {
this._videoStream.play(url, this.checkPolicyFile);
}

this._notifyVideoControl(VideoControlEvent.Init, {
url: this._videoStream.url
this._videoStream.urlPromise.then((url: string) => {
this._notifyVideoControl(VideoControlEvent.Init, {
url: url
});
}, (reason: any) => {
this.dispatchEvent(new this.sec.flash.events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, this.sec.createObjectFromJS({code: "NetStream.Play.NoSupportedTrackFound", level: "error"})));
});
}
play2(param: flash.net.NetStreamPlayOptions): void {
Expand Down Expand Up @@ -588,11 +589,10 @@ module Shumway.AVMX.AS.flash.net {
private _started: boolean;
private _buffer: string;
private _bufferTime: number;
private _url: string;
private _urlPromise: PromiseWrapper<string>;
private _contentTypeHint: string;
private _state: VideoStreamState;
private _mediaSource;
private _mediaSourceBuffer;
private _mediaSourceBufferLock: Promise<any>;
private _head: Uint8Array;
private _decoder: IDataDecoder;
Expand All @@ -617,18 +617,17 @@ module Shumway.AVMX.AS.flash.net {
this._started = false;
this._buffer = 'empty';
this._bufferTime = 0.1;
this._url = null;
this._urlPromise = new PromiseWrapper<string>();
this._mediaSource = null;
this._mediaSourceBuffer = null;
this._mediaSourceBufferLock = null;
this._contentTypeHint = null;
this._state = VideoStreamState.CLOSED;
this._head = null;
this._netStream = netStream;
}

get url(): string {
return this._url;
get urlPromise(): Promise<string> {
return this._urlPromise.promise;
}

play(url: string, checkPolicyFile: boolean) {
Expand All @@ -639,24 +638,32 @@ module Shumway.AVMX.AS.flash.net {
Debug.warning('MediaSource API is not enabled, falling back to regular playback');
isMediaSourceEnabled = false;
}
var flvMode: string = flvOption.value;
var forceMediaSource = false;
if (/\.flv($|\?)/i.test(url)) {
if (flvOption.value === 'supported') {
var useVP6Player = false;
if (vp6PlayerOption.value) {
useVP6Player = true;
} else if (/\.flv($|\?)/i.test(url)) {
if (flvMode === 'supported') {
forceMediaSource = true;
} else if (flvOption.value === 'mock') {
} else if (flvMode === 'mock') {
url = 'resource://shumway/web/noflv.mp4';
} else if (flvMode === 'flash') {
useVP6Player = true;
} else {
setTimeout(() => {
this._netStream.dispatchEvent(new this.sec.flash.events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, this.sec.createObjectFromJS({code: "NetStream.Play.NoSupportedTrackFound", level: "error"})));
});
this._urlPromise.reject('Not supported');
return;
}
}

if (!forceMediaSource && !isMediaSourceEnabled) {
somewhatImplemented("public flash.net.NetStream::play");
this._state = VideoStreamState.OPENED;
this._url = FileLoadingService.instance.resolveUrl(url);
url = FileLoadingService.instance.resolveUrl(url);
if (useVP6Player) {
url = 'vp6:' + url;
}
this._urlPromise.resolve(url);
return;
}

Expand Down Expand Up @@ -741,27 +748,55 @@ module Shumway.AVMX.AS.flash.net {
openInDataGenerationMode() {
release || assert(this._state === VideoStreamState.CLOSED);
this._state = VideoStreamState.OPENED_DATA_GENERATION;
}

private _createMediaSource(contentType: string): Promise<any> {
var mediaSourceReady = new PromiseWrapper<any>();
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', function(e) {
this._ensurePlaying();
var mediaSourceBuffer = this._mediaSource.addSourceBuffer(contentType);
mediaSourceReady.resolve(mediaSourceBuffer);
}.bind(this));
mediaSource.addEventListener('sourceend', function(e) {
this._mediaSource = null;
}.bind(this));
this._mediaSource = mediaSource;
this._url = URL.createObjectURL(mediaSource);
this._mediaSourceBufferLock = mediaSourceReady.promise;
var url = URL.createObjectURL(mediaSource);
this._urlPromise.resolve(url);
return mediaSourceReady.promise;
}

private _createVP6PlayerDecoder(): IDataDecoder {
var url = 'vp6:flvstream:' + generateRandomUUID();
this._urlPromise.resolve(url);
var player: any = this.sec.player;
// Shortcut: using decoder interface to push data to the gfx iframe.
// FIXME don't use player._gfxService -- implement interface
return {
onData: null,
onError: null,
push: function (bytes: Uint8Array) { player.sendVP6StreamData(url, bytes); },
close: function () { player.sendVP6StreamData(url, null /* EOF */); }
};
}

appendBytes(bytes: Uint8Array) {
release || assert(this._state === VideoStreamState.OPENED_DATA_GENERATION ||
this._state === VideoStreamState.OPENED);
release || assert(this._mediaSource);

if (this._decoder) {
this._decoder.push(bytes);
return;
}

if (vp6PlayerOption.value) {
this._decoder = this._createVP6PlayerDecoder();
this._decoder.push(bytes);
return;
}

// First we need to parse some content to find out mime type and codecs
// for MediaSource. Caching some data at the beginning until we can tell
// the type of the content.
Expand All @@ -783,21 +818,19 @@ module Shumway.AVMX.AS.flash.net {
// FLV data needs to be parsed and wrapped with MP4 tags.
var flvDecoder = new FlvMp4Decoder(this.sec);
flvDecoder.onHeader = function (contentType) {
this._mediaSourceBuffer = this._mediaSource.addSourceBuffer(contentType);
this._mediaSourceBufferLock = Promise.resolve(undefined);
this._createMediaSource(contentType);
}.bind(this);
flvDecoder.onData = this._queueData.bind(this);
this._decoder = flvDecoder;
} else if (contentType) {
// Let's use identity decoder for reset of the types.
// Let's use identity decoder for rest of the types.
this._decoder = {
onData: this._queueData.bind(this),
onError: function (e) { /* */ },
push: function (bytes: Uint8Array) { this.onData(bytes); },
close: function () { /* */ }
};
this._mediaSourceBuffer = this._mediaSource.addSourceBuffer(contentType);
this._mediaSourceBufferLock = Promise.resolve(undefined);
this._createMediaSource(contentType);
}
}

Expand All @@ -819,13 +852,12 @@ module Shumway.AVMX.AS.flash.net {

private _queueData(bytes: Uint8Array): void {
// We need to chain all appendBuffer operations using 'update' event.
var buffer = this._mediaSourceBuffer;
this._mediaSourceBufferLock = this._mediaSourceBufferLock.then(function () {
this._mediaSourceBufferLock = this._mediaSourceBufferLock.then(function (buffer) {
buffer.appendBuffer(bytes);
return new Promise(function (resolve) {
buffer.addEventListener('update', function updateHandler() {
buffer.removeEventListener('update', updateHandler);
resolve();
resolve(buffer);
});
});
});
Expand All @@ -842,12 +874,14 @@ module Shumway.AVMX.AS.flash.net {
throw new Error('Internal appendBytes error');
}
this._decoder.close();
this._mediaSourceBufferLock.then(function () {
if (this._mediaSource) {
this._mediaSource.endOfStream();
}
this.close();
}.bind(this));
if (this._mediaSourceBufferLock) {
this._mediaSourceBufferLock.then(function (buffer) {
if (this._mediaSource) {
this._mediaSource.endOfStream();
}
this.close();
}.bind(this));
}
}
somewhatImplemented("public flash.net.NetStream::appendBytesAction");
}
Expand Down
4 changes: 4 additions & 0 deletions src/flash/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ module Shumway.AVMX.AS {
new Shumway.Options.Option(null, "Use Media Source for Video", "boolean", false, "Enables Media Source Extension API for NetStream.")
);

export var vp6PlayerOption = flashOptions.register (
new Shumway.Options.Option(null, "Use VP6Player for Video", "boolean", false, "Always use VP6Player for media playback.")
);

export var mediaSourceMP3Option = flashOptions.register (
new Shumway.Options.Option(null, "Use Media Source for MP3", "boolean", true, "Enables Media Source Extension API for MP3 streams.")
);
Expand Down
4 changes: 4 additions & 0 deletions src/gfx/easelHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ module Shumway.GFX {
arguments.length; // keeping from closure removal
}

processVP6StreamData(url: string, data: Uint8Array) {
VP6Player.addVP6StreamData(url, data);
}

processFrame() {
arguments.length; // keeping from closure removal
}
Expand Down
1 change: 1 addition & 0 deletions src/gfx/references-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
/// <reference path='geometry.ts'/>
/// <reference path='regionAllocator.ts'/>
/// <reference path='nodes.ts'/>
/// <reference path='vp6player.ts' />
/// <reference path='renderables/renderables.ts'/>
/// <reference path='filters.ts'/>

Expand Down
Loading