На редите писали в тему undertale, типа зачем flac, если оно составляет 70% от размера игры, и писали же, чтоб для понтов. А игра, блин, весит 200 метров, что за дебилизм? Я спрашиваю, потому что flac проще декодировать, если верить примерам на github, вот мне интересно, так ли это.
Оказалось тема не совсем решена, теперь проблема с ресемпленгом. Как-то swr_convert не адекватно себя ведет, т.е если ей скормить формат семплов AV_SAMPLE_FMT_S16P то она нормально превращает его в AV_SAMPLE_FMT_S16, а если входной формат семпла AV_SAMPLE_FLTP то опять начинаются заикания, и какие-то звуковые артефакты, что опять этому FFMPEG'у не нравится?
Вот так я вызываю функцию:
... 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; ...
Вот так инициализирую контекст:
... swr := swr_alloc(); av_opt_set_int( swr, 'in_channel_layout', dec_ctxAud.channel_layout, 0); av_opt_set_int( swr, 'out_channel_layout', dec_ctxAud.channel_layout, 0); av_opt_set_int( swr, 'in_sample_rate', dec_ctxAud.sample_rate, 0); av_opt_set_int( swr, 'out_sample_rate', dec_ctxAud.sample_rate, 0); av_opt_set_sample_fmt( swr, 'in_sample_fmt', dec_ctxAud.sample_fmt, 0); av_opt_set_sample_fmt( swr, 'out_sample_fmt', AV_SAMPLE_FMT_S16, 0); swr_init( swr); ...
Нашел один способ:
swr_convert(&outputBuffer, audioFrame->nb_samples, audioFrame->extended_data, audioFrame->nb_samples);
Си не знаю вообще, но подозреваю что в делфи это должно выглядеть как-то так:
swr_convert(swr,@outputBuffer, audioFrame.nb_samples, audioFrame.extended_data, audioFrame.nb_samples)
Но я не могу в делфи так сделать, потому-что:
function swr_convert(s: PSwrContext; var out_: PByte; out_count: integer; var in_: PByte; in_count: integer): integer; cdecl; external LIB_SWRESAMPLE;
а тип AVFrame представлен так:
TAVFrame = record data: array [0..AV_NUM_DATA_POINTERS - 1] of PByte; linesize: array [0..AV_NUM_DATA_POINTERS - 1] of integer; extended_data: Pointer; ... end;
А если приводить тип через Pbyte(extended_data) swr_convert ругается, я думаю изза того что extended_data скорее всего является массивом
Dimich
> потому что flac проще декодировать
Тебе не хватает ресурсов процессора? Или ты не можешь настрочить класс декодера? :))) хыыыыыы
Здесь на форуме есть пример декодера Ogg Vorbis для OpenAL, но он не работает, я взял креативовский и сделал из него буферизированный и поточный декодеры в одном классе, повыпилив кучу лишнего кода.
А вообще Ogg Vorbis на мой взгляд идеальное решение = круче MP3 (большее сжатие при лучшем качестве) и свободный для использования :) хотя где-то промелькивал код декодирования ADPCM.
RedCat
посмотри сурцы - там есть примеры пользования swr_convert
https://github.com/DelphiForBroadcasting/ffmpeg-delphi
gambit_oz
посмотри сурцы - там есть примеры пользования swr_convert
https://github.com/DelphiForBroadcasting/ffmpeg-delphi
К сожалению там нет примера использования именно swr_convert
Daniil Petrov
mp3 тоже свободное для использования. Ты отстал от жизни
*Lain*
> Ты отстал от жизни
Ogg Vorbis изначально официально свободный формат, а у MP3 всего лишь закончилась лицензия.
Ты и сам прекрасно знаешь, что Ogg Vorbis имеет лучшее соотношение качество / степень сжатия, имеет большее количество каналов и прекрасно стримится.
Продолжать можно и дальше, но это уже будет словесный понос а-ля "Ты отстал от жизни"...
Daniil Petrov
> что Ogg Vorbis имеет лучшее соотношение качество / степень сжатия
Вот я не знаю. Моя практика говорит что ogg vorbis и variable bitrate mp3 +- погрешность одинаковы по качество/степень сжатия.
помогите пожалуйста перевести это в Delphi
static inline int convert_frame(SwrContext *s, AVFrame *out, const AVFrame *in) { int ret; uint8_t **out_data = NULL; const uint8_t **in_data = NULL; int out_nb_samples = 0, in_nb_samples = 0; if ( out) { out_data = out->extended_data; out_nb_samples = out->nb_samples; } if ( in) { in_data = ( const uint8_t **)in->extended_data; in_nb_samples = in->nb_samples; } ret = swr_convert( s, out_data, out_nb_samples, in_data, in_nb_samples); if ( ret < 0) { if ( out) out->nb_samples = 0; return ret; } if ( out) out->nb_samples = ret; return 0; }
RedCat
Это декодирование видео? Можешь кинуть ссылочку на исходники?
Вот :
http://ffmpeg.org/doxygen/2.7/files.html - Описание файлов исходников ffmpeg
https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/939440a - Сами исходники ffmpeg
RedCat
Просто я видел у них какой-то пример декодирования видео со звуком, так он устарел настолько, что в новых сборках начиная с версии 3.4.1 использующиеся нам функции отсутствую напрочь :) и не знаю, обновили они его или нет, но смотрел я его однако в прошлом году, что ли... и функции не отличаются от тех, которые я использовал сам.
Я вроде понял чего хочет от меня Libswr, когда я делаю так:
swr_convert(swr,MmyData, AudFrame.nb_samples,Pbyte( AudFrame.extended_Data) , AudFrame.nb_samples);
Вылетает AccessViolation at adress 00000000 Read of address 0000000. Скорее всего это происходит изза того что extended_Data пуста и её нужно как то инициализировать, но как вот вопрос...
У них на сайте написано это:
uint8_t** AVFrame::extended_data
pointers to the data planes/channels.
For video, this should simply point to data[].
For planar audio, each channel has a separate data pointer, and linesize[0] contains the size of each channel buffer. For packed audio, there is just one data pointer, and linesize[0] contains the total size of the buffer for all channels.
Note: Both data and extended_data will always be set by get_buffer(), but for planar audio with more channels that can fit in data, extended_data must be used by the decoder in order to access all channels.
encoding: set by user decoding: set by AVCodecContext.get_buffer()
Definition at line 1028 of file avcodec.h.
Может кто нибудь перевести что они хотят сказать?
RedCat
Точно :) у меня исходники последней версии (3.4.2) и в них тот самый пример :))) придётся как-то извращаться, чтоб родить плейер на их SDK... других нормальных SDK всё равно нету, а BinkVideo платный
Тема в архиве.