如何使用 ASF Writer 更快地压缩 WMV? 有什么提示吗?
我正在使用 ASF Writer 将原始 AVI 文件压缩为 WMV。 我非常需要加快压缩速度。 有任何提示和信息吗? 如何实现这一目标的最佳实践? 降低/降低索引器影响? 有任何隐藏压缩参数吗?
这些文件仅包含 RGB/24 位格式的视频,视频流的压缩级别在 200kbps 到 2000kbps 之间。
任何配置提示(使用 C++、C#、Delphi 等)
这是配置 WMV 编写器的代码部分(使用 DSPack)。
function CreateWMVWriter(VideoQuality, AudioQuality: Cardinal; videoInfo: PVideoInfoHeader; audioInfo: PWaveFormatEx; hasAudio: Boolean): IBaseFilter;
const
PROFILE_NAME = 'WMV AutoProfile';
// BUFFER_WINDOW = $FFFFFFFF; // auto buffer
BUFFER_WINDOW = 1000; // 1 second
MAX_KEY_FRAME_SPACING = 10000000; // 1 seconds
var
configWriter : IConfigAsfWriter;
profileManager : IWMProfileManager;
profile : IWMProfile;
stream : IWMStreamConfig;
mediaProps : IWMMediaProps;
vmediaProps : IWMVideoMediaProps;
pmt : PWMMediaType;
msize : Cardinal;
vih : PVideoInfoHeader;
wfe: PWaveFormatEx;
hr : HRESULT;
videoBitRate, audioBitRate: Cardinal;
width, height: Integer;
begin
videoBitRate := VideoQuality * 1000; // kbits
// create the profile
CheckDSError(WMCreateProfileManager(profileManager));
CheckDSError(profileManager.CreateEmptyProfile(WMT_VER_9_0, profile));
CheckDSError(profile.SetName(StringToOleStr(PROFILE_NAME)));
CheckDSError(profile.SetDescription(StringToOleStr(PROFILE_NAME)));
CheckDSError(profile.CreateNewStream(WMMEDIATYPE_Video, stream));
CheckDSError(stream.SetStreamName(StringToOleStr('Video')));
CheckDSError(stream.SetBitrate(videoBitRate));
CheckDSError(stream.SetBufferWindow(BUFFER_WINDOW));
// config video media type
stream.QueryInterface(IID_IWMMediaProps, mediaProps);
CheckDSError(mediaProps.GetMediaType(nil, msize));
GetMem(pmt, msize);
CheckDSError(mediaProps.GetMediaType(pmt, msize));
with pmt^ do
begin
majortype := WMMEDIATYPE_Video;
subtype := WMMEDIASUBTYPE_WMV3;
bFixedSizeSamples := True;
bTemporalCompression := True;
pUnk := nil;
vih := PVideoInfoHeader(pbFormat);
// copy video info header (the same as with the original - copy: rcSource, rcTarget, AvgTimePerFrame, biWidth, biHeight)
CopyMemory(vih, videoInfo, SizeOf(TVideoInfoHeader));
// set bit rate at the same value
vih.dwBitRate := videoBitRate;
// set new compression ('WMV3')
vih.bmiHeader.biCompression := MAKEFOURCC('W', 'M', 'V', '3');
end;
CheckDSError(mediaProps.SetMediaType(pmt));
FreeMem(pmt, msize);
// set media props
stream.QueryInterface(IID_IWMVideoMediaProps, vmediaProps);
CheckDSError(vmediaProps.SetQuality(100));
CheckDSError(vmediaProps.SetMaxKeyFrameSpacing(0));
// CheckDSError(vmediaProps.SetMaxKeyFrameSpacing(MAX_KEY_FRAME_SPACING));
// add video stream
CheckDSError(profile.AddStream(stream));
// add audio stream (if needed)
if hasAudio then
begin
CheckDSError(profile.CreateNewStream(WMMEDIATYPE_Audio, stream));
CheckDSError(stream.SetStreamName(StringToOleStr('Audio')));
audioBitRate := audioInfo.nSamplesPerSec * audioInfo.nChannels * audioInfo.wBitsPerSample;
CheckDSError(stream.SetBitrate(audioBitRate));
CheckDSError(stream.SetBufferWindow(BUFFER_WINDOW)); // auto
// config video media type
stream.QueryInterface(IID_IWMMediaProps, mediaProps);
CheckDSError(mediaProps.GetMediaType(nil, msize));
GetMem(pmt, msize);
hr := mediaProps.GetMediaType(pmt, msize);
with pmt^ do
begin
// uncompressed audio
majortype := WMMEDIATYPE_Audio;
subtype := WMMEDIASUBTYPE_PCM;
formattype := WMFORMAT_WaveFormatEx;
cbFormat := sizeof(TWaveFormatEx);
bFixedSizeSamples := True;
bTemporalCompression := False;
lSampleSize := audioInfo.nChannels * audioInfo.wBitsPerSample div 8;
pUnk := nil;
wfe := PWaveFormatEx(pbFormat);
// copy video info header (the same as with the original)
CopyMemory(wfe, audioInfo, SizeOf(TWaveFormatEx));
end;
CheckDSError(mediaProps.SetMediaType(pmt));
FreeMem(pmt, msize);
// add video stream
CheckDSError(profile.AddStream(stream));
end;
// create the writer
Result := AddFilterGUID(CLSID_WMAsfWriter, 'WmvWriter');
// config the writer
configWriter := Result as IConfigAsfWriter;
CheckDSError(configWriter.SetIndexMode(True));
CheckDSError(configWriter.ConfigureFilterUsingProfile(profile));
end;
I'm compressing raw AVI files to WMV using the ASF Writer.
I'm in a big need to make the compression faster.
There are any hints & best practicevs on how to achieve this ? Drop/lower the indexer impact ? Any hidden compression parameters ?
The files contains just video in RGB/24bits format and the compression level for the video stream is between 200kbps and 2000kbps.
Any configuration hints (using C++, C#, Delphi, etc)
Here is the the part of the code (using DSPack) that configure the WMV writer.
function CreateWMVWriter(VideoQuality, AudioQuality: Cardinal; videoInfo: PVideoInfoHeader; audioInfo: PWaveFormatEx; hasAudio: Boolean): IBaseFilter;
const
PROFILE_NAME = 'WMV AutoProfile';
// BUFFER_WINDOW = $FFFFFFFF; // auto buffer
BUFFER_WINDOW = 1000; // 1 second
MAX_KEY_FRAME_SPACING = 10000000; // 1 seconds
var
configWriter : IConfigAsfWriter;
profileManager : IWMProfileManager;
profile : IWMProfile;
stream : IWMStreamConfig;
mediaProps : IWMMediaProps;
vmediaProps : IWMVideoMediaProps;
pmt : PWMMediaType;
msize : Cardinal;
vih : PVideoInfoHeader;
wfe: PWaveFormatEx;
hr : HRESULT;
videoBitRate, audioBitRate: Cardinal;
width, height: Integer;
begin
videoBitRate := VideoQuality * 1000; // kbits
// create the profile
CheckDSError(WMCreateProfileManager(profileManager));
CheckDSError(profileManager.CreateEmptyProfile(WMT_VER_9_0, profile));
CheckDSError(profile.SetName(StringToOleStr(PROFILE_NAME)));
CheckDSError(profile.SetDescription(StringToOleStr(PROFILE_NAME)));
CheckDSError(profile.CreateNewStream(WMMEDIATYPE_Video, stream));
CheckDSError(stream.SetStreamName(StringToOleStr('Video')));
CheckDSError(stream.SetBitrate(videoBitRate));
CheckDSError(stream.SetBufferWindow(BUFFER_WINDOW));
// config video media type
stream.QueryInterface(IID_IWMMediaProps, mediaProps);
CheckDSError(mediaProps.GetMediaType(nil, msize));
GetMem(pmt, msize);
CheckDSError(mediaProps.GetMediaType(pmt, msize));
with pmt^ do
begin
majortype := WMMEDIATYPE_Video;
subtype := WMMEDIASUBTYPE_WMV3;
bFixedSizeSamples := True;
bTemporalCompression := True;
pUnk := nil;
vih := PVideoInfoHeader(pbFormat);
// copy video info header (the same as with the original - copy: rcSource, rcTarget, AvgTimePerFrame, biWidth, biHeight)
CopyMemory(vih, videoInfo, SizeOf(TVideoInfoHeader));
// set bit rate at the same value
vih.dwBitRate := videoBitRate;
// set new compression ('WMV3')
vih.bmiHeader.biCompression := MAKEFOURCC('W', 'M', 'V', '3');
end;
CheckDSError(mediaProps.SetMediaType(pmt));
FreeMem(pmt, msize);
// set media props
stream.QueryInterface(IID_IWMVideoMediaProps, vmediaProps);
CheckDSError(vmediaProps.SetQuality(100));
CheckDSError(vmediaProps.SetMaxKeyFrameSpacing(0));
// CheckDSError(vmediaProps.SetMaxKeyFrameSpacing(MAX_KEY_FRAME_SPACING));
// add video stream
CheckDSError(profile.AddStream(stream));
// add audio stream (if needed)
if hasAudio then
begin
CheckDSError(profile.CreateNewStream(WMMEDIATYPE_Audio, stream));
CheckDSError(stream.SetStreamName(StringToOleStr('Audio')));
audioBitRate := audioInfo.nSamplesPerSec * audioInfo.nChannels * audioInfo.wBitsPerSample;
CheckDSError(stream.SetBitrate(audioBitRate));
CheckDSError(stream.SetBufferWindow(BUFFER_WINDOW)); // auto
// config video media type
stream.QueryInterface(IID_IWMMediaProps, mediaProps);
CheckDSError(mediaProps.GetMediaType(nil, msize));
GetMem(pmt, msize);
hr := mediaProps.GetMediaType(pmt, msize);
with pmt^ do
begin
// uncompressed audio
majortype := WMMEDIATYPE_Audio;
subtype := WMMEDIASUBTYPE_PCM;
formattype := WMFORMAT_WaveFormatEx;
cbFormat := sizeof(TWaveFormatEx);
bFixedSizeSamples := True;
bTemporalCompression := False;
lSampleSize := audioInfo.nChannels * audioInfo.wBitsPerSample div 8;
pUnk := nil;
wfe := PWaveFormatEx(pbFormat);
// copy video info header (the same as with the original)
CopyMemory(wfe, audioInfo, SizeOf(TWaveFormatEx));
end;
CheckDSError(mediaProps.SetMediaType(pmt));
FreeMem(pmt, msize);
// add video stream
CheckDSError(profile.AddStream(stream));
end;
// create the writer
Result := AddFilterGUID(CLSID_WMAsfWriter, 'WmvWriter');
// config the writer
configWriter := Result as IConfigAsfWriter;
CheckDSError(configWriter.SetIndexMode(True));
CheckDSError(configWriter.ConfigureFilterUsingProfile(profile));
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我对此确实没有太多经验,但根据其他地方发布的内容,尝试设置
WMMEDIASUBTYPE_WVC1
而不是WMMEDIASUBTYPE_WVC3
。 信息是从此处收集的。其他一些可能有用的链接:此处和这里
I really don't have a lot of experience with this, but from what has been posted elsewhere, try setting
WMMEDIASUBTYPE_WVC1
instead ofWMMEDIASUBTYPE_WVC3
. Information was gleaned from here.Some other links that might be helpful: here and here