]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavformat/dv.c
frsh: Export information about the last RTP contract and VRES
[frescor/ffmpeg.git] / libavformat / dv.c
index f7a01465ea5920823a968caac6cb33e32750bc1b..820c3b5cec8a38b24df09e1419dce8440a7de656 100644 (file)
@@ -6,7 +6,7 @@
  * of DV technical info.
  *
  * Raw DV format
- * Copyright (c) 2002 Fabrice Bellard.
+ * Copyright (c) 2002 Fabrice Bellard
  *
  * 50 Mbps (DVCPRO50) and 100 Mbps (DVCPRO HD) support
  * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
@@ -31,6 +31,7 @@
 #include <time.h>
 #include "avformat.h"
 #include "libavcodec/dvdata.h"
+#include "libavutil/intreadwrite.h"
 #include "dv.h"
 
 struct DVDemuxContext {
@@ -399,13 +400,24 @@ typedef struct RawDVContext {
 static int dv_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
 {
+    unsigned state;
     RawDVContext *c = s->priv_data;
 
     c->dv_demux = dv_init_demux(s);
     if (!c->dv_demux)
         return -1;
 
-    if (get_buffer(s->pb, c->buf, DV_PROFILE_BYTES) <= 0 ||
+    state = get_be32(s->pb);
+    while ((state & 0xffffff7f) != 0x1f07003f) {
+        if (url_feof(s->pb)) {
+            av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
+            return -1;
+        }
+        state = (state << 8) | get_byte(s->pb);
+    }
+    AV_WB32(c->buf, state);
+
+    if (get_buffer(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 ||
         url_fseek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
         return AVERROR(EIO);
 
@@ -430,6 +442,8 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
     size = dv_get_packet(c->dv_demux, pkt);
 
     if (size < 0) {
+        if (!c->dv_demux->sys)
+            return AVERROR(EIO);
         size = c->dv_demux->sys->frame_size;
         if (get_buffer(s->pb, c->buf, size) <= 0)
             return AVERROR(EIO);
@@ -460,12 +474,30 @@ static int dv_read_close(AVFormatContext *s)
     return 0;
 }
 
-#ifdef CONFIG_DV_DEMUXER
+static int dv_probe(AVProbeData *p)
+{
+    unsigned state;
+    int i;
+
+    if (p->buf_size < 5)
+        return 0;
+
+    state = AV_RB32(p->buf);
+    for (i = 4; i < p->buf_size; i++) {
+        if ((state & 0xffffff7f) == 0x1f07003f)
+            return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match
+        state = (state << 8) | p->buf[i];
+    }
+
+    return 0;
+}
+
+#if CONFIG_DV_DEMUXER
 AVInputFormat dv_demuxer = {
     "dv",
     NULL_IF_CONFIG_SMALL("DV video format"),
     sizeof(RawDVContext),
-    NULL,
+    dv_probe,
     dv_read_header,
     dv_read_packet,
     dv_read_close,