[packages/openh264] - added firefox33 patch, build GMP plugin
qboosh
qboosh at pld-linux.org
Mon Oct 27 21:59:32 CET 2014
commit af7d046d0707b4c8b59996d79a43100c7865b10a
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date: Mon Oct 27 21:59:25 2014 +0100
- added firefox33 patch, build GMP plugin
openh264-firefox33.patch | 387 +++++++++++++++++++++++++++++++++++++++++++++++
openh264.spec | 56 ++++++-
2 files changed, 441 insertions(+), 2 deletions(-)
---
diff --git a/openh264.spec b/openh264.spec
index 5325a78..2d71278 100644
--- a/openh264.spec
+++ b/openh264.spec
@@ -1,4 +1,8 @@
-# TODO: GMP plugin
+# TODO: handle GMP plugins better in browser-plugins architecture (only firefox33+ based browsers supported)
+#
+# Conditional build:
+%bcond_without xulrunner # GMP plugin
+#
Summary: H.264 codec library
Summary(pl.UTF-8): Biblioteka kodeka H.264
Name: openh264
@@ -8,10 +12,15 @@ License: BSD
Group: Libraries
Source0: https://github.com/cisco/openh264/archive/v%{version}/%{name}-%{version}.tar.gz
# Source0-md5: 2dccd64e0359acbaec54f442792bba67
+Patch0: %{name}-firefox33.patch
URL: http://www.openh264.org/
BuildRequires: libstdc++-devel
+BuildRequires: rpmbuild(macros) >= 1.357
+%{?with_xulrunner:BuildRequires: xulrunner-devel >= 2:33}
BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
+%define gmp_plugindir %{_browserpluginsdir}
+
%description
OpenH264 is a codec library which supports H.264 encoding and
decoding. It is suitable for use in real time applications such as
@@ -47,11 +56,31 @@ Static OpenH264 library.
%description static -l pl.UTF-8
Statyczna biblioteka OpenH264.
+%package -n browser-gmp-openh264
+Summary: OpenH264 plugin for Gecko based browsers
+Summary(pl.UTF-8): Wtyczka OpenH264 dla przeglądarek opartych na Gecko
+License: BSD and MPL v2.0
+Group: Libraries
+Requires: browser-plugins >= 2.0
+
+%description -n browser-gmp-openh264
+OpenH264 Gecko Media Plugin for modern Gecko based browsers (like
+Firefox/Iceweasel 33+).
+
+%description -n browser-gmp-openh264 -l pl.UTF-8
+Wtyczka GMP (Gecko Media Plugin) OpenH264 dla nowych przeglądarek
+opartych na Gecko (takich jak Firefox/Iceweasel 33+).
+
%prep
%setup -q
+%patch0 -p1
+
+%if %{with xulrunner}
+ln -s /usr/include/xulrunner gmp-api
+%endif
%build
-%{__make} \
+%{__make} libraries binaries %{?with_xulrunner:plugin} \
CXX="%{__cxx}" \
CFLAGS_OPT="%{rpmcxxflags}"
@@ -65,12 +94,27 @@ install -d $RPM_BUILD_ROOT{%{_bindir},%{_libdir}}
install libopenh264.so libopenh264.a $RPM_BUILD_ROOT%{_libdir}
install h264dec h264enc $RPM_BUILD_ROOT%{_bindir}
+%if %{with xulrunner}
+# see https://wiki.mozilla.org/GeckoMediaPlugins
+install -d $RPM_BUILD_ROOT%{gmp_plugindir}/gmp-openh264
+install libgmpopenh264.so $RPM_BUILD_ROOT%{gmp_plugindir}/gmp-openh264
+cp -p gmpopenh264.info $RPM_BUILD_ROOT%{gmp_plugindir}/gmp-openh264
+%endif
+
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
+%post -n browser-gmp-openh264
+%update_browser_plugins
+
+%postun -n browser-gmp-openh264
+if [ "$1" = 0 ]; then
+ %update_browser_plugins
+fi
+
%files
%defattr(644,root,root,755)
%doc CONTRIBUTORS LICENSE README.md RELEASES
@@ -85,3 +129,11 @@ rm -rf $RPM_BUILD_ROOT
%files static
%defattr(644,root,root,755)
%{_libdir}/libopenh264.a
+
+%if %{with xulrunner}
+%files -n browser-gmp-openh264
+%defattr(644,root,root,755)
+%dir %{gmp_plugindir}/gmp-openh264
+%attr(755,root,root) %{gmp_plugindir}/gmp-openh264/libgmpopenh264.so
+%{gmp_plugindir}/gmp-openh264/gmpopenh264.info
+%endif
diff --git a/openh264-firefox33.patch b/openh264-firefox33.patch
new file mode 100644
index 0000000..06cd7ed
--- /dev/null
+++ b/openh264-firefox33.patch
@@ -0,0 +1,387 @@
+From 1acb0fb89fed6178057eccb28730bc4156746826 Mon Sep 17 00:00:00 2001
+From: Ethan Hugg <ethanhugg at gmail.com>
+Date: Fri, 11 Jul 2014 08:29:02 -0700
+Subject: [PATCH] Updated to match gmp-api changes for Firefox33
+
+---
+ module/gmp-openh264.cpp | 159 +++++++++++++++++++++++++++++-------------------
+ module/task_utils.h | 3 +
+ 2 files changed, 101 insertions(+), 61 deletions(-)
+
+diff --git a/module/gmp-openh264.cpp b/module/gmp-openh264.cpp
+index a70e883..5996ac8 100644
+--- a/module/gmp-openh264.cpp
++++ b/module/gmp-openh264.cpp
+@@ -190,19 +190,21 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ worker_thread_->Join();
+ }
+
+- virtual GMPVideoErr InitEncode (const GMPVideoCodec& codecSettings,
+- GMPEncoderCallback* callback,
+- int32_t numberOfCores,
+- uint32_t maxPayloadSize) {
++ virtual GMPErr InitEncode (const GMPVideoCodec& codecSettings,
++ const uint8_t* aCodecSpecific,
++ uint32_t aCodecSpecificSize,
++ GMPVideoEncoderCallback* callback,
++ int32_t numberOfCores,
++ uint32_t maxPayloadSize) {
+ GMPErr err = g_platform_api->createthread (&worker_thread_);
+ if (err != GMPNoErr) {
+ GMPLOG (GL_ERROR, "Couldn't create new thread");
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ int rv = WelsCreateSVCEncoder (&encoder_);
+ if (rv) {
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ SEncParamBase param;
+@@ -236,7 +238,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ rv = encoder_->Initialize (¶m);
+ if (rv) {
+ GMPLOG (GL_ERROR, "Couldn't initialize encoder");
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ max_payload_size_ = maxPayloadSize;
+@@ -244,12 +246,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+
+ GMPLOG (GL_INFO, "Initialized encoder");
+
+- return GMPVideoNoErr;
++ return GMPNoErr;
+ }
+
+- virtual GMPVideoErr Encode (GMPVideoi420Frame* inputImage,
+- const GMPCodecSpecificInfo& codecSpecificInfo,
+- const std::vector<GMPVideoFrameType>& frameTypes) {
++ virtual GMPErr Encode (GMPVideoi420Frame* inputImage,
++ const uint8_t* aCodecSpecificInfo,
++ uint32_t aCodecSpecificInfoLength,
++ const GMPVideoFrameType* aFrameTypes,
++ uint32_t aFrameTypesLength) {
+ GMPLOG (GL_DEBUG,
+ __FUNCTION__
+ << " size="
+@@ -257,19 +261,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+
+ stats_.FrameIn();
+
+- assert (!frameTypes.empty());
+- if (frameTypes.empty()) {
+- GMPLOG (GL_ERROR, "No frame types provided");
+- inputImage->Destroy();
+- return GMPVideoGenericErr;
+- }
++ assert (aFrameTypesLength != 0);
+
+ worker_thread_->Post (WrapTask (
+ this, &OpenH264VideoEncoder::Encode_w,
+ inputImage,
+- (frameTypes)[0]));
++ (aFrameTypes)[0]));
+
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ void Encode_w (GMPVideoi420Frame* inputImage,
+@@ -363,8 +362,8 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ GMPVideoFrameType frame_type) {
+ // Now return the encoded data back to the parent.
+ GMPVideoFrame* ftmp;
+- GMPVideoErr err = host_->CreateFrame (kGMPEncodedVideoFrame, &ftmp);
+- if (err != GMPVideoNoErr) {
++ GMPErr err = host_->CreateFrame (kGMPEncodedVideoFrame, &ftmp);
++ if (err != GMPNoErr) {
+ GMPLOG (GL_ERROR, "Error creating encoded frame");
+ frame->Destroy();
+ return;
+@@ -377,17 +376,20 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+
+ for (int i = 0; i < encoded->iLayerNum; ++i) {
+ lengths.push_back (0);
++ uint8_t *tmp = encoded->sLayerInfo[i].pBsBuf;
+ for (int j = 0; j < encoded->sLayerInfo[i].iNalCount; ++j) {
+ lengths[i] += encoded->sLayerInfo[i].pNalLengthInByte[j];
++ // Convert from 4-byte start codes to GMP_BufferLength32 (NAL lengths)
++ assert(*(reinterpret_cast<uint32_t *>(tmp)) == 0x01000000);
++ // BufferType32 doesn't include the length of the length itself!
++ *(reinterpret_cast<uint32_t *>(tmp)) = encoded->sLayerInfo[i].pNalLengthInByte[j] - sizeof(uint32_t);
+ length += encoded->sLayerInfo[i].pNalLengthInByte[j];
++ tmp += encoded->sLayerInfo[i].pNalLengthInByte[j];
+ }
+ }
+
+- // TODO start-code to length conversion here when gmp
+- // stops doing it for us before this call.
+-
+ err = f->CreateEmptyFrame (length);
+- if (err != GMPVideoNoErr) {
++ if (err != GMPNoErr) {
+ GMPLOG (GL_ERROR, "Error allocating frame data");
+ f->Destroy();
+ frame->Destroy();
+@@ -407,6 +409,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ f->SetTimeStamp (frame->Timestamp());
+ f->SetFrameType (frame_type);
+ f->SetCompleteFrame (true);
++ f->SetBufferType (GMP_BufferLength32);
+
+ GMPLOG (GL_DEBUG, "Encoding complete. type= "
+ << f->FrameType()
+@@ -420,9 +423,12 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+
+ // Return the encoded frame.
+ GMPCodecSpecificInfo info;
+- memset (&info, 0, sizeof (info));
+- // TODO need to set what goes in this info structure.
+- callback_->Encoded (f, info);
++ memset (&info, 0, sizeof (info)); // shouldn't be needed, we init everything
++ info.mCodecType = kGMPVideoCodecH264;
++ info.mBufferType = GMP_BufferLength32;
++ info.mCodecSpecific.mH264.mSimulcastIdx = 0;
++
++ callback_->Encoded (f, reinterpret_cast<uint8_t*>(&info), sizeof(info));
+
+ stats_.FrameOut();
+ }
+@@ -432,11 +438,11 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ frame->Destroy();
+ }
+
+- virtual GMPVideoErr SetChannelParameters (uint32_t aPacketLoss, uint32_t aRTT) {
+- return GMPVideoNoErr;
++ virtual GMPErr SetChannelParameters (uint32_t aPacketLoss, uint32_t aRTT) {
++ return GMPNoErr;
+ }
+
+- virtual GMPVideoErr SetRates (uint32_t aNewBitRate, uint32_t aFrameRate) {
++ virtual GMPErr SetRates (uint32_t aNewBitRate, uint32_t aFrameRate) {
+ GMPLOG (GL_INFO, "[SetRates] Begin with: "
+ << aNewBitRate << " , " << aFrameRate);
+ //update bitrate if needed
+@@ -451,7 +457,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ << existEncoderBitRate.iLayer
+ << " ; BR = "
+ << existEncoderBitRate.iBitrate);
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+ if (rv == cmResultSuccess && existEncoderBitRate.iBitrate != newBitRate) {
+ SBitrateInfo newEncoderBitRate;
+@@ -470,7 +476,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ << newEncoderBitRate.iLayer
+ << " ; BR = "
+ << newEncoderBitRate.iBitrate);
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+ }
+ //update framerate if needed
+@@ -479,7 +485,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ if (rv != cmResultSuccess) {
+ GMPLOG (GL_ERROR, "[SetRates] Error in Getting Frame Rate:"
+ << rv << " FrameRate: " << existFrameRate);
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+ if (rv == cmResultSuccess &&
+ (aFrameRate - existFrameRate > 0.001f ||
+@@ -492,14 +498,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ } else {
+ GMPLOG (GL_ERROR, "[SetRates] Error in Setting Frame Rate: ReturnValue: "
+ << rv << " FrameRate: " << aFrameRate);
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+ }
+- return GMPVideoNoErr;
++ return GMPNoErr;
+ }
+
+- virtual GMPVideoErr SetPeriodicKeyFrames (bool aEnable) {
+- return GMPVideoNoErr;
++ virtual GMPErr SetPeriodicKeyFrames (bool aEnable) {
++ return GMPNoErr;
+ }
+
+ virtual void EncodingComplete() {
+@@ -511,7 +517,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
+ GMPThread* worker_thread_;
+ ISVCEncoder* encoder_;
+ uint32_t max_payload_size_;
+- GMPEncoderCallback* callback_;
++ GMPVideoEncoderCallback* callback_;
+ FrameStats stats_;
+ };
+
+@@ -527,25 +533,27 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+ virtual ~OpenH264VideoDecoder() {
+ }
+
+- virtual GMPVideoErr InitDecode (const GMPVideoCodec& codecSettings,
+- GMPDecoderCallback* callback,
+- int32_t coreCount) {
++ virtual GMPErr InitDecode (const GMPVideoCodec& codecSettings,
++ const uint8_t* aCodecSpecific,
++ uint32_t aCodecSpecificSize,
++ GMPVideoDecoderCallback* callback,
++ int32_t coreCount) {
+ GMPLOG (GL_INFO, "InitDecode");
+
+ GMPErr err = g_platform_api->createthread (&worker_thread_);
+ if (err != GMPNoErr) {
+ GMPLOG (GL_ERROR, "Couldn't create new thread");
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ if (WelsCreateDecoder (&decoder_)) {
+ GMPLOG (GL_ERROR, "Couldn't create decoder");
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ if (!decoder_) {
+ GMPLOG (GL_ERROR, "Couldn't create decoder");
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ SDecodingParam param;
+@@ -557,21 +565,50 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+
+ if (decoder_->Initialize (¶m)) {
+ GMPLOG (GL_ERROR, "Couldn't initialize decoder");
+- return GMPVideoGenericErr;
++ return GMPGenericErr;
+ }
+
+ callback_ = callback;
+- return GMPVideoNoErr;
++ return GMPNoErr;
+ }
+
+- virtual GMPVideoErr Decode (GMPVideoEncodedFrame* inputFrame,
+- bool missingFrames,
+- const GMPCodecSpecificInfo& codecSpecificInfo,
+- int64_t renderTimeMs = -1) {
++ virtual GMPErr Decode (GMPVideoEncodedFrame* inputFrame,
++ bool missingFrames,
++ const uint8_t* aCodecSpecificInfo,
++ uint32_t aCodecSpecificInfoLength,
++ int64_t renderTimeMs = -1) {
+ GMPLOG (GL_DEBUG, __FUNCTION__
+ << "Decoding frame size=" << inputFrame->Size()
+ << " timestamp=" << inputFrame->TimeStamp());
+ stats_.FrameIn();
++ //const GMPCodecSpecificInfo *codecSpecificInfo = (GMPCodecSpecificInfo) aCodecSpecificInfo;
++
++ // Convert to H.264 start codes
++ switch (inputFrame->BufferType()) {
++ case GMP_BufferSingle:
++ case GMP_BufferLength8:
++ case GMP_BufferLength16:
++ case GMP_BufferLength24:
++ // We should look to support these, especially GMP_BufferSingle
++ assert(false);
++ break;
++
++ case GMP_BufferLength32:
++ {
++ uint8_t *start_code = inputFrame->Buffer();
++ while (start_code < inputFrame->Buffer() + inputFrame->Size()) {
++ static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
++ uint8_t *lenp = start_code;
++ start_code += *(reinterpret_cast<int32_t *>(lenp));
++ memcpy(lenp, code, 4);
++ }
++ }
++ break;
++
++ default:
++ assert(false);
++ break;
++ }
+
+ worker_thread_->Post (WrapTask (
+ this, &OpenH264VideoDecoder::Decode_w,
+@@ -579,15 +616,15 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+ missingFrames,
+ renderTimeMs));
+
+- return GMPVideoNoErr;
++ return GMPNoErr;
+ }
+
+- virtual GMPVideoErr Reset() {
+- return GMPVideoNoErr;
++ virtual GMPErr Reset() {
++ return GMPNoErr;
+ }
+
+- virtual GMPVideoErr Drain() {
+- return GMPVideoNoErr;
++ virtual GMPErr Drain() {
++ return GMPNoErr;
+ }
+
+ virtual void DecodingComplete() {
+@@ -660,8 +697,8 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+ GMPVideoFrame* ftmp = nullptr;
+
+ // Translate the image.
+- GMPVideoErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp);
+- if (err != GMPVideoNoErr) {
++ GMPErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp);
++ if (err != GMPNoErr) {
+ GMPLOG (GL_ERROR, "Couldn't allocate empty I420 frame");
+ return;
+ }
+@@ -674,7 +711,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+ uvstride * height / 2, static_cast<uint8_t*> (data[2]),
+ width, height,
+ ystride, uvstride, uvstride);
+- if (err != GMPVideoNoErr) {
++ if (err != GMPNoErr) {
+ GMPLOG (GL_ERROR, "Couldn't make decoded frame");
+ return;
+ }
+@@ -682,7 +719,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+ GMPLOG (GL_DEBUG, "Allocated size = "
+ << frame->AllocatedSize (kGMPYPlane));
+ frame->SetTimestamp (inputFrame->TimeStamp());
+- frame->SetRenderTime_ms (renderTimeMs);
++ frame->SetDuration (inputFrame->Duration());
+ callback_->Decoded (frame);
+
+ stats_.FrameOut();
+@@ -690,7 +727,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
+
+ GMPVideoHost* host_;
+ GMPThread* worker_thread_;
+- GMPDecoderCallback* callback_;
++ GMPVideoDecoderCallback* callback_;
+ ISVCDecoder* decoder_;
+ FrameStats stats_;
+ };
+diff --git a/module/task_utils.h b/module/task_utils.h
+index 2bd8937..c53e8d4 100644
+--- a/module/task_utils.h
++++ b/module/task_utils.h
+@@ -13,6 +13,9 @@
+ class gmp_args_base : public GMPTask {
+ public:
+ void Run() = 0;
++ void Destroy() {
++ delete this;
++ }
+ };
+
+ // The generated file contains four major function templates
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/openh264.git/commitdiff/af7d046d0707b4c8b59996d79a43100c7865b10a
More information about the pld-cvs-commit
mailing list