ПрограммированиеФорумЗвук

FFMpeg вывод при помощи OpenAL

Страницы: 1 2 3 Следующая »
#0
7:13, 9 мар 2018

Пытаюсь Воспроизвести звук при помощи связки OpenAL+FFmpeg Вывода звука вроде добился, но звук идет с прерываниями ,треском(Треск особенно заметен если уменьшать размер буффера)  и как-будто заикаится что-ли. Вот так я декодирую и передаю звук в OpenAL

function TOggStream.Playback: Boolean;
begin
  if Playing then
  begin
    Result := True;
    exit;
  end;
  if not Stream(Buffers[0]) then
  begin
    Result := False;
    exit;
  end;
  if not Stream(Buffers[1]) then
  begin
    Result := False;
    exit;
  end;
  alSourceQueueBuffers(Source, 2, @Buffers);
  alSourcePlay(Source);
  Result := True;
end;



function TOggStream.Update: Boolean;
var
  Processed: Integer;
  Active: Boolean;
  Buffer: TALUInt;
begin
  Active := False;
  alGetSourcei(Source, AL_BUFFERS_PROCESSED, @Processed);
  if Processed > 0 then
    repeat
      alSourceUnqueueBuffers(source, 1, @Buffer);
      Active := Stream(Buffer);
      alSourceQueueBuffers(source, 1, @Buffer);
      dec(Processed);
    until Processed <= 0;
  Result := Active;
end;

function TOggStream.Stream(Buffer : TALUInt) : Boolean;
var
 MMyData,MMyData2: PByte;
 dataa:byte;
 Size,NewSize    : Integer;
 Res,Mres     : Integer;
 ff,icnt,remaining,decoded:       integer;
 BufferTMP:array[1..BufferSize] of Integer;
 begin
Size := 0;

zeroMemory(@BufferTMP,SizeOf(BufferTMP));

while (Size < BufferSize) do
 begin
 av_read_frame(fmt_ctx, @MyPacket);
    begin
 if(MyPacket.stream_index=audio_index) then
      begin

       decoded:=avcodec_decode_audio4(dec_ctxAud, AudFrame, ff, @MyPacket);

        if ff>0 then
        begin
      Res:=av_samples_get_buffer_size(@AudFrame.linesize[0], AudFrame.channels,Audframe.nb_samples, dec_ctxAud.sample_fmt,1);;
   av_samples_alloc(MmyData, @AudFrame.linesize[0], AudFrame.channels, AudFrame.nb_samples, AV_SAMPLE_FMT_S16, 0);
 FrameFinished := swr_convert(swr,MmyData, AudFrame.nb_samples,AudFrame.Data[0] , AudFrame.nb_samples);
    Mres:=av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)*AudFrame.channels*FrameFinished;
     CopyMemory(@BufferTMP, MmyData, Mres );


          end;
        Application.ProcessMessages;
      end;

     av_free_packet(@MyPacket);


    end;


 if Res > 0 then
 begin

  inc(Size,Res);

  end
 else
  if Res < 0 then
   Log.Add(ErrorString(Res))
  else
   break;
 end;


 alBufferData(Buffer, audFormat, @BufferTMP, size,dec_ctxAud.sample_rate );

 Result := True;


end;

Если будет нужно приложу весь исходный код, кто сталкивался, подскажите пожалуйста

#1
10:14, 9 мар 2018

С этим делом я ещё не разбирался, но в исходниках Newton Dynamics в OpenAL накопал как раз код декодирования звука FFmpeg, и он гораздо больше твоего :) сам потом хочу его использовать.

#2
10:21, 9 мар 2018

RedCat
а если  Application.ProcessMessages; закомментировать ?
просто тут как - ты в своем цикле говоришь внешнему гуи обновиться(проверить состояния...) тут появляются временные задержки и они могут быть разными по длительности,
отсюда происходят провалы в воспроизведении и соответственно заикания.
Могу только посоветовать использовать отдельный поток - в котором у тебя будет производится все что связано со звуком.

#3
10:51, 9 мар 2018

Daniil Petrov
С этим делом я ещё не разбирался, но в исходниках Newton Dynamics в OpenAL накопал как раз код декодирования звука FFmpeg, и он гораздо больше твоего :) сам потом хочу его использовать.

Этот код, некая модификация известного примера OGG_OpenAl где используется библиотека vorbis, спасибо за ссылку посмотрю

gambit_oz
RedCat
а если  Application.ProcessMessages; закомментировать ?
просто тут как - ты в своем цикле говоришь внешнему гуи обновиться(проверить состояния...) тут появляются временные задержки и они могут быть разными по длительности,
отсюда происходят провалы в воспроизведении и соответственно заикания.
Могу только посоветовать использовать отдельный поток - в котором у тебя будет производится все что связано со звуком.

