Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Commit 2a51394

Browse files
authored
Merge pull request #2 from scriptorian/master
Add decode test and tidy error handling
2 parents 7ce7ea4 + 6e22c82 commit 2a51394

14 files changed

+181
-45
lines changed

index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Decoder.prototype.setInfo = function(srcTags, dstTags) {
3838

3939
Decoder.prototype.decode = function(srcBufArray, dstBuf, cb) {
4040
try {
41-
var numQueued = this.decoderAdon.decode(srcBufArray, dstBuf, function(err, resultBytes) {
41+
var numQueued = this.decoderAdon.decode(srcBufArray, dstBuf, (err, resultBytes) => {
4242
cb(err, resultBytes?dstBuf.slice(0,resultBytes):null);
4343
});
4444
return numQueued;
@@ -49,7 +49,7 @@ Decoder.prototype.decode = function(srcBufArray, dstBuf, cb) {
4949

5050
Decoder.prototype.quit = function(cb) {
5151
try {
52-
this.decoderAdon.quit(function(err, resultBytes) {
52+
this.decoderAdon.quit((err, resultBytes) => {
5353
cb(err, resultBytes);
5454
});
5555
} catch (err) {
@@ -84,7 +84,7 @@ Encoder.prototype.setInfo = function(srcTags, dstTags, duration, bitrate, gopfra
8484

8585
Encoder.prototype.encode = function(srcBufArray, dstBuf, cb) {
8686
try {
87-
var numQueued = this.encoderAdon.encode(srcBufArray, dstBuf, function(err, resultBytes) {
87+
var numQueued = this.encoderAdon.encode(srcBufArray, dstBuf, (err, resultBytes) => {
8888
cb(err, resultBytes?dstBuf.slice(0,resultBytes):null);
8989
});
9090
return numQueued;
@@ -95,7 +95,7 @@ Encoder.prototype.encode = function(srcBufArray, dstBuf, cb) {
9595

9696
Encoder.prototype.quit = function(cb) {
9797
try {
98-
this.encoderAdon.quit(function(err, resultBytes) {
98+
this.encoderAdon.quit((err, resultBytes) => {
9999
cb(err, resultBytes);
100100
});
101101
} catch (err) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
},
1414
"dependencies": {
1515
"bindings": "^1.2.1",
16-
"nan": "^2.3.5"
16+
"nan": "^2.5.1"
1717
},
1818
"gypfile": true,
1919
"devDependencies": {

src/Decoder.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ Decoder::Decoder(Nan::Callback *callback)
5151
Decoder::~Decoder() {}
5252

5353
// iProcess
54-
uint32_t Decoder::processFrame (std::shared_ptr<iProcessData> processData) {
54+
uint32_t Decoder::processFrame (std::shared_ptr<iProcessData> processData, std::string &errStr) {
5555
Timer t;
5656
std::shared_ptr<DecodeProcessData> dpd = std::dynamic_pointer_cast<DecodeProcessData>(processData);
5757

5858
// do the decode
5959
uint32_t dstBytes = 0;
60-
mDecoderDriver->decodeFrame (dpd->srcBuf(), dpd->dstBuf(), mFrameNum++, &dstBytes);
60+
mDecoderDriver->decodeFrame (dpd->srcBuf(), dpd->dstBuf(), mFrameNum++, &dstBytes, errStr);
6161
printf("decode : %.2fms\n", t.delta());
6262

6363
return dstBytes;

src/Decoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class Decoder : public Nan::ObjectWrap, public iProcess {
3030
static NAN_MODULE_INIT(Init);
3131

3232
// iProcess
33-
uint32_t processFrame (std::shared_ptr<iProcessData> processData);
33+
uint32_t processFrame (std::shared_ptr<iProcessData> processData, std::string &errStr);
3434

3535
private:
3636
explicit Decoder(Nan::Callback *callback);
@@ -50,7 +50,7 @@ class Decoder : public Nan::ObjectWrap, public iProcess {
5050
const int argc = 3;
5151
v8::Local<v8::Value> argv[] = {info[0], info[1], info[2]};
5252
v8::Local<v8::Function> cons = Nan::New(constructor());
53-
info.GetReturnValue().Set(cons->NewInstance(argc, argv));
53+
info.GetReturnValue().Set(cons->NewInstance(Nan::GetCurrentContext(), argc, argv).ToLocalChecked());
5454
}
5555
}
5656

src/DecoderCinegy.cc

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,31 @@
1414
*/
1515

1616
#include <nan.h>
17+
#include <sstream>
1718
#include "DecoderCinegy.h"
1819
#include "CodecCinegy.h"
1920
#include "Memory.h"
2021
#include "EssenceInfo.h"
22+
#include <mutex>
23+
#include <condition_variable>
2124

2225
#include "../cinegy/include/cinecoder_h.h"
2326

2427
namespace streampunk {
2528

2629
#define TESTCOND(cond,hr) ATLASSERT(cond); if(!(cond)) return (hr)
2730

28-
class C_DecoderErrorHandler : public ICC_ErrorHandler {
31+
class DecoderErrorHandler : public ICC_ErrorHandler {
32+
public:
33+
DecoderErrorHandler() : mErrStr("") {}
34+
virtual ~DecoderErrorHandler() {}
35+
36+
std::string readErrStr() {
37+
std::string errStr(mErrStr);
38+
mErrStr.clear();
39+
return errStr;
40+
}
41+
2942
STDMETHOD(QueryInterface)(REFIID riid, void**p) {
3043
if (p == NULL)
3144
return E_POINTER;
@@ -44,18 +57,40 @@ class C_DecoderErrorHandler : public ICC_ErrorHandler {
4457
return 1;
4558
}
4659
STDMETHOD(ErrorHandlerFunc)(HRESULT ErrCode, LPCSTR ErrDescription, LPCSTR pFileName, INT LineNo) {
47-
printf("Cinecoder decoder error %08xh (%s) at %s(%d): %s\n", ErrCode, Cinecoder_GetErrorString(ErrCode), pFileName, LineNo, ErrDescription);
60+
// printf("Cinecoder decoder error %08xh (%s) at %s(%d): %s\n", ErrCode, Cinecoder_GetErrorString(ErrCode), pFileName, LineNo, ErrDescription);
61+
std::stringstream ss;
62+
ss << "Cinecoder decoder error " <<
63+
std::hex << ErrCode << "h" <<
64+
" (" << Cinecoder_GetErrorString(ErrCode) << ")" <<
65+
" at " << pFileName <<
66+
"(" << std::dec << LineNo << ")" <<
67+
": " << ErrDescription;
68+
mErrStr = ss.str();
4869
return ErrCode;
4970
}
71+
72+
private:
73+
std::string mErrStr;
5074
};
51-
C_DecoderErrorHandler DecodeErrorHandler;
5275

5376
class DecodeCallback : public ICC_DataReadyCallback {
5477
public:
55-
DecodeCallback() : mFirstFrame(true) {}
78+
DecodeCallback() : m(), cv(), mDecodeDone(false), mFirstFrame(true) {}
5679
virtual ~DecodeCallback() {}
5780

58-
void setDecodeBuffer(std::shared_ptr<Memory> buf) { mDecodeBuffer = buf; }
81+
void setDecodeBuffer(std::shared_ptr<Memory> buf) {
82+
mDecodeDone = false;
83+
mErrStr.clear();
84+
mDecodeBuffer = buf;
85+
}
86+
87+
void waitResult(std::string &errStr) {
88+
std::unique_lock<std::mutex> lk(m);
89+
while(!mDecodeDone) {
90+
cv.wait(lk);
91+
}
92+
errStr = mErrStr;
93+
}
5994

6095
// IUnknown implementation: AddRef, Release, QueryInterface
6196
STDMETHOD_(ULONG, AddRef)(void) { return 2; }
@@ -106,14 +141,26 @@ class DecodeCallback : public ICC_DataReadyCallback {
106141
return hr;
107142

108143
DWORD dwBytesWrote = 0;
109-
if(FAILED(hr = spProducer->GetFrame(CCF_UYVY_10BIT, mDecodeBuffer->buf(), mDecodeBuffer->numBytes(), szFrame.cx*4, &dwBytesWrote)))
110-
return hr;
144+
if(FAILED(hr = spProducer->GetFrame(CCF_UYVY_10BIT, mDecodeBuffer->buf(), mDecodeBuffer->numBytes(), szFrame.cx*4, &dwBytesWrote))) {
145+
std::stringstream ss;
146+
ss << "Cinecoder decoder error " <<
147+
std::hex << hr << "h" <<
148+
" (" << Cinecoder_GetErrorString(hr) << ")";
149+
mErrStr = ss.str();
150+
}
151+
std::lock_guard<std::mutex> lk(m);
152+
mDecodeDone = true;
153+
cv.notify_one();
111154

112-
return S_OK;
155+
return hr;
113156
}
114157

115158
private:
159+
mutable std::mutex m;
160+
std::condition_variable cv;
161+
bool mDecodeDone;
116162
bool mFirstFrame;
163+
std::string mErrStr;
117164
std::shared_ptr<Memory> mDecodeBuffer;
118165
};
119166

@@ -125,7 +172,8 @@ DecoderCinegy::DecoderCinegy(std::shared_ptr<EssenceInfo> srcInfo, std::shared_p
125172
CC_VERSION_INFO version = Cinecoder_GetVersion();
126173
printf("Cinecoder.dll version %d.%02d.%02d\n\n", version.VersionHi, version.VersionLo, version.EditionNo);
127174

128-
Cinecoder_SetErrorHandler(&DecodeErrorHandler);
175+
mErrorHandler = new DecoderErrorHandler;
176+
Cinecoder_SetErrorHandler(mErrorHandler);
129177

130178
HRESULT hr = S_OK;
131179

@@ -152,19 +200,24 @@ DecoderCinegy::DecoderCinegy(std::shared_ptr<EssenceInfo> srcInfo, std::shared_p
152200
DecoderCinegy::~DecoderCinegy() {}
153201

154202
uint32_t DecoderCinegy::bytesReq() const {
155-
return mWidth * 4 * 3 / 4 * mHeight; // Decoder doesn't support unsqueeze yet so 1920 -> 1440, 1280 -> 960
203+
uint32_t pitch = mSrcEncoding.compare("AVCi50") ? mWidth * 4 : mWidth * 3; // Decoder doesn't support unsqueeze yet so 1920 -> 1440, 1280 -> 960
204+
return pitch * mHeight;
156205
}
157206

158-
void DecoderCinegy::decodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes) {
159-
207+
void DecoderCinegy::decodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes, std::string &errStr) {
208+
*pDstBytes = 0;
160209
mDecodeCb->setDecodeBuffer(dstBuf);
161210

162211
HRESULT hr = S_OK;
163212
DWORD dwBytesProcessed = 0;
164-
if(FAILED(hr = mVideoDecoder->ProcessData(srcBuf->buf(), (int)srcBuf->numBytes(), 0, -1, &dwBytesProcessed)))
213+
if(FAILED(hr = mVideoDecoder->ProcessData(srcBuf->buf(), (int)srcBuf->numBytes(), 0, -1, &dwBytesProcessed))) {
165214
printf("Cinecoder decoder failed to process frame\n");
215+
errStr = mErrorHandler->readErrStr();
216+
return;
217+
}
166218
mVideoDecoder->Break(CC_TRUE); // flush decoder frames immediately
167219

220+
mDecodeCb->waitResult(errStr);
168221
*pDstBytes = dstBuf->numBytes();
169222
}
170223

src/DecoderCinegy.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ class Memory;
2929
class Duration;
3030
class EssenceInfo;
3131
class DecodeCallback;
32+
class DecoderErrorHandler;
3233
class DecoderCinegy : public iDecoderDriver {
3334
public:
3435
DecoderCinegy(std::shared_ptr<EssenceInfo> srcInfo, std::shared_ptr<EssenceInfo> dstInfo);
3536
~DecoderCinegy();
3637

3738
uint32_t bytesReq() const;
38-
void decodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes);
39+
void decodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes, std::string &errStr);
3940

4041
private:
4142
std::string mSrcEncoding;
@@ -46,6 +47,7 @@ class DecoderCinegy : public iDecoderDriver {
4647
uint32_t mSrcFrameSize;
4748
CComPtr<ICC_VideoDecoder> mVideoDecoder;
4849
DecodeCallback *mDecodeCb;
50+
DecoderErrorHandler *mErrorHandler;
4951
};
5052

5153
} // namespace streampunk

src/Encoder.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ Encoder::Encoder(Nan::Callback *callback)
5656
Encoder::~Encoder() {}
5757

5858
// iProcess
59-
uint32_t Encoder::processFrame (std::shared_ptr<iProcessData> processData) {
59+
uint32_t Encoder::processFrame (std::shared_ptr<iProcessData> processData, std::string &errStr) {
6060
Timer t;
6161
std::shared_ptr<EncodeProcessData> epd = std::dynamic_pointer_cast<EncodeProcessData>(processData);
6262

6363
// do the encode
6464
uint32_t dstBytes = 0;
65-
mEncoderDriver->encodeFrame (epd->srcBuf(), epd->dstBuf(), mFrameNum++, &dstBytes);
65+
mEncoderDriver->encodeFrame (epd->srcBuf(), epd->dstBuf(), mFrameNum++, &dstBytes, errStr);
6666
printf("encode : %.2fms\n", t.delta());
6767

6868
return dstBytes;

src/Encoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Encoder : public Nan::ObjectWrap, public iProcess {
3131
static NAN_MODULE_INIT(Init);
3232

3333
// iProcess
34-
uint32_t processFrame (std::shared_ptr<iProcessData> processData);
34+
uint32_t processFrame (std::shared_ptr<iProcessData> processData, std::string &errStr);
3535

3636
private:
3737
explicit Encoder(Nan::Callback *callback);
@@ -52,7 +52,7 @@ class Encoder : public Nan::ObjectWrap, public iProcess {
5252
const int argc = 3;
5353
v8::Local<v8::Value> argv[] = {info[0], info[1], info[2]};
5454
v8::Local<v8::Function> cons = Nan::New(constructor());
55-
info.GetReturnValue().Set(cons->NewInstance(argc, argv));
55+
info.GetReturnValue().Set(cons->NewInstance(Nan::GetCurrentContext(), argc, argv).ToLocalChecked());
5656
}
5757
}
5858

src/EncoderCinegy.cc

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,17 @@ class AVCiMode {
6666
}
6767
};
6868

69-
class C_EncoderErrorHandler : public ICC_ErrorHandler {
69+
class EncoderErrorHandler : public ICC_ErrorHandler {
70+
public:
71+
EncoderErrorHandler() : mErrStr("") {}
72+
virtual ~EncoderErrorHandler() {}
73+
74+
std::string readErrStr() {
75+
std::string errStr(mErrStr);
76+
mErrStr.clear();
77+
return errStr;
78+
}
79+
7080
STDMETHOD(QueryInterface)(REFIID riid, void**p) {
7181
if (p == NULL)
7282
return E_POINTER;
@@ -85,11 +95,21 @@ class C_EncoderErrorHandler : public ICC_ErrorHandler {
8595
return 1;
8696
}
8797
STDMETHOD(ErrorHandlerFunc)(HRESULT ErrCode, LPCSTR ErrDescription, LPCSTR pFileName, INT LineNo) {
88-
printf("Cinecoder encoder error %08xh (%s) at %s(%d): %s\n", ErrCode, Cinecoder_GetErrorString(ErrCode), pFileName, LineNo, ErrDescription);
98+
// printf("Cinecoder encoder error %08xh (%s) at %s(%d): %s\n", ErrCode, Cinecoder_GetErrorString(ErrCode), pFileName, LineNo, ErrDescription);
99+
std::stringstream ss;
100+
ss << "Cinecoder encoder error " <<
101+
std::hex << ErrCode << "h" <<
102+
" (" << Cinecoder_GetErrorString(ErrCode) << ")" <<
103+
" at " << pFileName <<
104+
"(" << std::dec << LineNo << ")" <<
105+
": " << ErrDescription << "\n";
106+
mErrStr = ss.str();
89107
return ErrCode;
90108
}
109+
110+
private:
111+
std::string mErrStr;
91112
};
92-
C_EncoderErrorHandler EncodeErrorHandler;
93113

94114
class EncodeCallback : public ICC_ByteStreamCallback {
95115
public:
@@ -152,7 +172,8 @@ EncoderCinegy::EncoderCinegy(std::shared_ptr<EssenceInfo> srcInfo, std::shared_p
152172
CC_VERSION_INFO version = Cinecoder_GetVersion();
153173
printf("Cinecoder.dll version %d.%02d.%02d\n\n", version.VersionHi, version.VersionLo, version.EditionNo);
154174

155-
Cinecoder_SetErrorHandler(&EncodeErrorHandler);
175+
mErrorHandler = new EncoderErrorHandler;
176+
Cinecoder_SetErrorHandler(mErrorHandler);
156177

157178
HRESULT hr = S_OK;
158179

@@ -229,13 +250,22 @@ std::string EncoderCinegy::packingRequired() const {
229250
return "UYVY10";
230251
}
231252

232-
void EncoderCinegy::encodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes) {
253+
void EncoderCinegy::encodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes, std::string &errStr) {
254+
*pDstBytes = 0;
233255
HRESULT hr = S_OK;
234256
//if(FAILED(hr = mVideoEncoder->AddFrame(mVpar->cFormat, srcBuf->buf(), mSrcFrameSize, 0, NULL)))
235-
if (FAILED(hr = mVideoEncoder->AddScaleFrame(srcBuf->buf(), mSrcFrameSize, (CC_ADD_VIDEO_FRAME_PARAMS*)mVpar)))
257+
if (FAILED(hr = mVideoEncoder->AddScaleFrame(srcBuf->buf(), mSrcFrameSize, (CC_ADD_VIDEO_FRAME_PARAMS*)mVpar))) {
236258
printf("Error calling AddScaleFrame against Cinecoder\n");
237-
259+
errStr = mErrorHandler->readErrStr();
260+
return;
261+
}
262+
238263
std::shared_ptr<Memory> encodedBuf = mEncodeCb->getResult();
264+
if (!encodedBuf) {
265+
printf("Cinecoder encoder failed to encode\n");
266+
errStr = mErrorHandler->readErrStr();
267+
return;
268+
}
239269
memcpy_s(dstBuf->buf(), dstBuf->numBytes(), encodedBuf->buf(), encodedBuf->numBytes());
240270
*pDstBytes = encodedBuf->numBytes();
241271
}

src/EncoderCinegy.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Memory;
2929
class Duration;
3030
class EssenceInfo;
3131
class EncodeCallback;
32+
class EncoderErrorHandler;
3233
class EncoderCinegy : public iEncoderDriver {
3334
public:
3435
EncoderCinegy(std::shared_ptr<EssenceInfo> srcInfo, std::shared_ptr<EssenceInfo> dstInfo, const Duration& duration);
@@ -39,7 +40,7 @@ class EncoderCinegy : public iEncoderDriver {
3940
uint32_t width() const { return mWidth; }
4041
uint32_t height() const { return mHeight; }
4142

42-
void encodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes);
43+
void encodeFrame (std::shared_ptr<Memory> srcBuf, std::shared_ptr<Memory> dstBuf, uint32_t frameNum, uint32_t *pDstBytes, std::string &errStr);
4344

4445
private:
4546
std::string mSrcPacking;
@@ -52,6 +53,7 @@ class EncoderCinegy : public iEncoderDriver {
5253

5354
void *mVpar;
5455
EncodeCallback *mEncodeCb;
56+
EncoderErrorHandler *mErrorHandler;
5557
};
5658

5759
} // namespace streampunk

0 commit comments

Comments
 (0)