[PATCH] wav: detect dts-in-wav (issue70)

Anssi Hannula anssi.hannula
Tue Jul 27 07:56:41 CEST 2010


---
 libavformat/wav.c |   38 ++++++++++++++++++++++++++++++++++++--
 1 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/libavformat/wav.c b/libavformat/wav.c
index da08558..9bc8918 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -23,6 +23,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
+#include "libavcodec/dca.h"
 #include "raw.h"
 #include "riff.h"
 
@@ -220,6 +221,10 @@ static int wav_read_header(AVFormatContext *s,
     ff_get_wav_header(pb, st->codec, size);
     st->need_parsing = AVSTREAM_PARSE_FULL;
 
+    if (st->codec->codec_id == CODEC_ID_PCM_S16LE)
+        /* try to probe for DTS-in-WAV */
+        st->codec->codec_id = CODEC_ID_PROBE;
+
     av_set_pts_info(st, 64, 1, st->codec->sample_rate);
 
     size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
@@ -275,8 +280,11 @@ static int wav_read_packet(AVFormatContext *s,
             left = find_guid(s->pb, guid_data) - 24;
         else
             left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
-        if (left < 0)
+        if (left < 0) {
+            if (st->codec->codec_id == CODEC_ID_PROBE)
+                st->codec->codec_id = CODEC_ID_PCM_S16LE;
             return AVERROR_EOF;
+        }
         wav->data_end= url_ftell(s->pb) + left;
     }
 
@@ -288,10 +296,36 @@ static int wav_read_packet(AVFormatContext *s,
     }
     size = FFMIN(size, left);
     ret  = av_get_packet(s->pb, pkt, size);
-    if (ret < 0)
+    if (ret < 0) {
+        if (st->codec->codec_id == CODEC_ID_PROBE)
+            st->codec->codec_id = CODEC_ID_PCM_S16LE;
         return ret;
+    }
     pkt->stream_index = 0;
 
+    if (st->codec->codec_id == CODEC_ID_PROBE) {
+        /* a codec probe is running */
+        if (st->probe_packets == MAX_PROBE_PACKETS) {
+            /* first packet of a codec probe */
+            uint32_t state = 0;
+            uint8_t *buf = pkt->data;
+            while (buf < pkt->data + pkt->size) {
+                state = (state << 8) | *buf++;
+                if (state == DCA_MARKER_14B_LE || state == DCA_MARKER_14B_BE
+                    || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE)
+                    break;
+            }
+            if (buf == pkt->data + pkt->size)
+                /* no dca markers in the first packet, end probe */
+                st->codec->codec_id = CODEC_ID_PCM_S16LE;
+        } else if (st->probe_packets < MAX_PROBE_PACKETS - 20) {
+            /* no dca probed in 20 packets, end probe */
+            st->codec->codec_id = CODEC_ID_PCM_S16LE;
+            av_log(s, AV_LOG_DEBUG, "no codec detection in 20 packets, using"
+                                    " codec specified in wav header\n");
+        }
+    }
+
     return ret;
 }
 
-- 
1.7.1


--Boundary-00=_9jnTMYOr+3SdttW--



More information about the ffmpeg-devel mailing list