1 From 1acb0fb89fed6178057eccb28730bc4156746826 Mon Sep 17 00:00:00 2001
2 From: Ethan Hugg <ethanhugg@gmail.com>
3 Date: Fri, 11 Jul 2014 08:29:02 -0700
4 Subject: [PATCH] Updated to match gmp-api changes for Firefox33
7 module/gmp-openh264.cpp | 159 +++++++++++++++++++++++++++++-------------------
8 module/task_utils.h | 3 +
9 2 files changed, 101 insertions(+), 61 deletions(-)
11 diff --git a/module/gmp-openh264.cpp b/module/gmp-openh264.cpp
12 index a70e883..5996ac8 100644
13 --- a/module/gmp-openh264.cpp
14 +++ b/module/gmp-openh264.cpp
15 @@ -190,19 +190,21 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
16 worker_thread_->Join();
19 - virtual GMPVideoErr InitEncode (const GMPVideoCodec& codecSettings,
20 - GMPEncoderCallback* callback,
21 - int32_t numberOfCores,
22 - uint32_t maxPayloadSize) {
23 + virtual GMPErr InitEncode (const GMPVideoCodec& codecSettings,
24 + const uint8_t* aCodecSpecific,
25 + uint32_t aCodecSpecificSize,
26 + GMPVideoEncoderCallback* callback,
27 + int32_t numberOfCores,
28 + uint32_t maxPayloadSize) {
29 GMPErr err = g_platform_api->createthread (&worker_thread_);
30 if (err != GMPNoErr) {
31 GMPLOG (GL_ERROR, "Couldn't create new thread");
32 - return GMPVideoGenericErr;
33 + return GMPGenericErr;
36 int rv = WelsCreateSVCEncoder (&encoder_);
38 - return GMPVideoGenericErr;
39 + return GMPGenericErr;
43 @@ -236,7 +238,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
44 rv = encoder_->Initialize (¶m);
46 GMPLOG (GL_ERROR, "Couldn't initialize encoder");
47 - return GMPVideoGenericErr;
48 + return GMPGenericErr;
51 max_payload_size_ = maxPayloadSize;
52 @@ -244,12 +246,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
54 GMPLOG (GL_INFO, "Initialized encoder");
56 - return GMPVideoNoErr;
60 - virtual GMPVideoErr Encode (GMPVideoi420Frame* inputImage,
61 - const GMPCodecSpecificInfo& codecSpecificInfo,
62 - const std::vector<GMPVideoFrameType>& frameTypes) {
63 + virtual GMPErr Encode (GMPVideoi420Frame* inputImage,
64 + const uint8_t* aCodecSpecificInfo,
65 + uint32_t aCodecSpecificInfoLength,
66 + const GMPVideoFrameType* aFrameTypes,
67 + uint32_t aFrameTypesLength) {
71 @@ -257,19 +261,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
75 - assert (!frameTypes.empty());
76 - if (frameTypes.empty()) {
77 - GMPLOG (GL_ERROR, "No frame types provided");
78 - inputImage->Destroy();
79 - return GMPVideoGenericErr;
81 + assert (aFrameTypesLength != 0);
83 worker_thread_->Post (WrapTask (
84 this, &OpenH264VideoEncoder::Encode_w,
89 - return GMPVideoGenericErr;
90 + return GMPGenericErr;
93 void Encode_w (GMPVideoi420Frame* inputImage,
94 @@ -363,8 +362,8 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
95 GMPVideoFrameType frame_type) {
96 // Now return the encoded data back to the parent.
98 - GMPVideoErr err = host_->CreateFrame (kGMPEncodedVideoFrame, &ftmp);
99 - if (err != GMPVideoNoErr) {
100 + GMPErr err = host_->CreateFrame (kGMPEncodedVideoFrame, &ftmp);
101 + if (err != GMPNoErr) {
102 GMPLOG (GL_ERROR, "Error creating encoded frame");
105 @@ -377,17 +376,20 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
107 for (int i = 0; i < encoded->iLayerNum; ++i) {
108 lengths.push_back (0);
109 + uint8_t *tmp = encoded->sLayerInfo[i].pBsBuf;
110 for (int j = 0; j < encoded->sLayerInfo[i].iNalCount; ++j) {
111 lengths[i] += encoded->sLayerInfo[i].pNalLengthInByte[j];
112 + // Convert from 4-byte start codes to GMP_BufferLength32 (NAL lengths)
113 + assert(*(reinterpret_cast<uint32_t *>(tmp)) == 0x01000000);
114 + // BufferType32 doesn't include the length of the length itself!
115 + *(reinterpret_cast<uint32_t *>(tmp)) = encoded->sLayerInfo[i].pNalLengthInByte[j] - sizeof(uint32_t);
116 length += encoded->sLayerInfo[i].pNalLengthInByte[j];
117 + tmp += encoded->sLayerInfo[i].pNalLengthInByte[j];
121 - // TODO start-code to length conversion here when gmp
122 - // stops doing it for us before this call.
124 err = f->CreateEmptyFrame (length);
125 - if (err != GMPVideoNoErr) {
126 + if (err != GMPNoErr) {
127 GMPLOG (GL_ERROR, "Error allocating frame data");
130 @@ -407,6 +409,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
131 f->SetTimeStamp (frame->Timestamp());
132 f->SetFrameType (frame_type);
133 f->SetCompleteFrame (true);
134 + f->SetBufferType (GMP_BufferLength32);
136 GMPLOG (GL_DEBUG, "Encoding complete. type= "
138 @@ -420,9 +423,12 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
140 // Return the encoded frame.
141 GMPCodecSpecificInfo info;
142 - memset (&info, 0, sizeof (info));
143 - // TODO need to set what goes in this info structure.
144 - callback_->Encoded (f, info);
145 + memset (&info, 0, sizeof (info)); // shouldn't be needed, we init everything
146 + info.mCodecType = kGMPVideoCodecH264;
147 + info.mBufferType = GMP_BufferLength32;
148 + info.mCodecSpecific.mH264.mSimulcastIdx = 0;
150 + callback_->Encoded (f, reinterpret_cast<uint8_t*>(&info), sizeof(info));
154 @@ -432,11 +438,11 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
158 - virtual GMPVideoErr SetChannelParameters (uint32_t aPacketLoss, uint32_t aRTT) {
159 - return GMPVideoNoErr;
160 + virtual GMPErr SetChannelParameters (uint32_t aPacketLoss, uint32_t aRTT) {
164 - virtual GMPVideoErr SetRates (uint32_t aNewBitRate, uint32_t aFrameRate) {
165 + virtual GMPErr SetRates (uint32_t aNewBitRate, uint32_t aFrameRate) {
166 GMPLOG (GL_INFO, "[SetRates] Begin with: "
167 << aNewBitRate << " , " << aFrameRate);
168 //update bitrate if needed
169 @@ -451,7 +457,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
170 << existEncoderBitRate.iLayer
172 << existEncoderBitRate.iBitrate);
173 - return GMPVideoGenericErr;
174 + return GMPGenericErr;
176 if (rv == cmResultSuccess && existEncoderBitRate.iBitrate != newBitRate) {
177 SBitrateInfo newEncoderBitRate;
178 @@ -470,7 +476,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
179 << newEncoderBitRate.iLayer
181 << newEncoderBitRate.iBitrate);
182 - return GMPVideoGenericErr;
183 + return GMPGenericErr;
186 //update framerate if needed
187 @@ -479,7 +485,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
188 if (rv != cmResultSuccess) {
189 GMPLOG (GL_ERROR, "[SetRates] Error in Getting Frame Rate:"
190 << rv << " FrameRate: " << existFrameRate);
191 - return GMPVideoGenericErr;
192 + return GMPGenericErr;
194 if (rv == cmResultSuccess &&
195 (aFrameRate - existFrameRate > 0.001f ||
196 @@ -492,14 +498,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
198 GMPLOG (GL_ERROR, "[SetRates] Error in Setting Frame Rate: ReturnValue: "
199 << rv << " FrameRate: " << aFrameRate);
200 - return GMPVideoGenericErr;
201 + return GMPGenericErr;
204 - return GMPVideoNoErr;
208 - virtual GMPVideoErr SetPeriodicKeyFrames (bool aEnable) {
209 - return GMPVideoNoErr;
210 + virtual GMPErr SetPeriodicKeyFrames (bool aEnable) {
214 virtual void EncodingComplete() {
215 @@ -511,7 +517,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
216 GMPThread* worker_thread_;
217 ISVCEncoder* encoder_;
218 uint32_t max_payload_size_;
219 - GMPEncoderCallback* callback_;
220 + GMPVideoEncoderCallback* callback_;
224 @@ -527,25 +533,27 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
225 virtual ~OpenH264VideoDecoder() {
228 - virtual GMPVideoErr InitDecode (const GMPVideoCodec& codecSettings,
229 - GMPDecoderCallback* callback,
230 - int32_t coreCount) {
231 + virtual GMPErr InitDecode (const GMPVideoCodec& codecSettings,
232 + const uint8_t* aCodecSpecific,
233 + uint32_t aCodecSpecificSize,
234 + GMPVideoDecoderCallback* callback,
235 + int32_t coreCount) {
236 GMPLOG (GL_INFO, "InitDecode");
238 GMPErr err = g_platform_api->createthread (&worker_thread_);
239 if (err != GMPNoErr) {
240 GMPLOG (GL_ERROR, "Couldn't create new thread");
241 - return GMPVideoGenericErr;
242 + return GMPGenericErr;
245 if (WelsCreateDecoder (&decoder_)) {
246 GMPLOG (GL_ERROR, "Couldn't create decoder");
247 - return GMPVideoGenericErr;
248 + return GMPGenericErr;
252 GMPLOG (GL_ERROR, "Couldn't create decoder");
253 - return GMPVideoGenericErr;
254 + return GMPGenericErr;
257 SDecodingParam param;
258 @@ -557,21 +565,50 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
260 if (decoder_->Initialize (¶m)) {
261 GMPLOG (GL_ERROR, "Couldn't initialize decoder");
262 - return GMPVideoGenericErr;
263 + return GMPGenericErr;
266 callback_ = callback;
267 - return GMPVideoNoErr;
271 - virtual GMPVideoErr Decode (GMPVideoEncodedFrame* inputFrame,
272 - bool missingFrames,
273 - const GMPCodecSpecificInfo& codecSpecificInfo,
274 - int64_t renderTimeMs = -1) {
275 + virtual GMPErr Decode (GMPVideoEncodedFrame* inputFrame,
276 + bool missingFrames,
277 + const uint8_t* aCodecSpecificInfo,
278 + uint32_t aCodecSpecificInfoLength,
279 + int64_t renderTimeMs = -1) {
280 GMPLOG (GL_DEBUG, __FUNCTION__
281 << "Decoding frame size=" << inputFrame->Size()
282 << " timestamp=" << inputFrame->TimeStamp());
284 + //const GMPCodecSpecificInfo *codecSpecificInfo = (GMPCodecSpecificInfo) aCodecSpecificInfo;
286 + // Convert to H.264 start codes
287 + switch (inputFrame->BufferType()) {
288 + case GMP_BufferSingle:
289 + case GMP_BufferLength8:
290 + case GMP_BufferLength16:
291 + case GMP_BufferLength24:
292 + // We should look to support these, especially GMP_BufferSingle
296 + case GMP_BufferLength32:
298 + uint8_t *start_code = inputFrame->Buffer();
299 + while (start_code < inputFrame->Buffer() + inputFrame->Size()) {
300 + static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
301 + uint8_t *lenp = start_code;
302 + start_code += *(reinterpret_cast<int32_t *>(lenp));
303 + memcpy(lenp, code, 4);
313 worker_thread_->Post (WrapTask (
314 this, &OpenH264VideoDecoder::Decode_w,
315 @@ -579,15 +616,15 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
319 - return GMPVideoNoErr;
323 - virtual GMPVideoErr Reset() {
324 - return GMPVideoNoErr;
325 + virtual GMPErr Reset() {
329 - virtual GMPVideoErr Drain() {
330 - return GMPVideoNoErr;
331 + virtual GMPErr Drain() {
335 virtual void DecodingComplete() {
336 @@ -660,8 +697,8 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
337 GMPVideoFrame* ftmp = nullptr;
339 // Translate the image.
340 - GMPVideoErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp);
341 - if (err != GMPVideoNoErr) {
342 + GMPErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp);
343 + if (err != GMPNoErr) {
344 GMPLOG (GL_ERROR, "Couldn't allocate empty I420 frame");
347 @@ -674,7 +711,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
348 uvstride * height / 2, static_cast<uint8_t*> (data[2]),
350 ystride, uvstride, uvstride);
351 - if (err != GMPVideoNoErr) {
352 + if (err != GMPNoErr) {
353 GMPLOG (GL_ERROR, "Couldn't make decoded frame");
356 @@ -682,7 +719,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
357 GMPLOG (GL_DEBUG, "Allocated size = "
358 << frame->AllocatedSize (kGMPYPlane));
359 frame->SetTimestamp (inputFrame->TimeStamp());
360 - frame->SetRenderTime_ms (renderTimeMs);
361 + frame->SetDuration (inputFrame->Duration());
362 callback_->Decoded (frame);
365 @@ -690,7 +727,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
368 GMPThread* worker_thread_;
369 - GMPDecoderCallback* callback_;
370 + GMPVideoDecoderCallback* callback_;
371 ISVCDecoder* decoder_;
374 diff --git a/module/task_utils.h b/module/task_utils.h
375 index 2bd8937..c53e8d4 100644
376 --- a/module/task_utils.h
377 +++ b/module/task_utils.h
379 class gmp_args_base : public GMPTask {
387 // The generated file contains four major function templates