Спасибо ограмное за совет я обязательно попробую.


А еще у меня было предположение что вся проблема в том что массив BufferTMP в конце забит 0 или OpenAl игнорирует 0 в конце буффера?

#4
15:57, 9 мар 2018

gambit_oz
RedCat
а если  Application.ProcessMessages; закомментировать ?
просто тут как - ты в своем цикле говоришь внешнему гуи обновиться(проверить состояния...) тут появляются временные задержки и они могут быть разными по длительности,
отсюда происходят провалы в воспроизведении и соответственно заикания.
Могу только посоветовать использовать отдельный поток - в котором у тебя будет производится все что связано со звуком.

К сожалению удаление из кода processsmessage не помогло, и вынос в отдельный поток тоже

#5
17:33, 9 мар 2018

заикание результат либо окончания буфера прежде чем был добавлен следующий, либо неверного чтения блоков.
Требуется накачать десяток буферов перед запуском проигрывания, кроме того частота вызова функции докачки блоков неопределена, и точно зафиксировать не получиться, проще поддерживать определенный запас, и бросать несколько блоков за раз, если понадобиться.
как следствие
-запуск декодера в отдельном потоке с подъемом приоритета потока до максимального.
-декодер непрерывно работает пока не создаст запас блоков на половину секунды, или около того(не 2 блока большого размера  а 100 мелкого)
-поток ожидает в таймере половину накопленного периода времени, и потом повторяет цикл вновь.
-воспроизведение начинается не раньше чем буфер будет заполнен блоками полностью в первый раз

при достижении нормального звука можно поэкспериментировать с урезанием длины запаса и увеличением частоты обновления буфера, но момент начала заиканий зависит от нагрузки процессора в данный момент. Предположение о том что функция ожидающая 1ms подождет 1ms излишне оптимистичны. поэтому затруднительно поддерживать частоту заливки буферов близкую  их длине.

#6
17:39, 9 мар 2018

ShadowTeolog
> -запуск декодера в отдельном потоке с подъемом приоритета потока до максимального.
А сейчас так и делают, запускают декодирование звука и изображения в двух отдельных от основного потоках, я так и собираюсь делать!

#7
23:33, 10 мар 2018

ShadowTeolog

заикание результат либо окончания буфера прежде чем был добавлен следующий, либо неверного чтения блоков.
Требуется накачать десяток буферов перед запуском проигрывания, кроме того частота вызова функции докачки блоков неопределена, и точно зафиксировать не получиться, проще поддерживать определенный запас, и бросать несколько блоков за раз, если понадобиться.
как следствие
-запуск декодера в отдельном потоке с подъемом приоритета потока до максимального.
-декодер непрерывно работает пока не создаст запас блоков на половину секунды, или около того(не 2 блока большого размера  а 100 мелкого)
-поток ожидает в таймере половину накопленного периода времени, и потом повторяет цикл вновь.
-воспроизведение начинается не раньше чем буфер будет заполнен блоками полностью в первый раз
при достижении нормального звука можно поэкспериментировать с урезанием длины запаса и увеличением частоты обновления буфера, но момент начала заиканий зависит от нагрузки процессора в данный момент. Предположение о том что функция ожидающая 1ms подождет 1ms излишне оптимистичны. поэтому затруднительно поддерживать частоту заливки буферов близкую  их длине.

Спасибо, Ваш совет помог! все работает как нужно, за исключением одного, проц загружен в пределах 40-70% так же по идее быть не должно?

#8
23:41, 10 мар 2018

Все разобрался, в потоке декодирования написал Sleep(1); нагрузка на ЦП стала не более 3%

#9
2:57, 11 мар 2018

Раз тема разрешилась, спрошу своё, никто не пробовал libflac в играх? Как оно по скорости?

#10
4:10, 11 мар 2018

Dimich
> Раз тема разрешилась, спрошу своё, никто не пробовал libflac в играх? Как оно по скорости?
А чем хуже Ogg Vorbis?

#11
5:54, 11 мар 2018

Daniil Petrov
> А чем хуже Ogg Vorbis?
Кто сказал, что хуже?

#12
6:01, 11 мар 2018

Dimich
А зачем тогда тебе flac :)

#13
13:36, 11 мар 2018

Daniil Petrov
> А зачем тогда тебе flac :)
чтоб игра внушительно весила, чтоб её качали, думая что это ааа тайтл

RedCat
сделал то что?

#14
13:59, 11 мар 2018

*Lain*
> чтоб игра внушительно весила, чтоб её качали, думая что это ааа тайтл
Наподобие этой хохмы? Как палка копчёной колбасы в штанах для понта :)))

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумЗвук

Тема в архиве.