Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / FFMpeg вывод при помощи OpenAL

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

Страницы: 1 2 3 Следующая »
RedCatПостоялецwww9 мар. 20187:13#0
Пытаюсь Воспроизвести звук при помощи связки 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;

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

Daniil PetrovЗабаненwww9 мар. 201810:14#1
С этим делом я ещё не разбирался, но в исходниках Newton Dynamics в OpenAL накопал как раз код декодирования звука FFmpeg, и он гораздо больше твоего :) сам потом хочу его использовать.
gambit_ozПостоялецwww9 мар. 201810:21#2
RedCat
а если  Application.ProcessMessages; закомментировать ?
просто тут как - ты в своем цикле говоришь внешнему гуи обновиться(проверить состояния...) тут появляются временные задержки и они могут быть разными по длительности,
отсюда происходят провалы в воспроизведении и соответственно заикания.
Могу только посоветовать использовать отдельный поток - в котором у тебя будет производится все что связано со звуком.
RedCatПостоялецwww9 мар. 201810:51#3
Daniil Petrov
С этим делом я ещё не разбирался, но в исходниках Newton Dynamics в OpenAL накопал как раз код декодирования звука FFmpeg, и он гораздо больше твоего :) сам потом хочу его использовать.

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

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


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

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

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

Правка: 9 мар. 2018 16:32

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

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

Daniil PetrovЗабаненwww9 мар. 201817:39#6
ShadowTeolog
> -запуск декодера в отдельном потоке с подъемом приоритета потока до максимального.
А сейчас так и делают, запускают декодирование звука и изображения в двух отдельных от основного потоках, я так и собираюсь делать!
RedCatПостоялецwww10 мар. 201823:33#7
ShadowTeolog
заикание результат либо окончания буфера прежде чем был добавлен следующий, либо неверного чтения блоков.
Требуется накачать десяток буферов перед запуском проигрывания, кроме того частота вызова функции докачки блоков неопределена, и точно зафиксировать не получиться, проще поддерживать определенный запас, и бросать несколько блоков за раз, если понадобиться.
как следствие
-запуск декодера в отдельном потоке с подъемом приоритета потока до максимального.
-декодер непрерывно работает пока не создаст запас блоков на половину секунды, или около того(не 2 блока большого размера  а 100 мелкого)
-поток ожидает в таймере половину накопленного периода времени, и потом повторяет цикл вновь.
-воспроизведение начинается не раньше чем буфер будет заполнен блоками полностью в первый раз
при достижении нормального звука можно поэкспериментировать с урезанием длины запаса и увеличением частоты обновления буфера, но момент начала заиканий зависит от нагрузки процессора в данный момент. Предположение о том что функция ожидающая 1ms подождет 1ms излишне оптимистичны. поэтому затруднительно поддерживать частоту заливки буферов близкую  их длине.

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

RedCatПостоялецwww10 мар. 201823:41#8
Все разобрался, в потоке декодирования написал Sleep(1); нагрузка на ЦП стала не более 3%

Правка: 10 мар. 2018 23:42

DimichПостоялецwww11 мар. 20182:57#9
Раз тема разрешилась, спрошу своё, никто не пробовал libflac в играх? Как оно по скорости?
Daniil PetrovЗабаненwww11 мар. 20184:10#10
Dimich
> Раз тема разрешилась, спрошу своё, никто не пробовал libflac в играх? Как оно по скорости?
А чем хуже Ogg Vorbis?
DimichПостоялецwww11 мар. 20185:54#11
Daniil Petrov
> А чем хуже Ogg Vorbis?
Кто сказал, что хуже?
Daniil PetrovЗабаненwww11 мар. 20186:01#12
Dimich
А зачем тогда тебе flac :)
*Lain*Постоялецwww11 мар. 201813:36#13
Daniil Petrov
> А зачем тогда тебе flac :)
чтоб игра внушительно весила, чтоб её качали, думая что это ааа тайтл

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

Правка: 11 мар. 2018 13:37

Daniil PetrovЗабаненwww11 мар. 201813:59#14
*Lain*
> чтоб игра внушительно весила, чтоб её качали, думая что это ааа тайтл
Наподобие этой хохмы? Как палка копчёной колбасы в штанах для понта :)))
Страницы: 1 2 3 Следующая »

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

2001—2018 © GameDev.ru — Разработка игр