📄 ds_videodecoder.c
字号:
{ Debug printf("DS_VideoDecoder_StartInternal\n"); //cout << "DSSTART" << endl; this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll); this->m_pDS_Filter->Start(this->m_pDS_Filter); this->iv.m_State = START; framecount=0; framecount_in=0;}void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this){#ifdef WIN32_LOADER Setup_LDT_Keeper(); //prevent a segmentation fault during cleanup#endif this->m_pDS_Filter->Stop(this->m_pDS_Filter); //??? why was this here ??? m_pOurOutput->SetFramePointer(0);}void DS_VideoDecoder_SeekInternal(DS_VideoDecoder *this){ HRESULT ret; Debug printf("DS_VideoDecoder_SeekInternal\n"); ret = this->m_pDS_Filter->m_pInputPin->vt->BeginFlush(this->m_pDS_Filter->m_pInputPin); //printf("BeginFlush returned: %08lx\n", ret); ret = this->m_pDS_Filter->m_pInputPin->vt->EndFlush(this->m_pDS_Filter->m_pInputPin); //printf("EndFlush returned: %08lx\n", ret); ret = this->m_pDS_Filter->m_pInputPin->vt->NewSegment(this->m_pDS_Filter->m_pInputPin,0,0,1); //printf("NewSegment returned: %08lx\n", ret); memset(&sampleProcData, 0, sizeof(sampleProcData)); discontinuity = 1;}void DS_VideoDecoder_SetPTS(DS_VideoDecoder *this, uint64_t pts_nsec){ IMediaSample* sample = 0; REFERENCE_TIME stoptime; stoptime = pts_nsec + 1; this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); if(sample) sample->vt->SetTime(sample, &pts_nsec, &stoptime); sample->vt->Release((IUnknown*)sample);}uint64_t DS_VideoDecoder_GetPTS(DS_VideoDecoder *this){ return sampleProcData.frame[sampleProcData.lastFrame].pts_nsec;}void DS_VideoDecoder_FreeFrame(DS_VideoDecoder *this){ if(sampleProcData.frame[sampleProcData.lastFrame].state == PD_SENT) { sampleProcData.frame[sampleProcData.lastFrame].state = 0; memstruct_setlock(sampleProcData.frame[sampleProcData.lastFrame].frame_pointer, 0); sampleProcData.lastFrame = (sampleProcData.lastFrame + 1) % PD_MAX_FRAMES; }}int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int size, int is_keyframe, char* pImage){ IMediaSample* sample = 0; BYTE* ptr; int result; int ret = 0; Debug printf("DS_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src,size,is_keyframe,pImage); this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); if (!sample) { Debug printf("ERROR: null sample\n"); return -1; } //cout << "DECODE " << (void*) pImage << " d: " << (void*) pImage->Data() << endl; sample->vt->SetActualDataLength(sample, size); sample->vt->GetPointer(sample, &ptr); memcpy(ptr, src, size); sample->vt->SetSyncPoint(sample, is_keyframe); sample->vt->SetPreroll(sample, pImage ? 0 : 1); sample->vt->SetDiscontinuity(sample, discontinuity); discontinuity = 0; // sample->vt->SetMediaType(sample, &m_sOurType); // FIXME: - crashing with YV12 at this place decoder will crash // while doing this call // %FS register was not setup for calling into win32 dll. Are all // crashes inside ...->Receive() fixed now? // // nope - but this is surely helpfull - I'll try some more experiments#ifdef WIN32_LOADER Setup_FS_Segment();#endif#if 0 if (!this->m_pDS_Filter || !this->m_pDS_Filter->m_pImp || !this->m_pDS_Filter->m_pImp->vt || !this->m_pDS_Filter->m_pImp->vt->Receive) printf("DecodeInternal ERROR???\n");#endif framecount_in++; result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample); if (result) { Debug printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result); } if(sampleProcData.frame[sampleProcData.lastFrame].state == PD_SET) {#ifdef USE_SHARED_MEM int page; page = get_memstruct_pagenum(sampleProcData.frame[sampleProcData.lastFrame].frame_pointer); if (page != -1) ret |= (0x02 | (page << 8)); else#endif if (pImage) { memcpy(pImage, sampleProcData.frame[sampleProcData.lastFrame].frame_pointer, sampleProcData.frame[sampleProcData.lastFrame].frame_size); } ret |= 0x01; framecount++; sampleProcData.frame[sampleProcData.lastFrame].state = PD_SENT; if(sampleProcData.frame[sampleProcData.lastFrame].interlace) ret |= 0x10; } sample->vt->Release((IUnknown*)sample);#if 0 if (this->m_bIsDivX) { int q; IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); // always check for actual value // this seems to be the only way to know the actual value hidden->vt->GetSmth2(hidden, &this->m_iLastQuality); if (this->m_iLastQuality > 9) this->m_iLastQuality -= 10; if (this->m_iLastQuality < 0) this->m_iLastQuality = 0; else if (this->m_iLastQuality > this->m_iMaxAuto) this->m_iLastQuality = this->m_iMaxAuto; //cout << " Qual: " << this->m_iLastQuality << endl; this->iv.m_fQuality = this->m_iLastQuality / 4.0; } else if (this->m_bIsDivX4) { // maybe access methods directly to safe some cpu cycles... DS_VideoDecoder_GetValue(this, "Postprocessing", this->m_iLastQuality); if (this->m_iLastQuality < 0) this->m_iLastQuality = 0; else if (this->m_iLastQuality > this->m_iMaxAuto) this->m_iLastQuality = this->m_iMaxAuto; //cout << " Qual: " << m_iLastQuality << endl; this->iv.m_fQuality = this->m_iLastQuality / 6.0; } if (this->iv.m_Mode == -1 ) // ???BUFFERED_QUALITY_AUTO) { // adjust Quality - depends on how many cached frames we have int buffered = this->iv.m_iDecpos - this->iv.m_iPlaypos; if (this->m_bIsDivX || this->m_bIsDivX4) { int to = buffered - this->m_iMinBuffers; if (to < 0) to = 0; if (to != this->m_iLastQuality) { if (to > this->m_iMaxAuto) to = this->m_iMaxAuto; if (this->m_iLastQuality != to) { if (this->m_bIsDivX) { IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); hidden->vt->SetSmth(hidden, to, 0); } else DS_VideoDecoder_SetValue(this, "Postprocessing", to);#ifndef QUIET //printf("Switching quality %d -> %d b:%d\n",m_iLastQuality, to, buffered);#endif } } } }#endif return ret;}/* * bits == 0 - leave unchanged *///int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0);int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, unsigned int csp){ HRESULT result; ALLOCATOR_PROPERTIES props,props1; int should_test=1; int stopped = 0; Debug printf("DS_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits,(int)csp); /* if (!CImage::Supported(csp, bits)) return -1;*/ // BitmapInfo temp = m_obh; if (!csp) // RGB { int ok = true; switch (bits) { case 15: this->m_sDestType.subtype = MEDIASUBTYPE_RGB555; break; case 16: this->m_sDestType.subtype = MEDIASUBTYPE_RGB565; break; case 24: this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; break; case 32: this->m_sDestType.subtype = MEDIASUBTYPE_RGB32; break; default: ok = false; break; } if (ok) { if (bits == 15) this->iv.m_obh.biBitCount=16; else this->iv.m_obh.biBitCount=bits; if( bits == 15 || bits == 16 ) { this->iv.m_obh.biSize=sizeof(BITMAPINFOHEADER)+12; this->iv.m_obh.biCompression=3;//BI_BITFIELDS this->iv.m_obh.biSizeImage=abs((int)(2*this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)); } if( bits == 16 ) { this->iv.m_obh.colors[0]=0xF800; this->iv.m_obh.colors[1]=0x07E0; this->iv.m_obh.colors[2]=0x001F; } else if ( bits == 15 ) { this->iv.m_obh.colors[0]=0x7C00; this->iv.m_obh.colors[1]=0x03E0; this->iv.m_obh.colors[2]=0x001F; } else { this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression = 0; //BI_RGB //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) * ((this->iv.m_obh.biBitCount + 7) / 8); } } //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); } else { // YUV int ok = true; switch (csp) { case fccYUY2: this->m_sDestType.subtype = MEDIASUBTYPE_YUY2; break; case fccYV12: this->m_sDestType.subtype = MEDIASUBTYPE_YV12; break; case fccIYUV: this->m_sDestType.subtype = MEDIASUBTYPE_IYUV; break; case fccI420: this->m_sDestType.subtype = MEDIASUBTYPE_I420; break; case fccUYVY: this->m_sDestType.subtype = MEDIASUBTYPE_UYVY; break; case fccYVYU: this->m_sDestType.subtype = MEDIASUBTYPE_YVYU; break; case fccYVU9: this->m_sDestType.subtype = MEDIASUBTYPE_YVU9; default: ok = false; break; } if (ok) { if (csp != 0 && csp != 3 && this->iv.m_obh.biHeight > 0) this->iv.m_obh.biHeight *= -1; // YUV formats uses should have height < 0 this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression=csp; this->iv.m_obh.biBitCount=bits; this->iv.m_obh.biSizeImage=labs(this->iv.m_obh.biBitCount* this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)>>3; } } this->m_sDestType.lSampleSize = this->iv.m_obh.biSizeImage; memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_obh, sizeof(this->iv.m_obh)); this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if (this->m_sVhdr2->bmiHeader.biCompression == 3) this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER2) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER2); switch(csp) { case fccYUY2: if(!(this->m_Caps & CAP_YUY2)) should_test=false; break; case fccYV12: if(!(this->m_Caps & CAP_YV12)) should_test=false; break; case fccIYUV: if(!(this->m_Caps & CAP_IYUV)) should_test=false; break; case fccI420: if(!(this->m_Caps & CAP_I420)) should_test=false; break; case fccUYVY: if(!(this->m_Caps & CAP_UYVY)) should_test=false; break; case fccYVYU: if(!(this->m_Caps & CAP_YVYU)) should_test=false; break; case fccYVU9: if(!(this->m_Caps & CAP_YVU9)) should_test=false; break; } if(should_test) result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); else result = -1; if (result != 0) { if (csp) printf("Warning: unsupported color space\n"); else printf("Warning: unsupported bit depth\n"); this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -