[FFmpeg-devel] [PATCH] DCA-in-WAV detection
Kostya
kostya.shishkov
Fri May 4 08:40:01 CEST 2007
Here is my attempt on patch discussed on Febryary 2006
Thread called "[PATCH] Fix DTS in WAV file playback."
-------------- next part --------------
Index: libavformat/wav.c
===================================================================
--- libavformat/wav.c (revision 8883)
+++ libavformat/wav.c (working copy)
@@ -150,6 +150,58 @@
return 0;
}
+#define DCA_MARKER_RAW_BE 0x7FFE8001
+#define DCA_MARKER_RAW_LE 0xFE7F0180
+#define DCA_MARKER_14B_BE 0x1FFFE800
+#define DCA_MARKER_14B_LE 0xFF1F00E8
+
+#define DCA_PROBE_SIZE 16384
+
+/* Most WAV files with DTS audio are broken and use 0x01 (PCM) as format
+ ID instead of 0x2001 (DTS). If the format found is 0x01, check the first
+ bytes after 'data' for a valid DTS header. */
+static void find_dts_header (ByteIOContext *pb, AVCodecContext *codec)
+{
+ uint32_t state = -1, marker;
+ unsigned int i;
+ offset_t pos;
+ int found = 0;
+
+ pos = url_ftell(pb);
+ for (i = 0; i < DCA_PROBE_SIZE && !url_feof(pb) && !found; i += 2) {
+ state = (state << 16) | get_be16(pb);
+ /* raw stream markers */
+ if (state == DCA_MARKER_RAW_BE || state == DCA_MARKER_RAW_LE)
+ found = 1;
+ /* 14 bits and big endian bitstream */
+ if (state == DCA_MARKER_14B_BE) {
+ if ((get_be16(pb) & 0xFFF0) == 0x07F0)
+ found = 1;
+ else
+ url_fseek(pb, -2, SEEK_CUR);
+ }
+ /* 14 bits and big endian bitstream */
+ if (state == DCA_MARKER_14B_LE) {
+ if ((get_be16(pb) & 0xF0FF) == 0xF007)
+ found = 1;
+ else
+ url_fseek(pb, -2, SEEK_CUR);
+ }
+ }
+ /* if marker is found then test stream for more markers to appear */
+ if(found){
+ marker = state;
+ for (i = 0; i < DCA_PROBE_SIZE*3 && !url_feof(pb) && found < 4; i++) {
+ state = (state << 8) | get_byte(pb);
+ if(state == marker)
+ found++;
+ }
+ }
+ if(found == 4)
+ codec->codec_id = CODEC_ID_DTS;
+ url_fseek(pb, pos, SEEK_SET);
+}
+
/* wav input */
static int wav_read_header(AVFormatContext *s,
AVFormatParameters *ap)
@@ -186,6 +238,10 @@
size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
if (size < 0)
return -1;
+
+ /* check if it's really PCM or hidden DTS */
+ if (codec_get_id (codec_wav_tags, st->codec->codec_tag) == CODEC_ID_PCM_S16LE)
+ find_dts_header (pb, st->codec);
wav->data_end= url_ftell(pb) + size;
return 0;
}
More information about the ffmpeg-devel
mailing list