📄 ds_videodecoder.c
字号:
if (result) { ERROR_MSG("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x", result); } cs->ResetPointer(cs); pUserData->frame_pts = sampleProcData.frame_pts; sample->vt->Release((IUnknown*)sample); LOG_MSG("DS_VideoDecoder: m_bh: %dx%d, m_obh: %dx%d, m_decoder: %dx%d", this->iv.m_bh->biWidth, this->iv.m_bh->biHeight, this->iv.m_obh.biWidth, this->iv.m_obh.biHeight, this->iv.m_decoder.biWidth, this->iv.m_decoder.biHeight); return sampleProcData.size;}/* * bits == 0 - leave unchanged */int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, unsigned int csp, BITMAPINFOHEADER * bih){ HRESULT result; ALLOCATOR_PROPERTIES props, props1; int should_test = 1; int stoped = 0; LOG_MSG("DS_VideoDecoder_SetDestFmt (%p, %d, %d)",this,bits,(int)csp); // Change size if required if(bih) { this->iv.m_obh.biWidth = bih->biWidth; this->iv.m_obh.biHeight = bih->biHeight; LOG_MSG("DS_VideoDecoder_SetDestFmt: New size %dx%d", bih->biWidth, bih->biHeight); } 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); } } } 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: LOG_MSG("ERROR: Unknown YUV colorspace"); 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(VIDEOINFOHEADER) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); 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) { LOG_MSG("Warning: unsupported color space"); } else { LOG_MSG("Warning: unsupported bit depth"); } this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage; memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_decoder, sizeof(this->iv.m_decoder)); this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if (this->m_sVhdr2->bmiHeader.biCompression == 3) this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); return -1; } memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh)); this->iv.m_bh->biBitCount = bits; //DS_VideoDecoder_Restart(this); if (this->iv.m_State == START) { DS_VideoDecoder_StopInternal(this); this->iv.m_State = STOP; stoped = true; } this->m_pDS_Filter->m_pInputPin->vt->Disconnect(this->m_pDS_Filter->m_pInputPin); this->m_pDS_Filter->m_pOutputPin->vt->Disconnect(this->m_pDS_Filter->m_pOutputPin); this->m_pDS_Filter->m_pOurOutput->SetNewFormat(this->m_pDS_Filter->m_pOurOutput,&this->m_sDestType); result = this->m_pDS_Filter->m_pInputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pInputPin, this->m_pDS_Filter->m_pOurInput, &this->m_sOurType); if (result) { ERROR_MSG("Error reconnecting input pin 0x%x", (int)result); return -1; } if(this->m_pDS_Filter->m_pAll) this->m_pDS_Filter->m_pAll->vt->Release((IUnknown*)this->m_pDS_Filter->m_pAll); this->m_pDS_Filter->m_pAll=(IMemAllocator*)MemAllocatorCreate(); if (!this->m_pDS_Filter->m_pAll) { LOG_MSG("Call to MemAllocatorCreate failed"); return -1; } //Seting allocator property according to our media type props.cBuffers=1; props.cbBuffer=this->m_sDestType.lSampleSize; props.cbAlign=1; props.cbPrefix=0; this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1); //Notify remote pin about choosed allocator this->m_pDS_Filter->m_pImp->vt->NotifyAllocator(this->m_pDS_Filter->m_pImp, this->m_pDS_Filter->m_pAll, 0); result = this->m_pDS_Filter->m_pOutputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pOutputPin, (IPin *)this->m_pDS_Filter->m_pOurOutput, &this->m_sDestType); if (result) { ERROR_MSG("Error reconnecting output pin 0x%x", (int)result); return -1; } if (stoped) { DS_VideoDecoder_StartInternal(this); this->iv.m_State = START; } return 0;}int DS_VideoDecoder_SetDirection(DS_VideoDecoder *this, int d){ this->iv.m_obh.biHeight = (d) ? this->iv.m_bh->biHeight : -this->iv.m_bh->biHeight; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; return 0;}int DS_VideoDecoder_GetValue(DS_VideoDecoder *this, const char* name, int* value){ return 0;}int DS_VideoDecoder_SetValue(DS_VideoDecoder *this, const char* name, int value){ if (this->m_bIsDivX4) { IDivxFilterInterface* pIDivx=NULL;// LOG_MSG("DS_SetValue for DIVX4, name=%s value=%d",name,value); if (this->m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)this->m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx)) { LOG_MSG("No such interface"); return -1; } if (strcasecmp(name, "Postprocessing") == 0) pIDivx->vt->put_PPLevel(pIDivx, value * 10); else if (strcasecmp(name, "Brightness") == 0) pIDivx->vt->put_Brightness(pIDivx, value); else if (strcasecmp(name, "Contrast") == 0) pIDivx->vt->put_Contrast(pIDivx, value); else if (strcasecmp(name, "Saturation") == 0) pIDivx->vt->put_Saturation(pIDivx, value); else if (strcasecmp(name, "MaxAuto") == 0) this->m_iMaxAuto = value; pIDivx->vt->Release((IUnknown*)pIDivx); //LOG_MSG("Set %s %d", name, value); return 0; } if (this->m_bIsDivX) { IHidden* hidden; if (this->iv.m_State != START) return VFW_E_NOT_RUNNING; //cout << "set value " << name << " " << value << endl;// brightness 87// contrast 74// hue 23// saturation 20// post process mode 0// get1 0x01// get2 10// get3=set2 86// get4=set3 73// get5=set4 19 // get6=set5 23 hidden = (IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); //LOG_MSG("DS_SetValue for DIVX, name=%s value=%d",name,value); if (strcasecmp(name, "Quality") == 0) { this->m_iLastQuality = value; return hidden->vt->SetSmth(hidden, value, 0); } if (strcasecmp(name, "Brightness") == 0) return hidden->vt->SetSmth2(hidden, value, 0); if (strcasecmp(name, "Contrast") == 0) return hidden->vt->SetSmth3(hidden, value, 0); if (strcasecmp(name, "Saturation") == 0) return hidden->vt->SetSmth4(hidden, value, 0); if (strcasecmp(name, "Hue") == 0) return hidden->vt->SetSmth5(hidden, value, 0); if (strcasecmp(name, "MaxAuto") == 0) { this->m_iMaxAuto = value; } return 0; }#if 0 if (strcmp((const char*)record.dll, "ir50_32.dll") == 0) { IHidden2* hidden = 0; if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) { LOG_MSG("No such interface"); return -1; } int recordpar[30]; recordpar[0]=0x7c; recordpar[1]=fccIV50; recordpar[2]=0x10005; recordpar[3]=2; recordpar[4]=1; recordpar[5]=0x80000000; if (strcmp(name, "Brightness") == 0) { recordpar[5]|=0x20; recordpar[18]=value; } else if (strcmp(name, "Saturation") == 0) { recordpar[5]|=0x40; recordpar[19]=value; } else if (strcmp(name, "Contrast") == 0) { recordpar[5]|=0x80; recordpar[20]=value; } if(!recordpar[5]) { hidden->vt->Release((IUnknown*)hidden); return -1; } HRESULT result = hidden->vt->DecodeSet(hidden, recordpar); hidden->vt->Release((IUnknown*)hidden); return result; }#endif// LOG_MSG("DS_SetValue for ????, name=%s value=%d",name,value); return 0;}/*vim: vi* sux.*/int DS_SetAttr_DivX(char* attribute, int value){ int result, status, newkey; if(strcasecmp(attribute, "Quality")==0){ char* keyname="SOFTWARE\\Microsoft\\Scrunch"; result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); if(result!=0) { LOG_MSG("VideoDecoder::SetExtAttr: registry failure"); return -1; } result=RegSetValueExA(newkey, "Current Post Process Mode", 0, REG_DWORD, &value, 4); if(result!=0) { LOG_MSG("VideoDecoder::SetExtAttr: error writing value"); return -1; } value=-1; result=RegSetValueExA(newkey, "Force Post Process Mode", 0, REG_DWORD, &value, 4); if(result!=0) { LOG_MSG("VideoDecoder::SetExtAttr: error writing value"); return -1; } RegCloseKey(newkey); return 0; } if( (strcasecmp(attribute, "Saturation")==0) || (strcasecmp(attribute, "Hue")==0) || (strcasecmp(attribute, "Contrast")==0) || (strcasecmp(attribute, "Brightness")==0) ) { char* keyname="SOFTWARE\\Microsoft\\Scrunch\\Video"; result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); if(result!=0) { LOG_MSG("VideoDecoder::SetExtAttr: registry failure"); return -1; } result=RegSetValueExA(newkey, attribute, 0, REG_DWORD, &value, 4); if(result!=0) { LOG_MSG("VideoDecoder::SetExtAttr: error writing value"); return -1; } RegCloseKey(newkey); return 0; } LOG_MSG("Unknown attribute!"); return -200;}#endif // (C_HAS_DIRECTSHOW)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -