Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.01.05;
Скачать: [xml.tar.bz2];

Вниз

Проблема при компрессии MPEG layer-3   Найти похожие ветки 

 
Verg   (2003-09-02 11:23) [0]

При компрессии указанным кодеком возникла проблема
acmStreamConver вызывает Invalid floating point operation в двух случаях:
1. Если исходный буфер содержит одни нули (тишина)
2. На последнем блоке преобразования, т.е. когда
ConvertFlags=ACM_STREAMCONVERTF_END;

Ничего понять не могу.
Когда сигнал осмысленный - работает без проблем. Однако последнее преобазование всеравно выдает IFPO.

С другими кодеками таких проблем не возникало.
Ни кто не знает в чем может быть дело? Что надо проверить? Хотя бы приблизитьельно.


 
Крот   (2003-09-02 11:35) [1]

А через DirectShow не пробовал?


 
Verg   (2003-09-02 11:40) [2]


> А через DirectShow не пробовал?


Нет не пробовал.


 
Verg   (2003-09-02 12:40) [3]

Кстати, эффект проявляется только при стереосигнале. Если канал сжатия один - все идет как надо.


 
Крот   (2003-09-02 16:43) [4]

А можно немного поподробнее, то есть надо сконверитровать существующий файл (скажем, WAV) в MPEG3? Или поступает звук со входа?


 
Verg   (2003-09-03 08:37) [5]

Да, есть поток в формате PCM, его надо преобразовать в один из компрессированных форматов (wav) из имеющихся в системе (установленных кодеков). Для этого я воспользовался штатным средством компресии в Windows - ACM. А точнее функциями acmSTREAM***.
Вот. И все компрессоры нормально работают, кроме MPEG Layer-3.
Этот при получении на вход порции данных содержащих одни нули (математический ноль, а не шумы сигнала) в стереосигнале (2 канала) и только в стереосигнале, вырабатывает исключение IFPO.
Кроме того, IFPO в этом случае он вырабатывает на любую порцию стереосигнала обозначенную в fdwConvert ACM_STREAMCONVERTF_END, т.е. на последнюю.
Если поставить acmSTREAMConvert в блок try except end, то при записи реального сигнала (имеющего в паузах шум, а не мат0) создается впечатление, что все нормально, файл получается, декодируется любым софтом, но последняя порция сигнала просто отсутствует. Тогда я стал разбираться. Навходе компрессора занулил поступающий поток и увидел, что выходного потока просто НЕТ. Оказалось то, о чем я писал раньше. Вот сижу теперь почти наугад проверяю всевозможные даже невероятные версии. Хотя кажется, что ошибка (или нехватка информации) должна быть простой и лежать на поверхности...


 
Verg   (2003-09-03 08:42) [6]

Да, то, что я считаю это моей ошибкой, а не глюком кодека основано на том, что SoundForge прекрасно записывает wav-ки в этом формате. Специально в нем синтезировал mute-сигнал на два канала и записывал в формате MPEG layer-3. Все SF записывает прекрасно, потом считывает и считывает сигнал той длительности, которую я изначально синтезировал.


 
Verg   (2003-09-03 11:58) [7]

Ну вот уже упростил до "безобразия".
Что же не так?

unit AcmMp3;

interface

function TryToCompressMP3:boolean;

implementation

uses Windows,SysUtils,MmSystem,MSACM;
const
WAVE_FORMAT_MPEG_LAYER3 = $55;

function TryToCompressMP3:boolean;
var Hdr : TACMSTREAMHEADER;
Tdtl: TACMFORMATTAGDETAILS;
WfSrc : TWaveFormatEx;
Wf : PWaveFormatEx;

Handle : HACMSTREAM;
DstBuffer,
Buffer : pchar;
BufferSize,
DstBuffSize : DWORD;

ConvertFlags : DWORD;

begin
result:=false;
// Заполняем заголовок псевдопотока
WfSrc.wFormatTag:=WAVE_FORMAT_PCM;
WfSrc.nChannels:=2; // Стерео
WfSrc.nSamplesPerSec:=8000;
WfSrc.wBitsPerSample:=16;
WfSrc.nBlockAlign:=WfSrc.nChannels*(WfSrc.wBitsPerSample div 8);
WfSrc.nAvgBytesPerSec:=WfSrc.nSamplesPerSec*WfSrc.nBlockAlign;
WfSrc.cbSize:=0;

FillChar(Tdtl, sizeof(Tdtl), 0);
Tdtl.cbStruct := sizeof (Tdtl);
Tdtl.dwFormatTag:=WAVE_FORMAT_MPEG_LAYER3;
Wf:=nil;
// Попросим у ACM размер формата данного типа
try
if acmFormatTagDetails(0, Tdtl, ACM_FORMATTAGDETAILSF_FORMATTAG)=MMSYSERR_NOERROR then
begin
Wf:=AllocMem(Tdtl.cbFormatSize);
Wf^.wFormatTag:=WAVE_FORMAT_MPEG_LAYER3;
// заполним Wf^ параметрами целевого формата
if acmFormatSuggest(0, WfSrc, Wf^, Tdtl.cbFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)<>MMSYSERR_NOERROR then exit;
end else abort;
BufferSize:=WfSrc.nBlockAlign*1024;// Ну например на 1024
Buffer:=AllocMem(BufferSize);
try
if acmStreamOpen(@Handle, 0, WfSrc, Wf^, nil, 0, 0,0)<>MMSYSERR_NOERROR then exit;
try
// Узнаем какой потребуется буфер выходного потока, для данного входного
if acmStreamSize(Handle, BufferSize, DstBuffSize, ACM_STREAMSIZEF_SOURCE)<>MMSYSERR_NOERROR then exit;
DstBuffer:=AllocMem(DstBuffSize);
try
ConvertFlags := ACM_STREAMCONVERTF_START or ACM_STREAMCONVERTF_BLOCKALIGN;

FillChar(Buffer^, BufferSize,0); // Закладываем во входном буфере одни нули

//Заполняем заголовок входного буфера потока ACM
FillChar(Hdr, sizeof(Hdr),0);
Hdr.cbStruct:=Sizeof(Hdr);
Hdr.pbSrc:=pbyte(Buffer);
Hdr.cbSrcLength:=BufferSize;
Hdr.pbDst:=pbyte(DstBuffer);
Hdr.cbDstLength:=DstBuffSize;

if acmStreamPrepareHeader(Handle, Hdr, 0)<>MMSYSERR_NOERROR then exit;
if acmStreamConvert(Handle, Hdr, ConvertFlags)<>MMSYSERR_NOERROR then exit;
if acmStreamUnPrepareHeader(Handle, Hdr, 0)<>MMSYSERR_NOERROR then exit;
result:=true;
finally
FreeMem(DstBuffer);
end;
finally
acmStreamClose(Handle,0);
end;
finally
Freemem(Buffer);
end;
finally
if Wf<>nil then FreeMem(Wf);
end;
end;

end.


 
Verg   (2003-09-03 12:47) [8]

Во дурь-то...

Оказывается
1. Размер входного буфера не должен превосходить 512 отсчетов
2. Размер входного буфера на последнее преобразование должен быть =0

О как!



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2004.01.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.013 c
3-11769
paul_k
2003-12-09 15:03
2004.01.05
Имя пользователя


6-12023
Kinder
2003-10-27 19:17
2004.01.05
Компонент для работы с RAS


14-12052
1008
2003-12-10 11:17
2004.01.05
Как не потерять деньги в WebMoney при переустановке Windows?


3-11819
new
2003-12-08 12:24
2004.01.05
dbloocupcombobox


1-11918
$Hic0
2003-12-20 21:43
2004.01.05
Переход с Delphi 6.0 в Delphi 7.0





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский