]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/nutdec.c
lavc: allow decoders to override frame parameters.
[ffmpeg] / libavformat / nutdec.c
index 004a2ea255b66ffeeeba14096bce7d0e8b06d1c1..cee411b60164785753c5d7abda28d071dedd0ead 100644 (file)
@@ -27,6 +27,7 @@
 #include "libavutil/tree.h"
 #include "avio_internal.h"
 #include "nut.h"
+#include "riff.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -76,8 +77,8 @@ static uint64_t get_fourcc(AVIOContext *bc)
 }
 
 #ifdef TRACE
-static inline uint64_t get_v_trace(AVIOContext *bc, char *file,
-                                   char *func, int line)
+static inline uint64_t get_v_trace(AVIOContext *bc, const char *file,
+                                   const char *func, int line)
 {
     uint64_t v = ffio_read_varlen(bc);
 
@@ -86,8 +87,8 @@ static inline uint64_t get_v_trace(AVIOContext *bc, char *file,
     return v;
 }
 
-static inline int64_t get_s_trace(AVIOContext *bc, char *file,
-                                  char *func, int line)
+static inline int64_t get_s_trace(AVIOContext *bc, const char *file,
+                                  const char *func, int line)
 {
     int64_t v = get_s(bc);
 
@@ -96,18 +97,8 @@ static inline int64_t get_s_trace(AVIOContext *bc, char *file,
     return v;
 }
 
-static inline uint64_t get_vb_trace(AVIOContext *bc, char *file,
-                                    char *func, int line)
-{
-    uint64_t v = get_vb(bc);
-
-    av_log(NULL, AV_LOG_DEBUG, "get_vb %5"PRId64" / %"PRIX64" in %s %s:%d\n",
-           v, v, file, func, line);
-    return v;
-}
 #define ffio_read_varlen(bc) get_v_trace(bc,  __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #define get_s(bc)            get_s_trace(bc,  __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_vb(bc)           get_vb_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #endif
 
 static int get_packetheader(NUTContext *nut, AVIOContext *bc,
@@ -187,13 +178,15 @@ static int nut_probe(AVProbeData *p)
     return 0;
 }
 
-#define GET_V(dst, check)                                                 \
-    tmp = ffio_read_varlen(bc);                                           \
-    if (!(check)) {                                                       \
-        av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp);  \
-        return -1;                                                        \
-    }                                                                     \
-    dst = tmp;
+#define GET_V(dst, check)                                                     \
+    do {                                                                      \
+        tmp = ffio_read_varlen(bc);                                           \
+        if (!(check)) {                                                       \
+            av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp);  \
+            return -1;                                                        \
+        }                                                                     \
+        dst = tmp;                                                            \
+    } while (0)
 
 static int skip_reserved(AVIOContext *bc, int64_t pos)
 {
@@ -220,8 +213,8 @@ static int decode_main_header(NUTContext *nut)
     end  = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
     end += avio_tell(bc);
 
-    GET_V(tmp, tmp >= 2 && tmp <= 3)
-    GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS)
+    GET_V(tmp, tmp >= 2 && tmp <= 3);
+    GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS);
 
     nut->max_distance = ffio_read_varlen(bc);
     if (nut->max_distance > 65536) {
@@ -229,12 +222,12 @@ static int decode_main_header(NUTContext *nut)
         nut->max_distance = 65536;
     }
 
-    GET_V(nut->time_base_count, tmp > 0 && tmp < INT_MAX / sizeof(AVRational))
+    GET_V(nut->time_base_count, tmp > 0 && tmp < INT_MAX / sizeof(AVRational));
     nut->time_base = av_malloc(nut->time_base_count * sizeof(AVRational));
 
     for (i = 0; i < nut->time_base_count; i++) {
-        GET_V(nut->time_base[i].num, tmp > 0 && tmp < (1ULL << 31))
-        GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31))
+        GET_V(nut->time_base[i].num, tmp > 0 && tmp < (1ULL << 31));
+        GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31));
         if (av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1) {
             av_log(s, AV_LOG_ERROR, "time base invalid\n");
             return AVERROR_INVALIDDATA;
@@ -302,17 +295,21 @@ static int decode_main_header(NUTContext *nut)
 
     if (end > avio_tell(bc) + 4) {
         int rem = 1024;
-        GET_V(nut->header_count, tmp < 128U)
+        GET_V(nut->header_count, tmp < 128U);
         nut->header_count++;
         for (i = 1; i < nut->header_count; i++) {
+            uint8_t *hdr;
             GET_V(nut->header_len[i], tmp > 0 && tmp < 256);
             rem -= nut->header_len[i];
             if (rem < 0) {
                 av_log(s, AV_LOG_ERROR, "invalid elision header\n");
                 return AVERROR_INVALIDDATA;
             }
-            nut->header[i] = av_malloc(nut->header_len[i]);
-            avio_read(bc, nut->header[i], nut->header_len[i]);
+            hdr = av_malloc(nut->header_len[i]);
+            if (!hdr)
+                return AVERROR(ENOMEM);
+            avio_read(bc, hdr, nut->header_len[i]);
+            nut->header[i] = hdr;
         }
         assert(nut->header_len[0] == 0);
     }
@@ -354,15 +351,20 @@ static int decode_stream_header(NUTContext *nut)
     case 0:
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
         st->codec->codec_id   = av_codec_get_id((const AVCodecTag * const []) {
-                                                    ff_codec_bmp_tags,
                                                     ff_nut_video_tags,
+                                                    ff_codec_bmp_tags,
                                                     0
                                                 },
                                                 tmp);
         break;
     case 1:
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-        st->codec->codec_id   = ff_codec_get_id(ff_codec_wav_tags, tmp);
+        st->codec->codec_id   = av_codec_get_id((const AVCodecTag * const []) {
+                                                    ff_nut_audio_tags,
+                                                    ff_codec_wav_tags,
+                                                    0
+                                                },
+                                                tmp);
         break;
     case 2:
         st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
@@ -370,12 +372,13 @@ static int decode_stream_header(NUTContext *nut)
         break;
     case 3:
         st->codec->codec_type = AVMEDIA_TYPE_DATA;
+        st->codec->codec_id   = ff_codec_get_id(ff_nut_data_tags, tmp);
         break;
     default:
         av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
         return -1;
     }
