В ffmpeg-0.5.0-alt1.svn8927 сломано декодирование DTS - проявляется как в ffplay, так и в других программах (например, в mplayer). В частности, имеется файл (avi со звуковой дорожкой в dts), который в основном нормально проигрывается при использовании ffmpeg-0.5.0-alt1.svn7771. После обновления до ffmpeg-0.5.0-alt1.svn8927 выяснилось, что установленная ранее сборка mplayer-1.0-alt35.22092.1 перестала воспроизводить звук - как выяснилось, между этими версиями в ffmpeg добавили встроенную поддержку декодирования dts под именем "dca", а старая сборка mplayer знала только кодек с именем "dts" (это исправлено в codecs.conf в новом mplayer). Проблемы, относящиеся именно к ffmpeg: 1) Встроенный декодер с именем "dca", появившийся в новых версиях ffmpeg, не работает нормально - в местах, нормально воспроизводившихся с svn7771 (и внешней libdts), в ffplay возникает ужасный свист и куча ошибок: ERROR: block code look-up failed ERROR: block code look-up failed [dca @ 0xb7d3e184]Didn't get subframe DSYNC (хотя некоторые участки файла всё-таки воспроизводятся). В mplayer файл не воспроизводится вовсе - не появляется даже видео, а в терминал сыплются ошибки: [dca @ 0xb6f26184]Not a DCA frame 0.000 1/ 1 ??% ??% ??,?% 0 0 99% [dca @ 0xb6f26184]Not a DCA frame 0.004 2/ 2 ??% ??% ??,?% 0 0 99% [dca @ 0xb6f26184]Not a DCA frame 0.004 3/ 3 ??% ??% ??,?% 0 0 99% 2) Включение поддержки внешней libdts (пересборка с --enable-libdts) без отключения встроенного декодера dca недостаточно - например, заставить ffplay использовать кодек libdts вместо dca не удалось. 3) Пересборка с --enable-libdts --disable-decoder=dca на первый взгляд исправляет работу mplayer, однако при более внимательном анализе обнаружилось, что downmix в 2 канала выполняется некорректно - похоже, пропадает как минимум центральный канал, в результате диалоги в фильме не слышны. Кроме того, в ffplay и звук, и изображение воспроизводятся с очень сильным замедлением. 4) Вернуть старое поведение удалось только после пересборки с --enable-libdts --disable-decoder=dca и отката commit fb6069bf1668bb49fd966a9120da9e8bf0075ba0: fix multichannel decoding git-svn-id: svn://svn.mplayerhq.hu/ffmpeg/trunk@7839 В таком варианте вновь работает воспроизведение как в mplayer, так и в ffplay.
Хотя что-то этим коммитом всё-таки на самом деле исправлялось - например, преобразование dts в 6-канальный wav: ffmpeg -i file.avi -ac 6 file.wav До отката этого коммита (но с внешним libdts) создавался нормальный wav; после отката получается файл с сильно ускоренным звуком (эта же проблема была и в версии svn7771); с другой стороны, с -ac 2 до отката получался замедленный звук, а после отката - нормальный. Можно предположить, что в этом районе есть несколько багов, компенсирующих друг друга.
Created attachment 1961 [details] [PATCH 01] dtsdec: add missing break statements to convert2s16_multi() DTS decoding was broken for every speaker config except 5.1.
Created attachment 1962 [details] [PATCH 02] dtsdec: save frame flags in DTSContext Frame flags must be saved between calls to dts_decode_frame() (if the input buffer did not hold a complete frame, flags for that frame will be used by the next dts_decode_frame() call when the rest of frame data is available). Fixes "dts_frame() failed" errors in mplayer due to uninitialized garbage in flags.
Created attachment 1963 [details] [PATCH 03] dtsdec: downmix to mono or stereo if requested If avctx->channels is set to 1 or 2, ask libdts to downmix sound to the requested number of channels instead of returning all channels. This matches the AC3 decoder behavior and assumptions made by ffplay and ffmpeg programs. --- Этот патч не влияет на поведение mplayer, но исправляет проигрывание файла в ffplay (там не поддерживается больше 2 каналов, и если декодер всё же выдаёт более 2 каналов, они проигрываются как 2). В ffmpeg.c тоже имеется код, рассчитывающий на такое поведение декодера: if (codec->channels != icodec->channels && (icodec->codec_id == CODEC_ID_AC3 || icodec->codec_id == CODEC_ID_DTS)) { /* Special case for 5:1 AC3 and DTS input */ /* and mono or stereo output */ /* Request specific number of channels */ icodec->channels = codec->channels; if (codec->sample_rate == icodec->sample_rate) ost->audio_resample = 0; else { ost->audio_resample = 1; } } else { ost->audio_resample = 1; }
Да, после всех этих патчей в mplayer при наличии 2-канальной звуковой системы приходится использовать что-то типа "-af channels=2:6:0:0:1:1:2:0:3:1:4:0:4:1" (либо pan, где можно задать матрицу с уровнями), поскольку опция "-channels 2" не оказывает нужного влияния. Раньше в подобной ситуации mplayer работал без дополнительных опций, поскольку в старой версии ffmpeg в libdts всегда передавалось DTS_STEREO.
Created attachment 1964 [details] [PATCH 02] dtsdec: save flags, sample_rate, bit_rate in DTSContext Frame flags must be saved between calls to dts_decode_frame() (if the input buffer did not hold a complete frame, flags for that frame will be used by the next dts_decode_frame() call when the rest of frame data is available). Fixes "dts_frame() failed" errors in mplayer due to uninitialized garbage in flags. The sample_rate and bit_rate values also can be used by the next dts_decode_frame() call; uninitialized values can lead to SIGFPE in ffmpeg at the end of stream (when sample_rate == 0 is encountered). --- Заменяет предыдущий вариант патча; патч 03 не изменился.
Created attachment 1969 [details] [PATCH 04] dtsdec: fix attempts to decode incomplete frames When (!len) is checked in the buffer fill loop in dts_decode_frame(), the buffer does not contain a complete frame, therefore executing "break" when there is no more input data is not correct (subsequent code will try to decode the buffer, which then will lead to garbage output and sync loss). The proper action is to return the number of consumed bytes and wait for more data. The problematic case can be triggered by mplayer - apparently it passes the stream to decoder without caring about frame boundaries, and sometimes the data block happens to contain just the frame header; in this case the first pass through the loop will consume HEADER_SIZE bytes from the input data, and the second pass would trigger the bug.
Created attachment 1990 [details] [PATCH 05] dca: fix dca_bitalloc_index decoder init One of Huffman codes used in dca_bitalloc_index has 10-bit codes, but the decode table is built only for 9 bits, therefore the .wrap field must be set to 2 for correct decoding. --- Это уже исправление встроенного декодера (которое, правда, не помогает ему работать с mplayer).
так или иначе, исправлено.