Summary: | DTS (DCA) decoding is broken | ||
---|---|---|---|
Product: | Sisyphus | Reporter: | Sergey Vlasov <vsu> |
Component: | ffmpeg | Assignee: | Anton Farygin <rider> |
Status: | CLOSED FIXED | QA Contact: | qa-sisyphus |
Severity: | normal | ||
Priority: | P2 | CC: | darktemplar, placeholder, rider |
Version: | unstable | ||
Hardware: | all | ||
OS: | Linux | ||
Attachments: |
Description
Sergey Vlasov
2007-05-14 20:20:41 MSD
Хотя что-то этим коммитом всё-таки на самом деле исправлялось - например, преобразование 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).
так или иначе, исправлено. |