-    if (class < 3 && st->codec->codec_id == CODEC_ID_NONE)
+    if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE)
         av_log(s, AV_LOG_ERROR,
                "Unknown codec tag '0x%04x' for stream number %d\n",
                (unsigned int) tmp, stream_id);
@@ -395,8 +398,8 @@ static int decode_stream_header(NUTContext *nut)
     }
 
     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-        GET_V(st->codec->width,  tmp > 0)
-        GET_V(st->codec->height, tmp > 0)
+        GET_V(st->codec->width,  tmp > 0);
+        GET_V(st->codec->height, tmp > 0);
         st->sample_aspect_ratio.num = ffio_read_varlen(bc);
         st->sample_aspect_ratio.den = ffio_read_varlen(bc);
         if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
@@ -406,9 +409,9 @@ static int decode_stream_header(NUTContext *nut)
         }
         ffio_read_varlen(bc); /* csp type */
     } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-        GET_V(st->codec->sample_rate, tmp > 0)
+        GET_V(st->codec->sample_rate, tmp > 0);
         ffio_read_varlen(bc); // samplerate_den
-        GET_V(st->codec->channels, tmp > 0)
+        GET_V(st->codec->channels, tmp > 0);
     }
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
         av_log(s, AV_LOG_ERROR,
@@ -453,7 +456,7 @@ static int decode_info_header(NUTContext *nut)
     end  = get_packetheader(nut, bc, 1, INFO_STARTCODE);
     end += avio_tell(bc);
 
-    GET_V(stream_id_plus1, tmp <= s->nb_streams)
+    GET_V(stream_id_plus1, tmp <= s->nb_streams);
     chapter_id    = get_s(bc);
     chapter_start = ffio_read_varlen(bc);
     chapter_len   = ffio_read_varlen(bc);
@@ -571,7 +574,7 @@ static int find_and_decode_index(NUTContext *nut)
     end += avio_tell(bc);
 
     ffio_read_varlen(bc); // max_pts
-    GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0)
+    GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0);
     syncpoints   = av_malloc(sizeof(int64_t) *  syncpoint_count);
     has_keyframe = av_malloc(sizeof(int8_t)  * (syncpoint_count + 1));
     for (i = 0; i < syncpoint_count; i++) {
@@ -736,7 +739,7 @@ static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id,
     if (flags & FLAG_CODED)
         flags ^= ffio_read_varlen(bc);
     if (flags & FLAG_STREAM_ID) {
-        GET_V(*stream_id, tmp < s->nb_streams)
+        GET_V(*stream_id, tmp < s->nb_streams);
     }
     stc = &nut->stream[*stream_id];
     if (flags & FLAG_CODED_PTS) {
@@ -907,7 +910,7 @@ static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
     else if (stream_index == -2)
         return back_ptr;
 
-    assert(0);
+    return AV_NOPTS_VALUE;
 }
 
 static int read_seek(AVFormatContext *s, int stream_index,
@@ -987,7 +990,7 @@ static int nut_read_close(AVFormatContext *s)
 
 AVInputFormat ff_nut_demuxer = {
     .name           = "nut",
-    .long_name      = NULL_IF_CONFIG_SMALL("NUT format"),
+    .long_name      = NULL_IF_CONFIG_SMALL("NUT"),
     .priv_data_size = sizeof(NUTContext),
     .read_probe     = nut_probe,
     .read_header    = nut_read_header,
@@ -995,8 +998,5 @@ AVInputFormat ff_nut_demuxer = {
     .read_close     = nut_read_close,
     .read_seek      = read_seek,
     .extensions     = "nut",
-    .codec_tag      = (const AVCodecTag * const []) {
-        ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags,
-        ff_nut_subtitle_tags, 0
-    },
+    .codec_tag      = ff_nut_codec_tags,
 };