Пример #1
0
void
WidevineVideoDecoder::Drain()
{
  Log("WidevineVideoDecoder::Drain()");
  if (mReturnOutputCallDepth > 0) {
    Log("Drain call is reentrant, postponing drain");
    mDrainPending = true;
    return;
  }

  Status rv = kSuccess;
  while (rv == kSuccess) {
    WidevineVideoFrame frame;
    InputBuffer sample;
    Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame);
    Log("WidevineVideoDecoder::Drain();  DecryptAndDecodeFrame() rv=%d", rv);
    if (frame.Format() == kUnknownVideoFormat) {
      break;
    }
    if (rv == kSuccess) {
      if (!ReturnOutput(frame)) {
        Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
      }
    }
  }
  // Shouldn't be reset while draining.
  MOZ_ASSERT(!mResetInProgress);

  CDM()->ResetDecoder(kStreamTypeVideo);
  mDrainPending = false;
  mCallback->DrainComplete();
}
Пример #2
0
void
WidevineVideoDecoder::InitDecode(const GMPVideoCodec& aCodecSettings,
                                 const uint8_t* aCodecSpecific,
                                 uint32_t aCodecSpecificLength,
                                 GMPVideoDecoderCallback* aCallback,
                                 int32_t aCoreCount)
{
  mCallback = aCallback;
  VideoDecoderConfig config;
  config.codec = VideoDecoderConfig::kCodecH264; // TODO: others.
  const GMPVideoCodecH264* h264 = (const GMPVideoCodecH264*)(aCodecSpecific);
  config.profile = ToCDMH264Profile(h264->mAVCC.mProfile);
  config.format = kYv12;
  config.coded_size = Size(aCodecSettings.mWidth, aCodecSettings.mHeight);
  mExtraData->AppendElements(aCodecSpecific + 1, aCodecSpecificLength);
  config.extra_data = mExtraData->Elements();
  config.extra_data_size = mExtraData->Length();
  Status rv = CDM()->InitializeVideoDecoder(config);
  if (rv != kSuccess) {
    mCallback->Error(ToGMPErr(rv));
    return;
  }
  Log("WidevineVideoDecoder::InitDecode() rv=%d", rv);
  mAnnexB = mp4_demuxer::AnnexB::ConvertExtraDataToAnnexB(mExtraData);
}
Пример #3
0
void
WidevineDecryptor::CreateSession(uint32_t aCreateSessionToken,
                                 uint32_t aPromiseId,
                                 const char* aInitDataType,
                                 uint32_t aInitDataTypeSize,
                                 const uint8_t* aInitData,
                                 uint32_t aInitDataSize,
                                 GMPSessionType aSessionType)
{
  Log("Decryptor::CreateSession(token=%d, pid=%d)", aCreateSessionToken, aPromiseId);
  InitDataType initDataType;
  if (!strcmp(aInitDataType, "cenc")) {
    initDataType = kCenc;
  } else if (!strcmp(aInitDataType, "webm")) {
    initDataType = kWebM;
  } else if (!strcmp(aInitDataType, "keyids")) {
    initDataType = kKeyIds;
  } else {
    // Invalid init data type
    const char* errorMsg = "Invalid init data type when creating session.";
    OnRejectPromise(aPromiseId, kNotSupportedError, 0, errorMsg, sizeof(errorMsg));
    return;
  }
  mPromiseIdToNewSessionTokens[aPromiseId] = aCreateSessionToken;
  CDM()->CreateSessionAndGenerateRequest(aPromiseId,
                                         ToCDMSessionType(aSessionType),
                                         initDataType,
                                         aInitData, aInitDataSize);
}
Пример #4
0
void
WidevineDecryptor::CloseSession(uint32_t aPromiseId,
                                const char* aSessionId,
                                uint32_t aSessionIdLength)
{
  Log("Decryptor::CloseSession(pid=%d, session=%s)", aPromiseId, aSessionId);
  CDM()->CloseSession(aPromiseId, aSessionId, aSessionIdLength);
}
Пример #5
0
void
WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId,
                                        const uint8_t* aServerCert,
                                        uint32_t aServerCertSize)
{
  Log("Decryptor::SetServerCertificate()");
  CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize);
}
Пример #6
0
void
WidevineDecryptor::RemoveSession(uint32_t aPromiseId,
                                 const char* aSessionId,
                                 uint32_t aSessionIdLength)
{
  Log("Decryptor::RemoveSession(%s)", aSessionId);
  CDM()->RemoveSession(aPromiseId, aSessionId, aSessionIdLength);
}
Пример #7
0
void
WidevineDecryptor::Init(GMPDecryptorCallback* aCallback,
                        bool aDistinctiveIdentifierRequired,
                        bool aPersistentStateRequired)
{
  Log("WidevineDecryptor::Init() this=%p distinctiveId=%d persistentState=%d",
      this, aDistinctiveIdentifierRequired, aPersistentStateRequired);
  MOZ_ASSERT(aCallback);
  mCallback = aCallback;
  MOZ_ASSERT(mCDM);
  mDistinctiveIdentifierRequired = aDistinctiveIdentifierRequired;
  mPersistentStateRequired = aPersistentStateRequired;
  if (CDM()) {
    CDM()->Initialize(aDistinctiveIdentifierRequired,
                      aPersistentStateRequired);
  }
}
Пример #8
0
void
WidevineDecryptor::LoadSession(uint32_t aPromiseId,
                               const char* aSessionId,
                               uint32_t aSessionIdLength)
{
  Log("Decryptor::LoadSession(pid=%d, %s)", aPromiseId, aSessionId);
  // TODO: session type??
  CDM()->LoadSession(aPromiseId, kPersistentLicense, aSessionId, aSessionIdLength);
}
Пример #9
0
void
WidevineDecryptor::UpdateSession(uint32_t aPromiseId,
                                 const char* aSessionId,
                                 uint32_t aSessionIdLength,
                                 const uint8_t* aResponse,
                                 uint32_t aResponseSize)
{
  Log("Decryptor::UpdateSession(pid=%d, session=%s)", aPromiseId, aSessionId);
  CDM()->UpdateSession(aPromiseId, aSessionId, aSessionIdLength, aResponse, aResponseSize);
}
Пример #10
0
void
WidevineVideoDecoder::DecodingComplete()
{
  Log("WidevineVideoDecoder::DecodingComplete()");
  if (mCDMWrapper) {
    CDM()->DeinitializeDecoder(kStreamTypeVideo);
    mCDMWrapper = nullptr;
  }
  // Release that corresponds to AddRef() in constructor.
  Release();
}
Пример #11
0
void
WidevineDecryptor::CreateSession(uint32_t aCreateSessionToken,
                                 uint32_t aPromiseId,
                                 const char* aInitDataType,
                                 uint32_t aInitDataTypeSize,
                                 const uint8_t* aInitData,
                                 uint32_t aInitDataSize,
                                 GMPSessionType aSessionType)
{
  Log("Decryptor::CreateSession(token=%d, pid=%d)", aCreateSessionToken, aPromiseId);
  MOZ_ASSERT(!strcmp(aInitDataType, "cenc"));
  mPromiseIdToNewSessionTokens[aPromiseId] = aCreateSessionToken;
  CDM()->CreateSessionAndGenerateRequest(aPromiseId,
                                         ToCDMSessionType(aSessionType),
                                         kCenc,
                                         aInitData, aInitDataSize);
}
Пример #12
0
void
WidevineVideoDecoder::Reset()
{
  Log("WidevineVideoDecoder::Reset() mSentInput=%d", mSentInput);
  // We shouldn't reset if a drain is pending.
  MOZ_ASSERT(!mDrainPending);
  mResetInProgress = true;
  if (mSentInput) {
    CDM()->ResetDecoder(kStreamTypeVideo);
  }
  // Remove queued frames, but do not reset mReturnOutputCallDepth, let the
  // ReturnOutput calls unwind and decrement the counter as needed.
  mFrameAllocationQueue.clear();
  mFrameDurations.clear();
  // Only if no ReturnOutput calls are in progress can we complete, otherwise
  // ReturnOutput needs to finalize the reset.
  if (mReturnOutputCallDepth == 0) {
    CompleteReset();
  }
}
Пример #13
0
void
WidevineDecryptor::Decrypt(GMPBuffer* aBuffer,
                           GMPEncryptedBufferMetadata* aMetadata)
{
  if (!mCallback) {
    Log("WidevineDecryptor::Decrypt() this=%p FAIL; !mCallback", this);
    return;
  }
  const GMPEncryptedBufferMetadata* crypto = aMetadata;
  InputBuffer sample;
  nsTArray<SubsampleEntry> subsamples;
  InitInputBuffer(crypto, aBuffer->Id(), aBuffer->Data(), aBuffer->Size(), sample, subsamples);
  WidevineDecryptedBlock decrypted;
  Status rv = CDM()->Decrypt(sample, &decrypted);
  Log("Decryptor::Decrypt(timestamp=%lld) rv=%d sz=%d",
      sample.timestamp, rv, decrypted.DecryptedBuffer()->Size());
  if (rv == kSuccess) {
    aBuffer->Resize(decrypted.DecryptedBuffer()->Size());
    memcpy(aBuffer->Data(),
           decrypted.DecryptedBuffer()->Data(),
           decrypted.DecryptedBuffer()->Size());
  }
  mCallback->Decrypted(aBuffer, ToGMPErr(rv));
}
Пример #14
0
void
WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
                             bool aMissingFrames,
                             const uint8_t* aCodecSpecificInfo,
                             uint32_t aCodecSpecificInfoLength,
                             int64_t aRenderTimeMs)
{
  // We should not be given new input if a drain has been initiated
  MOZ_ASSERT(!mDrainPending);
  // We may not get the same out of the CDM decoder as we put in, and there
  // may be some latency, i.e. we may need to input (say) 30 frames before
  // we receive output. So we need to store the durations of the frames input,
  // and retrieve them on output.
  mFrameDurations[aInputFrame->TimeStamp()] = aInputFrame->Duration();

  mSentInput = true;
  InputBuffer sample;

  RefPtr<MediaRawData> raw(new MediaRawData(aInputFrame->Buffer(), aInputFrame->Size()));
  raw->mExtraData = mExtraData;
  raw->mKeyframe = (aInputFrame->FrameType() == kGMPKeyFrame);
  // Convert input from AVCC, which GMPAPI passes in, to AnnexB, which
  // Chromium uses internally.
  mp4_demuxer::AnnexB::ConvertSampleToAnnexB(raw);

  const GMPEncryptedBufferMetadata* crypto = aInputFrame->GetDecryptionData();
  nsTArray<SubsampleEntry> subsamples;
  InitInputBuffer(crypto, aInputFrame->TimeStamp(), raw->Data(), raw->Size(), sample, subsamples);

  // For keyframes, ConvertSampleToAnnexB will stick the AnnexB extra data
  // at the start of the input. So we need to account for that as clear data
  // in the subsamples.
  if (raw->mKeyframe && !subsamples.IsEmpty()) {
    subsamples[0].clear_bytes += mAnnexB->Length();
  }

  WidevineVideoFrame frame;
  Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame);
  Log("WidevineVideoDecoder::Decode(timestamp=%lld) rv=%d", sample.timestamp, rv);

  // Destroy frame, so that the shmem is now free to be used to return
  // output to the Gecko process.
  aInputFrame->Destroy();
  aInputFrame = nullptr;

  if (rv == kSuccess) {
    if (!ReturnOutput(frame)) {
      Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
      mCallback->Error(GMPDecodeErr);
      return;
    }
    // A reset should only be started at most at level mReturnOutputCallDepth 1,
    // and if it's started it should be finished by that call by the time
    // the it returns, so it should always be false by this point.
    MOZ_ASSERT(!mResetInProgress);
    // Only request more data if we don't have pending samples.
    if (mFrameAllocationQueue.empty()) {
      MOZ_ASSERT(mCDMWrapper);
      mCallback->InputDataExhausted();
    }
  } else if (rv == kNeedMoreData) {
    MOZ_ASSERT(mCDMWrapper);
    mCallback->InputDataExhausted();
  } else {
    mCallback->Error(ToGMPErr(rv));
  }
  // Finish a drain if pending and we have no pending ReturnOutput calls on the stack.
  if (mDrainPending && mReturnOutputCallDepth == 0) {
    Drain();
  }
}
Пример #15
0
void CLightSet::RunLightPrep(IplImage* src,IplImage* dest)
{
	int M,N;
	M=0;
	N=0;
	if (src->roi)
	{
		 M = src->roi->width;
		 N = src->roi->height;
	}
	else
	{
		 M = src->width;
		 N = src->height;
	}

	CvMat *matD; // create mat for meshgrid frequency matrices
	matD = cvCreateMat(M,N,CV_32FC1);

	CDM(M,N,matD);

	CvMat *matH;
	matH = cvCreateMat(M,N,CV_32FC1); // mat for lowpass filter

	float D0 = 10.0;
	float rH,rL,c;
	rH = 2.0;
	rL = 0.5;
	c  = 1.0;
	lpfilter(matD,matH,D0,rH,rL,c);

	IplImage *srcshift; // shift center
	srcshift = cvCloneImage(src);
	cvShiftDFT(srcshift,srcshift);

	IplImage *log, *temp;
	log = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);
	temp = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);

	cvCvtScale(srcshift,temp,1.0,0);
	cvLog(temp,log);
	cvCvtScale(log,log,-1.0,0);

	CvMat *Fourier;
	Fourier = cvCreateMat( M, N, CV_32FC2 );

	fft2(log,Fourier);
	IplImage* image_im;
	image_im = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);

	cvSplit(Fourier,dest,image_im,0,0);

	cvMul(dest,matH,dest); 
	cvMul(image_im,matH,image_im);

	IplImage *dst;
	dst  = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,2);

	cvMerge(dest,image_im,0,0,dst);
	cvDFT(dst,dst,CV_DXT_INV_SCALE); 

	cvExp(dst,dst);

	cvZero(dest);
	cvZero(image_im);

	cvSplit(dst,dest,image_im,0,0); 
	//使得图像按照原来的顺序显示
	cvShiftDFT(dest,dest);

	double max,min; // normalize
	cvMinMaxLoc(dest,&min,&max,NULL,NULL);

	cvReleaseImage(&image_im);
	cvReleaseImage(&srcshift);
 	cvReleaseImage(&dst);	
	cvReleaseImage(&log);
	cvReleaseImage(&temp);
	cvReleaseMat(&matD);
	cvReleaseMat(&matH);
}