зеркало из https://github.com/mozilla/pjs.git
Bug 508082: Implement a raw video decoder. Based on an earlier patch by Brad Lassey. r=doublec
This commit is contained in:
Родитель
1b8e172772
Коммит
1f722c7f09
|
@ -154,6 +154,7 @@ MOZ_MORK = @MOZ_MORK@
|
||||||
MOZ_MORKREADER = @MOZ_MORKREADER@
|
MOZ_MORKREADER = @MOZ_MORKREADER@
|
||||||
MOZ_NO_FAST_LOAD = @MOZ_NO_FAST_LOAD@
|
MOZ_NO_FAST_LOAD = @MOZ_NO_FAST_LOAD@
|
||||||
MOZ_OGG = @MOZ_OGG@
|
MOZ_OGG = @MOZ_OGG@
|
||||||
|
MOZ_RAW = @MOZ_RAW@
|
||||||
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
||||||
MOZ_WAVE = @MOZ_WAVE@
|
MOZ_WAVE = @MOZ_WAVE@
|
||||||
MOZ_MEDIA = @MOZ_MEDIA@
|
MOZ_MEDIA = @MOZ_MEDIA@
|
||||||
|
|
|
@ -4879,6 +4879,7 @@ MOZ_NO_ACTIVEX_SUPPORT=1
|
||||||
MOZ_NO_INSPECTOR_APIS=
|
MOZ_NO_INSPECTOR_APIS=
|
||||||
MOZ_NO_FAST_LOAD=
|
MOZ_NO_FAST_LOAD=
|
||||||
MOZ_OGG=1
|
MOZ_OGG=1
|
||||||
|
MOZ_RAW=1
|
||||||
MOZ_SYDNEYAUDIO=
|
MOZ_SYDNEYAUDIO=
|
||||||
MOZ_VORBIS=
|
MOZ_VORBIS=
|
||||||
MOZ_WAVE=1
|
MOZ_WAVE=1
|
||||||
|
@ -5827,6 +5828,9 @@ if test -n "$MOZ_NO_FAST_LOAD"; then
|
||||||
AC_DEFINE(MOZ_NO_FAST_LOAD)
|
AC_DEFINE(MOZ_NO_FAST_LOAD)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(MOZ_RAW)
|
||||||
|
AC_DEFINE(MOZ_RAW)
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl = Disable Ogg Codecs
|
dnl = Disable Ogg Codecs
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
|
|
|
@ -96,6 +96,9 @@
|
||||||
#ifdef MOZ_WEBM
|
#ifdef MOZ_WEBM
|
||||||
#include "nsWebMDecoder.h"
|
#include "nsWebMDecoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MOZ_RAW
|
||||||
|
#include "nsRawDecoder.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
static PRLogModuleInfo* gMediaElementLog;
|
static PRLogModuleInfo* gMediaElementLog;
|
||||||
|
@ -1195,6 +1198,36 @@ void nsHTMLMediaElement::UnbindFromTree(PRBool aDeep,
|
||||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_RAW
|
||||||
|
static const char gRawTypes[][16] = {
|
||||||
|
"video/x-raw",
|
||||||
|
"video/x-raw-yuv"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* gRawCodecs[] = {
|
||||||
|
nsnull
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* gRawMaybeCodecs[] = {
|
||||||
|
nsnull
|
||||||
|
};
|
||||||
|
|
||||||
|
static PRBool IsRawEnabled()
|
||||||
|
{
|
||||||
|
return nsContentUtils::GetBoolPref("media.raw.enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
static PRBool IsRawType(const nsACString& aType)
|
||||||
|
{
|
||||||
|
if (!IsRawEnabled())
|
||||||
|
return PR_FALSE;
|
||||||
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(gRawTypes); ++i) {
|
||||||
|
if (aType.EqualsASCII(gRawTypes[i]))
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef MOZ_OGG
|
#ifdef MOZ_OGG
|
||||||
// See http://www.rfc-editor.org/rfc/rfc5334.txt for the definitions
|
// See http://www.rfc-editor.org/rfc/rfc5334.txt for the definitions
|
||||||
// of Ogg media types and codec types
|
// of Ogg media types and codec types
|
||||||
|
@ -1301,6 +1334,12 @@ nsHTMLMediaElement::CanPlayStatus
|
||||||
nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType,
|
nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType,
|
||||||
char const *const ** aCodecList)
|
char const *const ** aCodecList)
|
||||||
{
|
{
|
||||||
|
#ifdef MOZ_RAW
|
||||||
|
if (IsRawType(nsDependentCString(aMIMEType))) {
|
||||||
|
*aCodecList = gRawCodecs;
|
||||||
|
return CANPLAY_MAYBE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef MOZ_OGG
|
#ifdef MOZ_OGG
|
||||||
if (IsOggType(nsDependentCString(aMIMEType))) {
|
if (IsOggType(nsDependentCString(aMIMEType))) {
|
||||||
*aCodecList = gOggCodecs;
|
*aCodecList = gOggCodecs;
|
||||||
|
@ -1325,6 +1364,10 @@ nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType,
|
||||||
/* static */
|
/* static */
|
||||||
PRBool nsHTMLMediaElement::ShouldHandleMediaType(const char* aMIMEType)
|
PRBool nsHTMLMediaElement::ShouldHandleMediaType(const char* aMIMEType)
|
||||||
{
|
{
|
||||||
|
#ifdef MOZ_RAW
|
||||||
|
if (IsRawType(nsDependentCString(aMIMEType)))
|
||||||
|
return PR_TRUE;
|
||||||
|
#endif
|
||||||
#ifdef MOZ_OGG
|
#ifdef MOZ_OGG
|
||||||
if (IsOggType(nsDependentCString(aMIMEType)))
|
if (IsOggType(nsDependentCString(aMIMEType)))
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
@ -1411,6 +1454,14 @@ nsHTMLMediaElement::CanPlayType(const nsAString& aType, nsAString& aResult)
|
||||||
already_AddRefed<nsMediaDecoder>
|
already_AddRefed<nsMediaDecoder>
|
||||||
nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
|
nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
|
||||||
{
|
{
|
||||||
|
#ifdef MOZ_RAW
|
||||||
|
if (IsRawType(aType)) {
|
||||||
|
nsRefPtr<nsRawDecoder> decoder = new nsRawDecoder();
|
||||||
|
if (decoder && decoder->Init(this)) {
|
||||||
|
return decoder.forget().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef MOZ_OGG
|
#ifdef MOZ_OGG
|
||||||
if (IsOggType(aType)) {
|
if (IsOggType(aType)) {
|
||||||
nsRefPtr<nsOggDecoder> decoder = new nsOggDecoder();
|
nsRefPtr<nsOggDecoder> decoder = new nsOggDecoder();
|
||||||
|
|
|
@ -73,6 +73,10 @@ CPPSRCS += \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef MOZ_RAW
|
||||||
|
PARALLEL_DIRS += raw
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef MOZ_OGG
|
ifdef MOZ_OGG
|
||||||
PARALLEL_DIRS += ogg
|
PARALLEL_DIRS += ogg
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -59,6 +59,18 @@
|
||||||
#define PR_INT64_MIN (-PR_INT64_MAX - 1)
|
#define PR_INT64_MIN (-PR_INT64_MAX - 1)
|
||||||
#define PR_UINT64_MAX (~(PRUint64)(0))
|
#define PR_UINT64_MAX (~(PRUint64)(0))
|
||||||
|
|
||||||
|
static PRBool MulOverflow32(PRUint32 a, PRUint32 b, PRUint32 &aResult)
|
||||||
|
{
|
||||||
|
PRUint64 rl = static_cast<PRUint64>(a) * static_cast<PRUint64>(b);
|
||||||
|
|
||||||
|
if (rl > PR_UINT32_MAX) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
aResult = static_cast<PRUint32>(rl);
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// This belongs in xpcom/monitor/Monitor.h, once we've made
|
// This belongs in xpcom/monitor/Monitor.h, once we've made
|
||||||
// mozilla::Monitor non-reentrant.
|
// mozilla::Monitor non-reentrant.
|
||||||
|
|
|
@ -61,20 +61,6 @@ static PRBool AddOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult);
|
||||||
// in an integer overflow.
|
// in an integer overflow.
|
||||||
static PRBool MulOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult);
|
static PRBool MulOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult);
|
||||||
|
|
||||||
static PRBool MulOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult)
|
|
||||||
{
|
|
||||||
// 32 bit integer multiplication with overflow checking. Returns PR_TRUE
|
|
||||||
// if the multiplication was successful, or PR_FALSE if the operation resulted
|
|
||||||
// in an integer overflow.
|
|
||||||
PRUint64 a64 = a;
|
|
||||||
PRUint64 b64 = b;
|
|
||||||
PRUint64 r64 = a64 * b64;
|
|
||||||
if (r64 > PR_UINT32_MAX)
|
|
||||||
return PR_FALSE;
|
|
||||||
aResult = static_cast<PRUint32>(r64);
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsOggCodecState*
|
nsOggCodecState*
|
||||||
nsOggCodecState::Create(ogg_page* aPage)
|
nsOggCodecState::Create(ogg_page* aPage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
# 1.1 (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.mozilla.org/MPL/
|
||||||
|
#
|
||||||
|
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
# for the specific language governing rights and limitations under the
|
||||||
|
# License.
|
||||||
|
#
|
||||||
|
# The Original Code is Mozilla Raw Decoder code.
|
||||||
|
#
|
||||||
|
# The Initial Developer of the Original Code is
|
||||||
|
# Mozilla Foundation.
|
||||||
|
# Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
# the Initial Developer. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Contributor(s):
|
||||||
|
# Brad Lassey <blassey@mozilla.com>
|
||||||
|
#
|
||||||
|
# Alternatively, the contents of this file may be used under the terms of
|
||||||
|
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
# of those above. If you wish to allow use of your version of this file only
|
||||||
|
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
# use your version of this file under the terms of the MPL, indicate your
|
||||||
|
# decision by deleting the provisions above and replace them with the notice
|
||||||
|
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
# the provisions above, a recipient may use your version of this file under
|
||||||
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
|
||||||
|
DEPTH = ../../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = content
|
||||||
|
LIBRARY_NAME = gkconraw_s
|
||||||
|
LIBXUL_LIBRARY = 1
|
||||||
|
|
||||||
|
EXPORTS += \
|
||||||
|
nsRawDecoder.h \
|
||||||
|
nsRawReader.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
CPPSRCS += \
|
||||||
|
nsRawDecoder.cpp \
|
||||||
|
nsRawReader.cpp \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
FORCE_STATIC_LIB = 1
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
INCLUDES += \
|
||||||
|
-I$(srcdir)/../../base/src \
|
||||||
|
-I$(srcdir)/../../html/content/src \
|
||||||
|
$(NULL)
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (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.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Raw Decoder code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsBuiltinDecoderStateMachine.h"
|
||||||
|
#include "nsRawReader.h"
|
||||||
|
#include "nsRawDecoder.h"
|
||||||
|
|
||||||
|
nsDecoderStateMachine* nsRawDecoder::CreateStateMachine()
|
||||||
|
{
|
||||||
|
return new nsBuiltinDecoderStateMachine(this, new nsRawReader(this));
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (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.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Raw Decoder code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#if !defined(nsRawDecoder_h_)
|
||||||
|
#define nsRawDecoder_h_
|
||||||
|
|
||||||
|
#include "nsBuiltinDecoder.h"
|
||||||
|
|
||||||
|
class nsRawDecoder : public nsBuiltinDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual nsMediaDecoder* Clone() { return new nsRawDecoder(); }
|
||||||
|
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,299 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (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.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brad Lassey <blassey@mozilla.com>
|
||||||
|
* Kyle Huey <me@kylehuey.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsBuiltinDecoderStateMachine.h"
|
||||||
|
#include "nsBuiltinDecoder.h"
|
||||||
|
#include "nsRawReader.h"
|
||||||
|
#include "nsRawDecoder.h"
|
||||||
|
#include "VideoUtils.h"
|
||||||
|
|
||||||
|
#define RAW_ID 0x595556
|
||||||
|
|
||||||
|
nsRawReader::nsRawReader(nsBuiltinDecoder* aDecoder)
|
||||||
|
: nsBuiltinDecoderReader(aDecoder),
|
||||||
|
mCurrentFrame(0)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(nsRawReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRawReader::~nsRawReader()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(nsRawReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsRawReader::Init()
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsRawReader::ResetDecode()
|
||||||
|
{
|
||||||
|
mCurrentFrame = 0;
|
||||||
|
return nsBuiltinDecoderReader::ResetDecode();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsRawReader::ReadMetadata()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mDecoder->OnStateMachineThread(),
|
||||||
|
"Should be on state machine thread.");
|
||||||
|
mozilla::MonitorAutoEnter autoEnter(mMonitor);
|
||||||
|
|
||||||
|
nsMediaStream* stream = mDecoder->GetCurrentStream();
|
||||||
|
NS_ASSERTION(stream, "Decoder has no media stream");
|
||||||
|
|
||||||
|
if (!ReadFromStream(stream, reinterpret_cast<PRUint8*>(&mMetadata),
|
||||||
|
sizeof(mMetadata)))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// Validate the header
|
||||||
|
if (!(mMetadata.headerPacketID == 0 /* Packet ID of 0 for the header*/ &&
|
||||||
|
mMetadata.codecID == RAW_ID /* "YUV" */ &&
|
||||||
|
mMetadata.majorVersion == 0 &&
|
||||||
|
mMetadata.minorVersion == 1))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRUint32 dummy;
|
||||||
|
if (!MulOverflow32(mMetadata.frameWidth, mMetadata.frameHeight, dummy))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
mInfo.mHasVideo = PR_TRUE;
|
||||||
|
mInfo.mPicture.x = 0;
|
||||||
|
mInfo.mPicture.y = 0;
|
||||||
|
mInfo.mPicture.width = mMetadata.frameWidth;
|
||||||
|
mInfo.mPicture.height = mMetadata.frameHeight;
|
||||||
|
mInfo.mFrame.width = mMetadata.frameWidth;
|
||||||
|
mInfo.mFrame.height = mMetadata.frameHeight;
|
||||||
|
if (mMetadata.aspectDenominator == 0 ||
|
||||||
|
mMetadata.framerateDenominator == 0)
|
||||||
|
return NS_ERROR_FAILURE; // Invalid data
|
||||||
|
mInfo.mPixelAspectRatio = static_cast<float>(mMetadata.aspectNumerator) /
|
||||||
|
mMetadata.aspectDenominator;
|
||||||
|
mInfo.mDataOffset = sizeof(nsRawVideoHeader) + 1;
|
||||||
|
mInfo.mHasAudio = PR_FALSE;
|
||||||
|
|
||||||
|
mFrameRate = static_cast<float>(mMetadata.framerateNumerator) /
|
||||||
|
mMetadata.framerateDenominator;
|
||||||
|
|
||||||
|
// Make some sanity checks
|
||||||
|
if (mFrameRate > 45 ||
|
||||||
|
mFrameRate == 0 ||
|
||||||
|
mInfo.mPixelAspectRatio == 0 ||
|
||||||
|
mMetadata.frameWidth > 2000 ||
|
||||||
|
mMetadata.frameHeight > 2000 ||
|
||||||
|
mMetadata.chromaChannelBpp != 4 ||
|
||||||
|
mMetadata.lumaChannelBpp != 8 ||
|
||||||
|
mMetadata.colorspace != 1 /* 4:2:0 */)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
mFrameSize = mMetadata.frameWidth * mMetadata.frameHeight *
|
||||||
|
(mMetadata.lumaChannelBpp + mMetadata.chromaChannelBpp) / 8.0 +
|
||||||
|
sizeof(nsRawPacketHeader);
|
||||||
|
|
||||||
|
PRInt64 length = stream->GetLength();
|
||||||
|
if (length != -1) {
|
||||||
|
mozilla::MonitorAutoExit autoExitMonitor(mMonitor);
|
||||||
|
mozilla::MonitorAutoEnter autoMonitor(mDecoder->GetMonitor());
|
||||||
|
mDecoder->GetStateMachine()->SetDuration(1000 *
|
||||||
|
(length - sizeof(nsRawVideoHeader)) /
|
||||||
|
(mFrameSize * mFrameRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsRawReader::DecodeAudioData()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
|
||||||
|
"Should be on state machine thread or decode thread.");
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method that either reads until it gets aLength bytes
|
||||||
|
// or returns PR_FALSE
|
||||||
|
PRBool nsRawReader::ReadFromStream(nsMediaStream *aStream, PRUint8* aBuf,
|
||||||
|
PRUint32 aLength)
|
||||||
|
{
|
||||||
|
while (aLength > 0) {
|
||||||
|
PRUint32 bytesRead = 0;
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
rv = aStream->Read(reinterpret_cast<char*>(aBuf), aLength, &bytesRead);
|
||||||
|
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||||
|
|
||||||
|
if (bytesRead == 0) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
aLength -= bytesRead;
|
||||||
|
aBuf += bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsRawReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
|
||||||
|
PRInt64 aTimeThreshold)
|
||||||
|
{
|
||||||
|
mozilla::MonitorAutoEnter autoEnter(mMonitor);
|
||||||
|
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
|
||||||
|
"Should be on state machine thread or decode thread.");
|
||||||
|
|
||||||
|
PRInt64 currentFrameTime = 1000 * mCurrentFrame / mFrameRate;
|
||||||
|
PRUint32 length = mFrameSize - sizeof(nsRawPacketHeader);
|
||||||
|
|
||||||
|
nsAutoPtr<PRUint8> buffer(new PRUint8[length]);
|
||||||
|
nsMediaStream* stream = mDecoder->GetCurrentStream();
|
||||||
|
NS_ASSERTION(stream, "Decoder has no media stream");
|
||||||
|
|
||||||
|
// We're always decoding one frame when called
|
||||||
|
while(true) {
|
||||||
|
nsRawPacketHeader header;
|
||||||
|
|
||||||
|
// Read in a packet header and validate
|
||||||
|
if (!(ReadFromStream(stream, reinterpret_cast<PRUint8*>(&header),
|
||||||
|
sizeof(header))) ||
|
||||||
|
!(header.packetID == 0xFF && header.codecID == RAW_ID /* "YUV" */)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReadFromStream(stream, buffer, length)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFrameTime >= aTimeThreshold)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mCurrentFrame++;
|
||||||
|
currentFrameTime += 1000.0 / mFrameRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoData::YCbCrBuffer b;
|
||||||
|
b.mPlanes[0].mData = buffer;
|
||||||
|
b.mPlanes[0].mStride = mMetadata.frameWidth * mMetadata.lumaChannelBpp / 8.0;
|
||||||
|
b.mPlanes[0].mHeight = mMetadata.frameHeight;
|
||||||
|
b.mPlanes[0].mWidth = mMetadata.frameWidth;
|
||||||
|
|
||||||
|
PRUint32 cbcrStride = mMetadata.frameWidth * mMetadata.chromaChannelBpp / 8.0;
|
||||||
|
|
||||||
|
b.mPlanes[1].mData = buffer + mMetadata.frameHeight * b.mPlanes[0].mStride;
|
||||||
|
b.mPlanes[1].mStride = cbcrStride;
|
||||||
|
b.mPlanes[1].mHeight = mMetadata.frameHeight / 2;
|
||||||
|
b.mPlanes[1].mWidth = mMetadata.frameWidth / 2;
|
||||||
|
|
||||||
|
b.mPlanes[2].mData = b.mPlanes[1].mData + mMetadata.frameHeight * cbcrStride / 2;
|
||||||
|
b.mPlanes[2].mStride = cbcrStride;
|
||||||
|
b.mPlanes[2].mHeight = mMetadata.frameHeight / 2;
|
||||||
|
b.mPlanes[2].mWidth = mMetadata.frameWidth / 2;
|
||||||
|
|
||||||
|
VideoData *v = VideoData::Create(mInfo,
|
||||||
|
mDecoder->GetImageContainer(),
|
||||||
|
-1,
|
||||||
|
currentFrameTime,
|
||||||
|
currentFrameTime + (1000 / mFrameRate),
|
||||||
|
b,
|
||||||
|
1, // In raw video every frame is a keyframe
|
||||||
|
-1);
|
||||||
|
if (!v)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
mVideoQueue.Push(v);
|
||||||
|
mCurrentFrame++;
|
||||||
|
currentFrameTime += 1000 / mFrameRate;
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime)
|
||||||
|
{
|
||||||
|
mozilla::MonitorAutoEnter autoEnter(mMonitor);
|
||||||
|
NS_ASSERTION(mDecoder->OnStateMachineThread(),
|
||||||
|
"Should be on state machine thread.");
|
||||||
|
|
||||||
|
nsMediaStream *stream = mDecoder->GetCurrentStream();
|
||||||
|
NS_ASSERTION(stream, "Decoder has no media stream");
|
||||||
|
|
||||||
|
PRUint32 frame = mCurrentFrame;
|
||||||
|
if (aTime >= UINT_MAX)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
mCurrentFrame = aTime * mFrameRate / 1000;
|
||||||
|
|
||||||
|
PRUint32 offset;
|
||||||
|
if (!MulOverflow32(mCurrentFrame, mFrameSize, offset))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
offset += sizeof(nsRawVideoHeader);
|
||||||
|
|
||||||
|
nsresult rv = stream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
mVideoQueue.Erase();
|
||||||
|
|
||||||
|
while(mVideoQueue.GetSize() == 0) {
|
||||||
|
PRBool keyframeSkip = PR_FALSE;
|
||||||
|
if (!DecodeVideoFrame(keyframeSkip, 0)) {
|
||||||
|
mCurrentFrame = frame;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
mozilla::MonitorAutoExit autoMonitorExit(mMonitor);
|
||||||
|
mozilla::MonitorAutoEnter autoMonitor(mDecoder->GetMonitor());
|
||||||
|
if (mDecoder->GetDecodeState() ==
|
||||||
|
nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
|
||||||
|
mCurrentFrame = frame;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoPtr<VideoData> video(mVideoQueue.PeekFront());
|
||||||
|
if (video && video->mEndTime < aTime) {
|
||||||
|
mVideoQueue.PopFront();
|
||||||
|
video = nsnull;
|
||||||
|
} else {
|
||||||
|
video.forget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt64 nsRawReader::FindEndTime(PRInt64 aEndTime)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (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.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brad Lassey
|
||||||
|
* Kyle Huey <me@kylehuey.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#if !defined(nsRawReader_h_)
|
||||||
|
#define nsRawReader_h_
|
||||||
|
|
||||||
|
#include "nsBuiltinDecoderReader.h"
|
||||||
|
|
||||||
|
struct nsRawVideo_PRUint24 {
|
||||||
|
operator PRUint32() const { return value[2] << 16 | value[1] << 8 | value[0]; }
|
||||||
|
private:
|
||||||
|
PRUint8 value[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nsRawPacketHeader {
|
||||||
|
typedef nsRawVideo_PRUint24 PRUint24;
|
||||||
|
PRUint8 packetID;
|
||||||
|
PRUint24 codecID;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is Arc's draft from wiki.xiph.org/OggYUV
|
||||||
|
struct nsRawVideoHeader {
|
||||||
|
typedef nsRawVideo_PRUint24 PRUint24;
|
||||||
|
PRUint8 headerPacketID; // Header Packet ID (always 0)
|
||||||
|
PRUint24 codecID; // Codec identifier (always "YUV")
|
||||||
|
PRUint8 majorVersion; // Version Major (breaks backwards compat)
|
||||||
|
PRUint8 minorVersion; // Version Minor (preserves backwards compat)
|
||||||
|
PRUint16 options; // Bit 1: Color (false = B/W)
|
||||||
|
// Bits 2-4: Chroma Pixel Shape
|
||||||
|
// Bit 5: 50% horizontal offset for Cr samples
|
||||||
|
// Bit 6: 50% vertical ...
|
||||||
|
// Bits 7-8: Chroma Blending
|
||||||
|
// Bit 9: Packed (false = Planar)
|
||||||
|
// Bit 10: Cr Staggered Horizontally
|
||||||
|
// Bit 11: Cr Staggered Vertically
|
||||||
|
// Bit 12: Unused (format is always little endian)
|
||||||
|
// Bit 13: Interlaced (false = Progressive)
|
||||||
|
// Bits 14-16: Interlace options (undefined)
|
||||||
|
|
||||||
|
PRUint8 alphaChannelBpp;
|
||||||
|
PRUint8 lumaChannelBpp;
|
||||||
|
PRUint8 chromaChannelBpp;
|
||||||
|
PRUint8 colorspace;
|
||||||
|
|
||||||
|
PRUint24 frameWidth;
|
||||||
|
PRUint24 frameHeight;
|
||||||
|
PRUint24 aspectNumerator;
|
||||||
|
PRUint24 aspectDenominator;
|
||||||
|
|
||||||
|
PRUint32 framerateNumerator;
|
||||||
|
PRUint32 framerateDenominator;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsRawReader : public nsBuiltinDecoderReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsRawReader(nsBuiltinDecoder* aDecoder);
|
||||||
|
~nsRawReader();
|
||||||
|
|
||||||
|
virtual nsresult Init();
|
||||||
|
virtual nsresult ResetDecode();
|
||||||
|
virtual PRBool DecodeAudioData();
|
||||||
|
|
||||||
|
virtual PRBool DecodeVideoFrame(PRBool &aKeyframeSkip,
|
||||||
|
PRInt64 aTimeThreshold);
|
||||||
|
|
||||||
|
virtual PRBool HasAudio()
|
||||||
|
{
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual PRBool HasVideo()
|
||||||
|
{
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual nsresult ReadMetadata();
|
||||||
|
virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime);
|
||||||
|
virtual PRInt64 FindEndTime(PRInt64 aEndOffset);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PRBool ReadFromStream(nsMediaStream *aStream, PRUint8 *aBuf,
|
||||||
|
PRUint32 aLength);
|
||||||
|
|
||||||
|
nsRawVideoHeader mMetadata;
|
||||||
|
PRUint32 mCurrentFrame;
|
||||||
|
double mFrameRate;
|
||||||
|
PRUint32 mFrameSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -195,6 +195,7 @@ _TEST_FILES += \
|
||||||
dirac.ogg \
|
dirac.ogg \
|
||||||
seek.ogv \
|
seek.ogv \
|
||||||
seek.webm \
|
seek.webm \
|
||||||
|
seek.yuv \
|
||||||
short-video.ogv \
|
short-video.ogv \
|
||||||
small-shot.ogg \
|
small-shot.ogg \
|
||||||
sound.ogg \
|
sound.ogg \
|
||||||
|
|
|
@ -104,6 +104,9 @@ var gPlayTests = [
|
||||||
// Test playback of a webm file
|
// Test playback of a webm file
|
||||||
{ name:"seek.webm", type:"video/webm", duration:3.966 },
|
{ name:"seek.webm", type:"video/webm", duration:3.966 },
|
||||||
|
|
||||||
|
// Test playback of a raw file
|
||||||
|
{ name:"seek.yuv", type:"video/x-raw-yuv", duration:1.833 },
|
||||||
|
|
||||||
{ name:"bogus.duh", type:"bogus/duh", duration:Number.NaN }
|
{ name:"bogus.duh", type:"bogus/duh", duration:Number.NaN }
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
Двоичный файл не отображается.
|
@ -169,6 +169,10 @@ SHARED_LIBRARY_LIBS += \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
SHARED_LIBRARY_LIBS += \
|
||||||
|
$(DEPTH)/content/media/raw/$(LIB_PREFIX)gkconraw_s.$(LIB_SUFFIX)\
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
ifdef MOZ_WEBM
|
ifdef MOZ_WEBM
|
||||||
SHARED_LIBRARY_LIBS += \
|
SHARED_LIBRARY_LIBS += \
|
||||||
$(DEPTH)/content/media/webm/$(LIB_PREFIX)gkconwebm_s.$(LIB_SUFFIX) \
|
$(DEPTH)/content/media/webm/$(LIB_PREFIX)gkconwebm_s.$(LIB_SUFFIX) \
|
||||||
|
|
|
@ -156,6 +156,9 @@ pref("media.enforce_same_site_origin", false);
|
||||||
// Media cache size in kilobytes
|
// Media cache size in kilobytes
|
||||||
pref("media.cache_size", 512000);
|
pref("media.cache_size", 512000);
|
||||||
|
|
||||||
|
#ifdef MOZ_RAW
|
||||||
|
pref("media.raw.enabled", true);
|
||||||
|
#endif
|
||||||
#ifdef MOZ_OGG
|
#ifdef MOZ_OGG
|
||||||
pref("media.ogg.enabled", true);
|
pref("media.ogg.enabled", true);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -156,6 +156,7 @@
|
||||||
#define TEXT_XSL "text/xsl"
|
#define TEXT_XSL "text/xsl"
|
||||||
|
|
||||||
#define VIDEO_MPEG "video/mpeg"
|
#define VIDEO_MPEG "video/mpeg"
|
||||||
|
#define VIDEO_RAW "video/x-raw-yuv"
|
||||||
#define VIDEO_OGG "video/ogg"
|
#define VIDEO_OGG "video/ogg"
|
||||||
#define VIDEO_WEBM "video/webm"
|
#define VIDEO_WEBM "video/webm"
|
||||||
#define APPLICATION_OGG "application/ogg"
|
#define APPLICATION_OGG "application/ogg"
|
||||||
|
|
|
@ -544,6 +544,7 @@ static nsExtraMimeTypeEntry extraMimeEntries [] =
|
||||||
{ VIDEO_WEBM, "webm", "Web Media Video" },
|
{ VIDEO_WEBM, "webm", "Web Media Video" },
|
||||||
{ AUDIO_WEBM, "webm", "Web Media Audio" },
|
{ AUDIO_WEBM, "webm", "Web Media Audio" },
|
||||||
#endif
|
#endif
|
||||||
|
{ VIDEO_RAW, "yuv", "Raw YUV Video" },
|
||||||
{ AUDIO_WAV, "wav", "Waveform Audio" },
|
{ AUDIO_WAV, "wav", "Waveform Audio" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче