DirectShow: 我对asf文件进行加密,能不能写一个source filter进行动态解密?
要求不能生成临时文件 问题点数:200、回复次数:19Top
1 楼robothn(雷鸟)回复于 2003-03-31 16:52:45 得分 0
更正:
加密的源文件不一定是asf,有可能是avi, wmv等
现在难点在不知道如何将我的source filter 输出连接到DShow的其他SourceFilter上Top
2 楼CCBeyond(西别_&_钱不够用)回复于 2003-04-03 09:55:37 得分 50
GZTop
3 楼sjsj(虚怀若谷)回复于 2003-04-03 12:20:35 得分 20
高手,我学了好一阵子还是没有写出一个filter来。
帮你upTop
4 楼robothn(雷鸟)回复于 2003-04-03 12:30:43 得分 0
写出来一定公贴源码Top
5 楼sjsj(虚怀若谷)回复于 2003-04-03 15:15:42 得分 20
帮你upTop
6 楼robothn(雷鸟)回复于 2003-04-04 17:50:09 得分 0
也请帮忙up一下
http://expert.csdn.net/Expert/topic/1610/1610704.xml
thanksTop
7 楼cllr(寂寞2001)回复于 2003-04-04 22:14:04 得分 50
在你的FILTER和其他FILTER之间加一个转换用的FILTER可以吗?Top
8 楼robothn(雷鸟)回复于 2003-04-07 08:49:49 得分 0
这是另一个贴子
http://expert.csdn.net/Expert/topic/1610/1610704.xm
主 题: DirectShow:如何做一个File Source Filter?
作 者: robothn (雷鸟)
等 级:
信 誉 值: 100
所属论坛: VC/MFC 基础类
问题点数: 200
回复次数: 15
发表时间: 2003-4-2 18:57:37
怎么做一个支持读取一种未支持文件SourceFilter
是一种加密过的mp3,加/解密算法都有
这样继承行不行?给点提示也行
回复人: robothn(雷鸟) ( ) 信誉:100 2003-4-2 19:02:33 得分:0
因解密需打开整个文件进行验证,所以不能做成一个Transform Fiter
我不知道DShow 的Stream实现细节,有哪位高人能说说吗?
解密用的com组件是另一个公司的,没源码,只能全文件访问,也就是说
我得自己读文件,生成stream
Top
9 楼robothn(雷鸟)回复于 2003-04-09 13:19:42 得分 0
今天从memfile 改造了一下,现在可以放加密mp3 了,原码如下
class CCDIPin : public CAsyncStream
{
public:
CCDIPin();
virtual ~CCDIPin();
/* Initialization */
HRESULT Init(LPCOLESTR lpwszFileName, DWORD dwKBPerSec = INFINITE);
HRESULT SetPointer(LONGLONG llPos);
HRESULT Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead);
LONGLONG Size(LONGLONG *pSizeAvailable);
DWORD Alignment() { return 1; }
void Lock() { m_csLock.Lock(); }
void Unlock() { m_csLock.Unlock(); }
private:
CCdiDec m_decoder; // 我的解码器,封装了一个dll中的函数调用
CCritSec m_csLock;
DWORD m_dwSize;
DWORD m_dwPosition;
DWORD m_dwKBPerSec;
DWORD m_dwTimeStart;
};
class CCDISource : public CAsyncReader
{
public:
CCDISource(CCDIPin *pStream, CMediaType *pmt, HRESULT *phr)
: CAsyncReader(NAME("CDI source filter"), NULL, pStream, phr)
{
m_mt = *pmt;
}
~CCDISource() {};
// We're not going to be CoCreate'd so we don't need registration
// stuff etc
STDMETHODIMP Register()
{
return S_OK;
}
STDMETHODIMP Unregister()
{
return S_OK;
}
};
Top
10 楼robothn(雷鸟)回复于 2003-04-09 13:57:34 得分 0
忘了头文件中还包含三个头文件:
#include "..\include\asyncio.h"
#include "..\include\asyncrdr.h"
#include "cdidec.h"// for class CCdiDec
// 实现 File: CDIFilter.cpp
#include <streams.h>
#include "CDISource.h"
CCDIPin::CCDIPin()
: m_dwPosition(0), m_dwSize(0), m_dwKBPerSec(INFINITE)
{}
CCDIPin::~CCDIPin()
{}
HRESULT CCDIPin::Init(LPCOLESTR lpwszFileName, DWORD dwKBPerSec)
{
if(S_OK != m_decoder.LoadFile(lpwszFileName))
return S_FALSE;
if(S_OK != m_decoder.GetSize(&m_dwSize))
return S_FALSE;
m_dwKBPerSec = dwKBPerSec;
m_dwTimeStart = timeGetTime();
return S_OK;
}
HRESULT CCDIPin::SetPointer(LONGLONG llPos)
{
if (llPos < 0 || llPos > (LONGLONG)m_dwSize)
return S_FALSE;
m_dwPosition = (DWORD)llPos;
return S_OK;
}
HRESULT CCDIPin::Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead)
{
CAutoLock lck(&m_csLock);
DWORD dwReadLength;
/* Wait until the bytes are here! */
DWORD dwTime = timeGetTime();
if (m_dwPosition + dwBytesToRead > m_dwSize)
dwReadLength = (DWORD)(m_dwSize - m_dwPosition);
else
dwReadLength = dwBytesToRead;
DWORD dwTimeToArrive = (m_dwPosition + dwReadLength) / m_dwKBPerSec;
if (dwTime - m_dwTimeStart < dwTimeToArrive)
{
Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
}
HRESULT hr = m_decoder.ReadData(m_dwPosition, pbBuffer, dwReadLength, &dwReadLength);
ASSERT(hr == S_OK);
m_dwPosition += dwReadLength;
*pdwBytesRead = dwReadLength;
return S_OK;
}
LONGLONG CCDIPin::Size(LONGLONG *pSizeAvailable)
{
LONGLONG llCurrentAvailable =
static_cast <LONGLONG> (UInt32x32To64((timeGetTime() - m_dwTimeStart), m_dwKBPerSec));
*pSizeAvailable = min((LONGLONG)m_dwSize, llCurrentAvailable);
return (LONGLONG)m_dwSize;
}
//测试程序
#include <streams.h>
#include <stdio.h>
#include <asyncio.h>
#include <asyncrdr.h>
#include "memfile.h"
#include "cdisource.h"
/* Fail gracefully if UNICODE build is enabled */
#ifdef UNICODE
#error This application does not build for UNICODE.
#endif
/* Function prototypes */
HRESULT SelectAndRender(CMemReader *pReader, IFilterGraph **pFG);
HRESULT PlayFileWait(IFilterGraph *pFG);
/* Read a file into memory, play it (or part of it), then exit */
int main(int argc, char *argv[])
{
CMediaType mt;
mt.majortype = MEDIATYPE_Stream;
mt.subtype = MEDIASUBTYPE_NULL;
HRESULT hr = S_OK;
CoInitialize(NULL);
CCDIPin Stream;
Stream.Init(L"c:\\temp\\coffee3.cdi");
CCDISource Source(&Stream, &mt, &hr);
if (FAILED(hr)) {
printf("Could not create filter HRESULT 0x%8.8X\n", hr);
CoUninitialize();
return 1;
}
// Make sure we don't accidentally go away!
Source.AddRef();
IFilterGraph *pFG = NULL;
/* Create filter graph */
// 下面都没有验证返回值,我设了断点,一步一步跟的
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IFilterGraph, (void**) &pFG);
/* Add our filter */
hr = pFG->AddFilter(&Source, NULL);
/* Render our output pin */
IGraphBuilder *pBuilder;
hr = pFG->QueryInterface(IID_IGraphBuilder, (void **)&pBuilder);
hr = pBuilder->Render(Source.GetPin(0));
pBuilder->Release();
if (FAILED(hr))
printf("Failed to create graph and render file HRESULT 0x%8.8X", hr);
else
{
// Play the file
HRESULT hr = PlayFileWait(pFG);
if (FAILED(hr)) {
printf("Failed to play graph HRESULT 0x%8.8X",
hr);
}
}
if (pFG) {
ULONG ulRelease = pFG->Release();
if (ulRelease != 0) {
printf("Filter graph count not 0! was %d", ulRelease);
}
}
CoUninitialize();
return 0;
}
HRESULT PlayFileWait(IFilterGraph *pFG)
{// 和原来一样,就不用写了
}
现在正在看asynio.cpp, asynrdr.cpp源码,看流的实现
另:帮忙up,我已经连发三贴了,不能继续贴了Top
11 楼ypyao85(云)回复于 2003-04-09 14:07:26 得分 20
那就up一个Top
12 楼sjsj(虚怀若谷)回复于 2003-04-09 14:47:17 得分 20
up
Top
13 楼robothn(雷鸟)回复于 2003-04-11 13:47:09 得分 0
//------------------------------------------------------------------------------
// File: CDISource.H
//
// Copyright (c) CDI Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef _CDI_FILTER_HEADER_
#define _CDI_FILTER_HEADER_
#pragma once
#include "..\include\asyncio.h"
#include "..\include\asyncrdr.h"
#include "cdidec.h" // 我对解密dll的封装类
// Filter name strings
// Show in GraphEdit->Graph->Insert Filters->DriectShow Filters
#define g_wszCDIFilterName L"File Source (CDI)"
#define g_wszCDIPinName L"CDI output"
#define BUF_SIZE 32*1024
/**********************************************
*
* Class declarations
*
**********************************************/
class CCDIPin : public CAsyncStream
{
public:
CCDIPin();
virtual ~CCDIPin();
/* Initialization */
HRESULT Init(LPCOLESTR lpwszFileName, CMediaType& mt, DWORD dwKBPerSec = INFINITE);
HRESULT SetPointer(LONGLONG llPos);
HRESULT Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead);
LONGLONG Size(LONGLONG *pSizeAvailable);
DWORD Alignment() { return 1; }
void Lock() { m_csLock.Lock(); }
void Unlock() { m_csLock.Unlock(); }
private:
CCdiDec m_decoder;
CCritSec m_csLock;
DWORD m_dwSize;
DWORD m_dwPosition;
DWORD m_dwKBPerSec;
DWORD m_dwTimeStart;
};
class CCDISource : public CAsyncReader, public IFileSourceFilter
{
private:
CCDISource(LPUNKNOWN pUnk, HRESULT *phr)
: CAsyncReader(NAME("CDI Source Filter"), pUnk, &m_Pin, phr)
{
memset(m_wszFilePath, 0, sizeof(m_wszFilePath));
m_mt.InitMediaType();
}
~CCDISource() {};
CCDIPin m_Pin;
OLECHAR m_wszFilePath[MAX_PATH];
public:
static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr);
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IFileSourceFilter)
return GetInterface((IFileSourceFilter *)this, ppv);
else
return CAsyncReader::NonDelegatingQueryInterface(riid, ppv);
}
STDMETHODIMP Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt);
STDMETHODIMP GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt);
};
#endif
// cdidec.h: interface for the CCdiDec class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CDIDEC_H__45D0EA4F_75AB_4201_AFB1_CAF7B2558317__INCLUDED_)
#define AFX_CDIDEC_H__45D0EA4F_75AB_4201_AFB1_CAF7B2558317__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "wtypes.h"
class CCdiDec
{
public:
CCdiDec();
virtual ~CCdiDec();
HRESULT LoadFile(LPCWSTR sEpaFileName);
HRESULT ReadData(DWORD dwReadPos, BYTE* pReadBuf, DWORD dwReadSize, DWORD* pdwActualReadBytes);
HRESULT GetSize(DWORD* pdwSize);
HRESULT GetExt(LPWSTR pszExt);
HRESULT UnpackToBuffer(PBYTE pBuf, DWORD dwBufSize);
private:
//私有变量省略
#ifdef _DEBUG
HRESULT UnpackToFile(LPCWSTR wszOutFile); // for debug only
#endif
};
#endif // !defined(AFX_UNPACK_H__45D0EA4F_75AB_4201_AFB1_CAF7B2558317__INCLUDED_)
Top
14 楼robothn(雷鸟)回复于 2003-04-11 13:54:59 得分 0
//------------------------------------------------------------------------------
// File: CDIGuids.h
//
// Desc: GUID definitions for CDISource filter set
//
// Copyright(c) CDI Corporation. All rights reserved.
//------------------------------------------------------------------------------
#pragma once
#ifndef __CDIGUIDS_DEFINED
#define __CDIGUIDS_DEFINED
// {71F75368-2974-40af-8A2C-5796CD4B6E1A}
DEFINE_GUID(CLSID_FileSourceCDI,
0x71f75368, 0x2974, 0x40af, 0x8a, 0x2c, 0x57, 0x96, 0xcd, 0x4b, 0x6e, 0x1a);
#endif
//------------------------------------------------------------------------------
// File: CDIFilter.cpp
//
//------------------------------------------------------------------------------
#include <streams.h>
#include "CDISource.h"
#include "CDIGuids.h"
/**********************************************
*
* CCDIPin Class
*
*
**********************************************/
CCDIPin::CCDIPin()
: m_dwPosition(0), m_dwSize(0), m_dwKBPerSec(INFINITE)
{}
CCDIPin::~CCDIPin()
{}
HRESULT CCDIPin::Init(LPCOLESTR lpwszFileName, CMediaType& mt, DWORD dwKBPerSec)
{
if(S_OK != m_decoder.LoadFile(lpwszFileName))
return S_FALSE;
if(S_OK != m_decoder.GetSize(&m_dwSize))
return S_FALSE;
WCHAR wszExt[10];
if(S_OK != m_decoder.GetExt(wszExt))
return S_FALSE;
mt.majortype = MEDIATYPE_Stream;
// begin media subtype map
// 暂时就支持这些了,其它的就是映射subtype,wma, wmv怎么赋值?
if (lstrcmpiW(wszExt, L"mpg") == 0)
mt.subtype = MEDIASUBTYPE_MPEG1System;
else if (lstrcmpiW(wszExt, L"mpa") == 0)
mt.subtype = MEDIASUBTYPE_MPEG1Audio;
else if (lstrcmpiW(wszExt, L"mpv") == 0)
mt.subtype = MEDIASUBTYPE_MPEG1Video;
else if (lstrcmpiW(wszExt, L"dat") == 0)
mt.subtype = MEDIASUBTYPE_MPEG1VideoCD;
else if (lstrcmpiW(wszExt, L"avi") == 0)
mt.subtype = MEDIASUBTYPE_Avi;
else if (lstrcmpiW(wszExt, L"mov") == 0)
mt.subtype = MEDIASUBTYPE_QTMovie;
else if (lstrcmpiW(wszExt, L"wav") == 0)
mt.subtype = MEDIASUBTYPE_WAVE;
else if (lstrcmpiW(wszExt, L"mp3") == 0)
mt.subtype = MEDIASUBTYPE_NULL;
// end media subtype map
m_dwKBPerSec = dwKBPerSec;
m_dwTimeStart = timeGetTime();
return S_OK;
}
HRESULT CCDIPin::SetPointer(LONGLONG llPos)
{
if (llPos < 0 || llPos > (LONGLONG)m_dwSize)
return S_FALSE;
m_dwPosition = (DWORD)llPos;
return S_OK;
}
HRESULT CCDIPin::Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead)
{
CAutoLock lck(&m_csLock);
DWORD dwReadLength;
/* Wait until the bytes are here! */
DWORD dwTime = timeGetTime();
if (m_dwPosition + dwBytesToRead > m_dwSize)
dwReadLength = (DWORD)(m_dwSize - m_dwPosition);
else
dwReadLength = dwBytesToRead;
DWORD dwTimeToArrive = (m_dwPosition + dwReadLength) / m_dwKBPerSec;
if (dwTime - m_dwTimeStart < dwTimeToArrive)
{
Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
}
HRESULT hr = m_decoder.ReadData(m_dwPosition, pbBuffer, dwReadLength, &dwReadLength);
ASSERT(hr == S_OK);
m_dwPosition += dwReadLength;
*pdwBytesRead = dwReadLength;
return S_OK;
}
LONGLONG CCDIPin::Size(LONGLONG *pSizeAvailable)
{
LONGLONG llCurrentAvailable =
static_cast <LONGLONG> (UInt32x32To64((timeGetTime() - m_dwTimeStart), m_dwKBPerSec));
*pSizeAvailable = min((LONGLONG)m_dwSize, llCurrentAvailable);
return (LONGLONG)m_dwSize;
}
/**********************************************
*
* CCDISource Class
*
* CreateInstance()
**********************************************/
CUnknown * WINAPI CCDISource::CreateInstance(IUnknown *pUnk, HRESULT *phr)
{
CCDISource *pNewFilter = new CCDISource(pUnk, phr );
if (phr)
{
if (pNewFilter == NULL)
*phr = E_OUTOFMEMORY;
else
*phr = S_OK;
}
return pNewFilter;
}
STDMETHODIMP CCDISource::Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt)
{
CheckPointer(lpwszFileName, E_POINTER);
if(pmt != NULL)
{
m_mt = *pmt;
m_mt.bTemporalCompression = TRUE;
m_mt.lSampleSize = 1;
}
HRESULT hr = m_Pin.Init(lpwszFileName, m_mt);//load 文件,初始化,并分析格式
if(hr == S_OK)
wcscpy(m_wszFilePath, lpwszFileName);
return hr;
}
STDMETHODIMP CCDISource::GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt)
{
CheckPointer(ppszFileName, E_POINTER);
*ppszFileName = NULL;
if (m_wszFilePath != NULL)
{
DWORD n = sizeof(WCHAR)*(1+lstrlenW(m_wszFilePath));
*ppszFileName = (LPOLESTR) CoTaskMemAlloc(n);
if (*ppszFileName != NULL)
CopyMemory(*ppszFileName, m_wszFilePath, n);
}
if (pmt!=NULL)
CopyMediaType(pmt, &m_mt);
return S_OK;
}
Top
15 楼robothn(雷鸟)回复于 2003-04-11 14:04:25 得分 0
//------------------------------------------------------------------------------
// File: Setup.cpp
//------------------------------------------------------------------------------
#include <streams.h>
#include <initguid.h>
#include "CDIGuids.h"
#include "CDISource.h"
// Note: It is better to register no media types than to register a partial
// media type (subtype == GUID_NULL) because that can slow down intelligent connect
// for everyone else.
// Filter setup data
// 这里指定该输出针支持哪种媒体类型,子类型 以便于下级流自动连接
const AMOVIESETUP_MEDIATYPE sudOpPinTypes =
{
&MEDIATYPE_Stream, // Major type
&MEDIASUBTYPE_NULL // Minor type
};
const AMOVIESETUP_PIN sudOutputCDIPin =
{
L"Output", // LPWSTR strName; Obsolete(not used).
FALSE, // BOOL bRendered; Is this pin rendered?
TRUE, // BOOL bOutput; Is it an output pin?
FALSE, // BOOL bZero; Can the filter create zero instances?
FALSE, // BOOL bMany; Does the filter create multiple instances?
&CLSID_NULL, // const CLSID *clsConnectsToFilter; Obsolete.
NULL, // const WCHAR *strConnectsToPin; Obsolete.
1, // UINT nMediaTypes; Number of media types.
&sudOpPinTypes // const REGPINTYPES *lpMediaType; Pointer to media types.
};
// For a specialized source filter like this, it is best to leave out the
// AMOVIESETUP_FILTER altogether, so that the filter is not available for
// intelligent connect. Instead, use the CLSID to create the filter or just
// use 'new' in your application.
const AMOVIESETUP_FILTER sudCDISource =
{
&CLSID_FileSourceCDI, // Filter CLSID
g_wszCDIFilterName, // String name
MERIT_NORMAL, // Filter merit
1, // Number pins
&sudOutputCDIPin // Pin details
};
// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance.
// We provide a set of filters in this one DLL.
CFactoryTemplate g_Templates[1] =
{
{
g_wszCDIFilterName, // Name
&CLSID_FileSourceCDI, // CLSID
CCDISource::CreateInstance, // Method to create an instance of MyComponent
NULL, // Initialization function
&sudCDISource // Set-up information (for filters)
}
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
////////////////////////////////////////////////////////////////////////
//
// Exported entry points for registration and unregistration
// (in this case they only call through to default implementations).
//
////////////////////////////////////////////////////////////////////////
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2( TRUE );
}
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2( FALSE );
}
//
// DllEntryPoint
//
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}
//总算贴完了,cdidec.cpp涉及公司机密,就不贴了,cdidec.h也不算全,
//只是有一些方法声明
//生成的cdifilter.ax文件用 regsvr32 cdifilter.ax注册即可,
//这时*.cdi就可以在Win Media player 7和9中(只试了这两个)直接打开播放
//帮忙up,以便以后补充,thanks
Top
16 楼niuniuboby(想回家)回复于 2003-04-11 17:28:52 得分 20
markTop
17 楼robothn(雷鸟)回复于 2003-05-19 16:22:43 得分 0
另外注册表里还要加一项:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Media Type\Extensions\.cdi]
"Source Filter"="{71F75368-2974-40af-8A2C-5796CD4B6E1A}"
Top
18 楼robothn(雷鸟)回复于 2003-05-19 16:24:11 得分 0
{71F75368-2974-40af-8A2C-5796CD4B6E1A}
这个是filter的 CLSID
Top
19 楼robothn(雷鸟)回复于 2003-07-07 15:45:39 得分 0
这里没有解决asf文件,请继续关注
http://expert.csdn.net/Expert/TopicView1.asp?id=1998444Top



