]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/nsvdec.c
Extract rotation in MOV metadata
[ffmpeg] / libavformat / nsvdec.c
index 1dc7cb0869f7615023c98e9d99cabaa6fd4dd80b..8d22520e80815504d5b1be6584e32b68fa60eaed 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include "avformat.h"
 #include "riff.h"
+#include "libavutil/dict.h"
 
 //#define DEBUG
 //#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
@@ -230,7 +231,7 @@ static int nsv_resync(AVFormatContext *s)
     //nsv->state = NSV_UNSYNC;
 
     for (i = 0; i < NSV_MAX_RESYNC; i++) {
-        if (pb->eof_reached) {
+        if (url_feof(pb)) {
             av_dlog(s, "NSV EOF\n");
             nsv->state = NSV_UNSYNC;
             return -1;
@@ -267,7 +268,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
 {
     NSVContext *nsv = s->priv_data;
     AVIOContext *pb = s->pb;
-    unsigned int file_size, size;
+    unsigned int av_unused file_size;
+    unsigned int size;
     int64_t duration;
     int strings_size;
     int table_entries;
@@ -296,7 +298,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
     table_entries_used = avio_rl32(pb);
     av_dlog(s, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n",
             strings_size, table_entries, table_entries_used);
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
 
     av_dlog(s, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));
@@ -327,11 +329,11 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
                 break;
             *p++ = '\0';
             av_dlog(s, "NSV NSVf INFO: %s='%s'\n", token, value);
-            av_metadata_set2(&s->metadata, token, value, 0);
+            av_dict_set(&s->metadata, token, value, 0);
         }
         av_free(strings);
     }
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
 
     av_dlog(s, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb));
@@ -378,7 +380,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
 
     avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
     nsv->state = NSV_HAS_READ_NSVF;
     return 0;
@@ -546,7 +548,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header)
     uint32_t vsize;
     uint16_t asize;
     uint16_t auxsize;
-    uint32_t auxtag;
+    uint32_t av_unused auxtag;
 
     av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header);
 
@@ -554,7 +556,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header)
         return 0; //-1; /* hey! eat what you've in your plate first! */
 
 null_chunk_retry:
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
 
     for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++)
@@ -584,11 +586,11 @@ null_chunk_retry:
               ((auxtag >> 16) & 0x0ff),
               ((auxtag >> 24) & 0x0ff),
               auxsize);
-        avio_seek(pb, auxsize, SEEK_CUR);
+        avio_skip(pb, auxsize);
         vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */
     }
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
     if (!vsize && !asize) {
         nsv->state = NSV_UNSYNC;
@@ -737,6 +739,9 @@ static int nsv_read_close(AVFormatContext *s)
 static int nsv_probe(AVProbeData *p)
 {
     int i;
+    int score;
+    int vsize, asize, auxcount;
+    score = 0;
     av_dlog(NULL, "nsv_probe(), buf_size %d\n", p->buf_size);
     /* check file header */
     /* streamed files might not have any header */
@@ -749,14 +754,25 @@ static int nsv_probe(AVProbeData *p)
     /* sometimes even the first header is at 9KB or something :^) */
     for (i = 1; i < p->buf_size - 3; i++) {
         if (p->buf[i+0] == 'N' && p->buf[i+1] == 'S' &&
-            p->buf[i+2] == 'V' && p->buf[i+3] == 's')
-            return AVPROBE_SCORE_MAX-20;
+            p->buf[i+2] == 'V' && p->buf[i+3] == 's') {
+            score = AVPROBE_SCORE_MAX/5;
+            /* Get the chunk size and check if at the end we are getting 0xBEEF */
+            auxcount = p->buf[i+19];
+            vsize = p->buf[i+20]  | p->buf[i+21] << 8;
+            asize = p->buf[i+22]  | p->buf[i+23] << 8;
+            vsize = (vsize << 4) | (auxcount >> 4);
+            if ((asize + vsize + i + 23) <  p->buf_size - 2) {
+                if (p->buf[i+23+asize+vsize+1] == 0xEF &&
+                    p->buf[i+23+asize+vsize+2] == 0xBE)
+                    return AVPROBE_SCORE_MAX-20;
+            }
+        }
     }
     /* so we'll have more luck on extension... */
     if (av_match_ext(p->filename, "nsv"))
         return AVPROBE_SCORE_MAX/2;
     /* FIXME: add mime-type check */
-    return 0;
+    return score;
 }
 
 AVInputFormat ff_nsv_demuxer = {