Merge pull request #1746 from kinetiknz/gmp-fixes

Various fixes for the GeckoMediaPlugin wrapper
This commit is contained in:
Ethan Hugg 2015-01-30 09:25:35 -08:00
commit 195df08bb9

View File

@ -550,6 +550,16 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
FrameStats stats_;
};
uint16_t readU16BE(const uint8_t* in) {
return in[0] << 8 | in[1];
}
void copyWithStartCode(std::vector<uint8_t>& out, const uint8_t* in, size_t size) {
static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
out.insert(out.end(), code, code + sizeof(code));
out.insert(out.end(), in, in + size);
}
class OpenH264VideoDecoder : public GMPVideoDecoder {
public:
OpenH264VideoDecoder (GMPVideoHost* hostAPI) :
@ -595,6 +605,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
param.eOutputColorFormat = videoFormatI420;
param.uiTargetDqLayer = UCHAR_MAX; // Default value
param.eEcActiveIdc = ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE; // Error concealment on.
param.sVideoProperty.size = sizeof(param.sVideoProperty);
param.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
if (decoder_->Initialize (&param)) {
@ -602,6 +613,43 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
Error (GMPGenericErr);
return;
}
if (aCodecSpecific && aCodecSpecificSize >= sizeof(GMPVideoCodecH264)) {
std::vector<uint8_t> annexb;
// Convert the AVCC data, starting at the byte containing
// numOfSequenceParameterSets, to Annex B format.
const uint8_t* avcc = aCodecSpecific + offsetof(GMPVideoCodecH264, mAVCC.mNumSPS);
static const int kSPSMask = (1 << 5) - 1;
uint8_t spsCount = *avcc++ & kSPSMask;
for (int i = 0; i < spsCount; ++i) {
size_t size = readU16BE(avcc);
avcc += 2;
copyWithStartCode(annexb, avcc, size);
avcc += size;
}
uint8_t ppsCount = *avcc++;
for (int i = 0; i < ppsCount; ++i) {
size_t size = readU16BE(avcc);
avcc += 2;
copyWithStartCode(annexb, avcc, size);
avcc += size;
}
SBufferInfo decoded;
memset (&decoded, 0, sizeof (decoded));
unsigned char* data[3] = {nullptr, nullptr, nullptr};
DECODING_STATE dState = decoder_->DecodeFrame2 (&*annexb.begin(),
annexb.size(),
data,
&decoded);
if (dState) {
GMPLOG (GL_ERROR, "Decoding error dState=" << dState);
}
GMPLOG (GL_ERROR, "InitDecode iBufferStatus=" << decoded.iBufferStatus);
}
}
virtual void Decode (GMPVideoEncodedFrame* inputFrame,
@ -655,9 +703,15 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
}
virtual void Reset() {
if (callback_) {
callback_->ResetComplete ();
}
}
virtual void Drain() {
if (callback_) {
callback_->DrainComplete ();
}
}
virtual void DecodingComplete() {
@ -715,11 +769,14 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
// If we don't actually have data, just abort.
if (!valid) {
GMPLOG (GL_ERROR, "No valid data decoded");
Error (GMPDecodeErr);
return;
}
if (decoded->iBufferStatus != 1) {
GMPLOG (GL_ERROR, "iBufferStatus=" << decoded->iBufferStatus);
callback_->InputDataExhausted();
return;
}