// Return the decoded data back to the parent. void Decode_m (GMPVideoEncodedFrame* inputFrame, SBufferInfo* decoded, unsigned char* data[3], int64_t renderTimeMs, bool valid) { // Attach a self-destructor so that this dies on return. SelfDestruct<GMPVideoEncodedFrame> ifd (inputFrame); // If we don't actually have data, just abort. if (!valid) { return; } if (decoded->iBufferStatus != 1) { return; } int width = decoded->UsrData.sSystemBuffer.iWidth; int height = decoded->UsrData.sSystemBuffer.iHeight; int ystride = decoded->UsrData.sSystemBuffer.iStride[0]; int uvstride = decoded->UsrData.sSystemBuffer.iStride[1]; GMPLOG (GL_DEBUG, "Video frame ready for display " << width << "x" << height << " timestamp=" << inputFrame->TimeStamp()); GMPVideoFrame* ftmp = nullptr; // Translate the image. GMPErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp); if (err != GMPNoErr) { GMPLOG (GL_ERROR, "Couldn't allocate empty I420 frame"); return; } GMPVideoi420Frame* frame = static_cast<GMPVideoi420Frame*> (ftmp); err = frame->CreateFrame ( ystride * height, static_cast<uint8_t*> (data[0]), uvstride * height / 2, static_cast<uint8_t*> (data[1]), uvstride * height / 2, static_cast<uint8_t*> (data[2]), width, height, ystride, uvstride, uvstride); if (err != GMPNoErr) { GMPLOG (GL_ERROR, "Couldn't make decoded frame"); return; } GMPLOG (GL_DEBUG, "Allocated size = " << frame->AllocatedSize (kGMPYPlane)); frame->SetTimestamp (inputFrame->TimeStamp()); frame->SetDuration (inputFrame->Duration()); callback_->Decoded (frame); stats_.FrameOut(); }
// Return the decoded data back to the parent. void Decode_m (GMPVideoEncodedFrame* inputFrame, int64_t renderTimeMs) { EncodedFrame *eframe; if (inputFrame->Size() != (sizeof(*eframe))) { GMPLOG (GL_ERROR, "Couldn't decode frame. Size=" << inputFrame->Size()); return; } eframe = reinterpret_cast<EncodedFrame*>(inputFrame->Buffer()); if (eframe->magic_ != ENCODED_FRAME_MAGIC) { GMPLOG (GL_ERROR, "Couldn't decode frame. Magic=" << eframe->magic_); return; } int width = eframe->width_; int height = eframe->height_; int ystride = eframe->width_; int uvstride = eframe->width_/2; GMPLOG (GL_DEBUG, "Video frame ready for display " << width << "x" << height << " timestamp=" << inputFrame->TimeStamp()); GMPVideoFrame* ftmp = NULL; // Translate the image. GMPErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp); if (err != GMPNoErr) { GMPLOG (GL_ERROR, "Couldn't allocate empty I420 frame"); return; } GMPVideoi420Frame* frame = static_cast<GMPVideoi420Frame*> (ftmp); err = frame->CreateEmptyFrame ( width, height, ystride, uvstride, uvstride); if (err != GMPNoErr) { GMPLOG (GL_ERROR, "Couldn't make decoded frame"); return; } memset(frame->Buffer(kGMPYPlane), eframe->y_, frame->AllocatedSize(kGMPYPlane)); memset(frame->Buffer(kGMPUPlane), eframe->u_, frame->AllocatedSize(kGMPUPlane)); memset(frame->Buffer(kGMPVPlane), eframe->v_, frame->AllocatedSize(kGMPVPlane)); GMPLOG (GL_DEBUG, "Allocated size = " << frame->AllocatedSize (kGMPYPlane)); frame->SetTimestamp (inputFrame->TimeStamp()); frame->SetDuration (inputFrame->Duration()); callback_->Decoded (frame); }