Bug 11760 - DTS (DCA) decoding is broken
Summary: DTS (DCA) decoding is broken
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: ffmpeg (show other bugs)
Version: unstable
Hardware: all Linux
: P2 normal
Assignee: Anton Farygin
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-14 20:20 MSD by Sergey Vlasov
Modified: 2007-07-13 12:49 MSD (History)
2 users (show)

See Also:


Attachments
[PATCH 01] dtsdec: add missing break statements to convert2s16_multi() (3.24 KB, patch)
2007-05-15 14:54 MSD, Sergey Vlasov
no flags Details | Diff
[PATCH 02] dtsdec: save frame flags in DTSContext (1.74 KB, patch)
2007-05-15 14:55 MSD, Sergey Vlasov
no flags Details | Diff
[PATCH 03] dtsdec: downmix to mono or stereo if requested (1.24 KB, patch)
2007-05-15 14:57 MSD, Sergey Vlasov
no flags Details | Diff
[PATCH 02] dtsdec: save flags, sample_rate, bit_rate in DTSContext (2.71 KB, patch)
2007-05-15 17:10 MSD, Sergey Vlasov
no flags Details | Diff
[PATCH 04] dtsdec: fix attempts to decode incomplete frames (1.50 KB, patch)
2007-05-17 13:56 MSD, Sergey Vlasov
no flags Details | Diff
[PATCH 05] dca: fix dca_bitalloc_index decoder init (976 bytes, patch)
2007-05-23 19:48 MSD, Sergey Vlasov
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey Vlasov 2007-05-14 20:20:41 MSD
В 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.
Comment 1 Sergey Vlasov 2007-05-14 20:28:31 MSD
Хотя что-то этим коммитом всё-таки на самом деле исправлялось - например,
преобразование dts в 6-канальный wav:

  ffmpeg -i file.avi -ac 6 file.wav

До отката этого коммита (но с внешним libdts) создавался нормальный wav; после
отката получается файл с сильно ускоренным звуком (эта же проблема была и в
версии svn7771); с другой стороны, с -ac 2 до отката получался замедленный звук,
а после отката - нормальный. Можно предположить, что в этом районе есть
несколько багов, компенсирующих друг друга.
Comment 2 Sergey Vlasov 2007-05-15 14:54:28 MSD
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.
Comment 3 Sergey Vlasov 2007-05-15 14:55:13 MSD
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.
Comment 4 Sergey Vlasov 2007-05-15 14:57:56 MSD
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;
		    }
Comment 5 Sergey Vlasov 2007-05-15 16:03:34 MSD
Да, после всех этих патчей в 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.
Comment 6 Sergey Vlasov 2007-05-15 17:10:27 MSD
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 не изменился.
Comment 7 Sergey Vlasov 2007-05-17 13:56:01 MSD
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.
Comment 8 Sergey Vlasov 2007-05-23 19:48:06 MSD
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).
Comment 9 Konstantin Pavlov 2007-07-13 12:49:57 MSD
так или иначе, исправлено.