[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 (&param);
+     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 (&param)) {
+       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