Statistics
| Branch: | Revision:

ffmpeg / libavformat / nutdec.c @ da9e6c42

History | View | Annotate | Download (29.2 KB)

1 619d8e2e Michael Niedermayer
/*
2
 * "NUT" Container Format demuxer
3
 * Copyright (c) 2004-2006 Michael Niedermayer
4
 * Copyright (c) 2003 Alex Beregszaszi
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23 00798e45 Aurelien Jacobs
#include <strings.h>
24 245976da Diego Biurrun
#include "libavutil/avstring.h"
25 6a5d31ac Diego Biurrun
#include "libavutil/bswap.h"
26 245976da Diego Biurrun
#include "libavutil/tree.h"
27 619d8e2e Michael Niedermayer
#include "nut.h"
28
29
#undef NDEBUG
30
#include <assert.h>
31
32
static int get_str(ByteIOContext *bc, char *string, unsigned int maxlen){
33 7798b42d Kostya Shishkov
    unsigned int len= ff_get_v(bc);
34 619d8e2e Michael Niedermayer
35
    if(len && maxlen)
36
        get_buffer(bc, string, FFMIN(len, maxlen));
37
    while(len > maxlen){
38
        get_byte(bc);
39
        len--;
40
    }
41
42
    if(maxlen)
43
        string[FFMIN(len, maxlen-1)]= 0;
44
45
    if(maxlen == len)
46
        return -1;
47
    else
48
        return 0;
49
}
50
51
static int64_t get_s(ByteIOContext *bc){
52 7798b42d Kostya Shishkov
    int64_t v = ff_get_v(bc) + 1;
53 619d8e2e Michael Niedermayer
54
    if (v&1) return -(v>>1);
55
    else     return  (v>>1);
56
}
57
58
static uint64_t get_fourcc(ByteIOContext *bc){
59 7798b42d Kostya Shishkov
    unsigned int len= ff_get_v(bc);
60 619d8e2e Michael Niedermayer
61
    if     (len==2) return get_le16(bc);
62
    else if(len==4) return get_le32(bc);
63
    else            return -1;
64
}
65
66
#ifdef TRACE
67
static inline uint64_t get_v_trace(ByteIOContext *bc, char *file, char *func, int line){
68 7798b42d Kostya Shishkov
    uint64_t v= ff_get_v(bc);
69 619d8e2e Michael Niedermayer
70 7a26da44 Michael Niedermayer
    av_log(NULL, AV_LOG_DEBUG, "get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
71 619d8e2e Michael Niedermayer
    return v;
72
}
73
74
static inline int64_t get_s_trace(ByteIOContext *bc, char *file, char *func, int line){
75
    int64_t v= get_s(bc);
76
77 7a26da44 Michael Niedermayer
    av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
78 619d8e2e Michael Niedermayer
    return v;
79
}
80
81
static inline uint64_t get_vb_trace(ByteIOContext *bc, char *file, char *func, int line){
82
    uint64_t v= get_vb(bc);
83
84 7a26da44 Michael Niedermayer
    av_log(NULL, AV_LOG_DEBUG, "get_vb %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
85 619d8e2e Michael Niedermayer
    return v;
86
}
87 7798b42d Kostya Shishkov
#define ff_get_v(bc)  get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
88 619d8e2e Michael Niedermayer
#define get_s(bc)  get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
89
#define get_vb(bc)  get_vb_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
90
#endif
91
92 073811cd Michael Niedermayer
static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int calculate_checksum, uint64_t startcode)
93 619d8e2e Michael Niedermayer
{
94 a47ec310 Diego Biurrun
    int64_t size;
95 619d8e2e Michael Niedermayer
//    start= url_ftell(bc) - 8;
96
97 073811cd Michael Niedermayer
    startcode= be2me_64(startcode);
98 992e78f5 Baptiste Coudurier
    startcode= ff_crc04C11DB7_update(0, &startcode, 8);
99 073811cd Michael Niedermayer
100 992e78f5 Baptiste Coudurier
    init_checksum(bc, ff_crc04C11DB7_update, startcode);
101 7798b42d Kostya Shishkov
    size= ff_get_v(bc);
102 bb0eb714 Luca Barbato
    if(size > 4096)
103 47772399 Michael Niedermayer
        get_be32(bc);
104
    if(get_checksum(bc) && size > 4096)
105
        return -1;
106 619d8e2e Michael Niedermayer
107 992e78f5 Baptiste Coudurier
    init_checksum(bc, calculate_checksum ? ff_crc04C11DB7_update : NULL, 0);
108 619d8e2e Michael Niedermayer
109
    return size;
110
}
111
112
static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){
113
    uint64_t state=0;
114
115
    if(pos >= 0)
116 bd107136 Diego Biurrun
        url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream is not seekable, but that should not matter, as in this case we simply start where we currently are
117 619d8e2e Michael Niedermayer
118
    while(!url_feof(bc)){
119
        state= (state<<8) | get_byte(bc);
120
        if((state>>56) != 'N')
121
            continue;
122
        switch(state){
123
        case MAIN_STARTCODE:
124
        case STREAM_STARTCODE:
125
        case SYNCPOINT_STARTCODE:
126
        case INFO_STARTCODE:
127
        case INDEX_STARTCODE:
128
            return state;
129
        }
130
    }
131
132
    return 0;
133
}
134
135
/**
136 93951943 Diego Biurrun
 * Find the given startcode.
137 619d8e2e Michael Niedermayer
 * @param code the startcode
138
 * @param pos the start position of the search, or -1 if the current position
139 32e543f8 Benoit Fouet
 * @return the position of the startcode or -1 if not found
140 619d8e2e Michael Niedermayer
 */
141
static int64_t find_startcode(ByteIOContext *bc, uint64_t code, int64_t pos){
142
    for(;;){
143
        uint64_t startcode= find_any_startcode(bc, pos);
144
        if(startcode == code)
145
            return url_ftell(bc) - 8;
146
        else if(startcode == 0)
147
            return -1;
148
        pos=-1;
149
    }
150
}
151
152
static int nut_probe(AVProbeData *p){
153
    int i;
154
    uint64_t code= 0;
155
156
    for (i = 0; i < p->buf_size; i++) {
157
        code = (code << 8) | p->buf[i];
158
        if (code == MAIN_STARTCODE)
159
            return AVPROBE_SCORE_MAX;
160
    }
161
    return 0;
162
}
163
164
#define GET_V(dst, check) \
165 7798b42d Kostya Shishkov
    tmp= ff_get_v(bc);\
166 619d8e2e Michael Niedermayer
    if(!(check)){\
167
        av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp);\
168
        return -1;\
169
    }\
170
    dst= tmp;
171
172
static int skip_reserved(ByteIOContext *bc, int64_t pos){
173
    pos -= url_ftell(bc);
174
    if(pos<0){
175
        url_fseek(bc, pos, SEEK_CUR);
176
        return -1;
177
    }else{
178
        while(pos--)
179
            get_byte(bc);
180
        return 0;
181
    }
182
}
183
184
static int decode_main_header(NUTContext *nut){
185
    AVFormatContext *s= nut->avf;
186 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
187 619d8e2e Michael Niedermayer
    uint64_t tmp, end;
188
    unsigned int stream_count;
189 3b4f69ae Michael Niedermayer
    int i, j, tmp_stream, tmp_mul, tmp_pts, tmp_size, count, tmp_res, tmp_head_idx;
190 6cb4b28f Michael Niedermayer
    int64_t tmp_match;
191 619d8e2e Michael Niedermayer
192 073811cd Michael Niedermayer
    end= get_packetheader(nut, bc, 1, MAIN_STARTCODE);
193 5d97d9d5 Michael Niedermayer
    end += url_ftell(bc);
194 619d8e2e Michael Niedermayer
195
    GET_V(tmp              , tmp >=2 && tmp <= 3)
196
    GET_V(stream_count     , tmp > 0 && tmp <=MAX_STREAMS)
197
198 7798b42d Kostya Shishkov
    nut->max_distance = ff_get_v(bc);
199 619d8e2e Michael Niedermayer
    if(nut->max_distance > 65536){
200
        av_log(s, AV_LOG_DEBUG, "max_distance %d\n", nut->max_distance);
201
        nut->max_distance= 65536;
202
    }
203
204
    GET_V(nut->time_base_count, tmp>0 && tmp<INT_MAX / sizeof(AVRational))
205
    nut->time_base= av_malloc(nut->time_base_count * sizeof(AVRational));
206
207
    for(i=0; i<nut->time_base_count; i++){
208
        GET_V(nut->time_base[i].num, tmp>0 && tmp<(1ULL<<31))
209
        GET_V(nut->time_base[i].den, tmp>0 && tmp<(1ULL<<31))
210 9ce6c138 Aurelien Jacobs
        if(av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1){
211 619d8e2e Michael Niedermayer
            av_log(s, AV_LOG_ERROR, "time base invalid\n");
212
            return -1;
213
        }
214
    }
215
    tmp_pts=0;
216
    tmp_mul=1;
217
    tmp_stream=0;
218 6cb4b28f Michael Niedermayer
    tmp_match= 1-(1LL<<62);
219 3b4f69ae Michael Niedermayer
    tmp_head_idx= 0;
220 619d8e2e Michael Niedermayer
    for(i=0; i<256;){
221 7798b42d Kostya Shishkov
        int tmp_flags = ff_get_v(bc);
222
        int tmp_fields= ff_get_v(bc);
223 619d8e2e Michael Niedermayer
        if(tmp_fields>0) tmp_pts   = get_s(bc);
224 7798b42d Kostya Shishkov
        if(tmp_fields>1) tmp_mul   = ff_get_v(bc);
225
        if(tmp_fields>2) tmp_stream= ff_get_v(bc);
226
        if(tmp_fields>3) tmp_size  = ff_get_v(bc);
227 619d8e2e Michael Niedermayer
        else             tmp_size  = 0;
228 7798b42d Kostya Shishkov
        if(tmp_fields>4) tmp_res   = ff_get_v(bc);
229 619d8e2e Michael Niedermayer
        else             tmp_res   = 0;
230 7798b42d Kostya Shishkov
        if(tmp_fields>5) count     = ff_get_v(bc);
231 619d8e2e Michael Niedermayer
        else             count     = tmp_mul - tmp_size;
232 6cb4b28f Michael Niedermayer
        if(tmp_fields>6) tmp_match = get_s(bc);
233 3b4f69ae Michael Niedermayer
        if(tmp_fields>7) tmp_head_idx= ff_get_v(bc);
234 619d8e2e Michael Niedermayer
235 3b4f69ae Michael Niedermayer
        while(tmp_fields-- > 8)
236 7798b42d Kostya Shishkov
           ff_get_v(bc);
237 619d8e2e Michael Niedermayer
238
        if(count == 0 || i+count > 256){
239
            av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i);
240
            return -1;
241
        }
242
        if(tmp_stream >= stream_count){
243
            av_log(s, AV_LOG_ERROR, "illegal stream number\n");
244
            return -1;
245
        }
246
247
        for(j=0; j<count; j++,i++){
248
            if (i == 'N') {
249
                nut->frame_code[i].flags= FLAG_INVALID;
250
                j--;
251
                continue;
252
            }
253
            nut->frame_code[i].flags           = tmp_flags ;
254
            nut->frame_code[i].pts_delta       = tmp_pts   ;
255
            nut->frame_code[i].stream_id       = tmp_stream;
256
            nut->frame_code[i].size_mul        = tmp_mul   ;
257
            nut->frame_code[i].size_lsb        = tmp_size+j;
258
            nut->frame_code[i].reserved_count  = tmp_res   ;
259 3b4f69ae Michael Niedermayer
            nut->frame_code[i].header_idx      = tmp_head_idx;
260 619d8e2e Michael Niedermayer
        }
261
    }
262
    assert(nut->frame_code['N'].flags == FLAG_INVALID);
263
264 3b4f69ae Michael Niedermayer
    if(end > url_ftell(bc) + 4){
265
        int rem= 1024;
266
        GET_V(nut->header_count, tmp<128U)
267
        nut->header_count++;
268
        for(i=1; i<nut->header_count; i++){
269
            GET_V(nut->header_len[i], tmp>0 && tmp<256);
270
            rem -= nut->header_len[i];
271
            if(rem < 0){
272
                av_log(s, AV_LOG_ERROR, "invalid elision header\n");
273
                return -1;
274
            }
275
            nut->header[i]= av_malloc(nut->header_len[i]);
276
            get_buffer(bc, nut->header[i], nut->header_len[i]);
277
        }
278
        assert(nut->header_len[0]==0);
279
    }
280
281 5d97d9d5 Michael Niedermayer
    if(skip_reserved(bc, end) || get_checksum(bc)){
282 93951943 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n");
283 619d8e2e Michael Niedermayer
        return -1;
284
    }
285
286
    nut->stream = av_mallocz(sizeof(StreamContext)*stream_count);
287
    for(i=0; i<stream_count; i++){
288
        av_new_stream(s, i);
289
    }
290
291
    return 0;
292
}
293
294
static int decode_stream_header(NUTContext *nut){
295
    AVFormatContext *s= nut->avf;
296 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
297 619d8e2e Michael Niedermayer
    StreamContext *stc;
298 c873bc17 Michael Niedermayer
    int class, stream_id;
299 619d8e2e Michael Niedermayer
    uint64_t tmp, end;
300
    AVStream *st;
301
302 073811cd Michael Niedermayer
    end= get_packetheader(nut, bc, 1, STREAM_STARTCODE);
303 5d97d9d5 Michael Niedermayer
    end += url_ftell(bc);
304 619d8e2e Michael Niedermayer
305 efd8f22a Michael Niedermayer
    GET_V(stream_id, tmp < s->nb_streams && !nut->stream[tmp].time_base);
306 619d8e2e Michael Niedermayer
    stc= &nut->stream[stream_id];
307
308
    st = s->streams[stream_id];
309
    if (!st)
310 769e10f0 Panagiotis Issaris
        return AVERROR(ENOMEM);
311 619d8e2e Michael Niedermayer
312 7798b42d Kostya Shishkov
    class = ff_get_v(bc);
313 619d8e2e Michael Niedermayer
    tmp = get_fourcc(bc);
314
    st->codec->codec_tag= tmp;
315
    switch(class)
316
    {
317
        case 0:
318 72415b2a Stefano Sabatini
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
319 49837b8d Stefano Sabatini
            st->codec->codec_id = av_codec_get_id(
320
                (const AVCodecTag * const []) { ff_codec_bmp_tags, ff_nut_video_tags, 0 },
321
                tmp);
322 619d8e2e Michael Niedermayer
            break;
323
        case 1:
324 72415b2a Stefano Sabatini
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
325 1a40491e Daniel Verkamp
            st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, tmp);
326 619d8e2e Michael Niedermayer
            break;
327
        case 2:
328 72415b2a Stefano Sabatini
            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
329 1a40491e Daniel Verkamp
            st->codec->codec_id = ff_codec_get_id(ff_nut_subtitle_tags, tmp);
330 a048febd Michael Niedermayer
            break;
331 619d8e2e Michael Niedermayer
        case 3:
332 72415b2a Stefano Sabatini
            st->codec->codec_type = AVMEDIA_TYPE_DATA;
333 619d8e2e Michael Niedermayer
            break;
334
        default:
335 93951943 Diego Biurrun
            av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
336 619d8e2e Michael Niedermayer
            return -1;
337
    }
338 9fdfd21c Michael Niedermayer
    if(class<3 && st->codec->codec_id == CODEC_ID_NONE)
339 8e89cd1f Stefano Sabatini
        av_log(s, AV_LOG_ERROR, "Unknown codec tag '0x%04x' for stream number %d\n",
340
               (unsigned int)tmp, stream_id);
341 9fdfd21c Michael Niedermayer
342 619d8e2e Michael Niedermayer
    GET_V(stc->time_base_id    , tmp < nut->time_base_count);
343
    GET_V(stc->msb_pts_shift   , tmp < 16);
344 7798b42d Kostya Shishkov
    stc->max_pts_distance= ff_get_v(bc);
345 93951943 Diego Biurrun
    GET_V(stc->decode_delay    , tmp < 1000); //sanity limit, raise this if Moore's law is true
346 619d8e2e Michael Niedermayer
    st->codec->has_b_frames= stc->decode_delay;
347 7798b42d Kostya Shishkov
    ff_get_v(bc); //stream flags
348 619d8e2e Michael Niedermayer
349
    GET_V(st->codec->extradata_size, tmp < (1<<30));
350
    if(st->codec->extradata_size){
351
        st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
352
        get_buffer(bc, st->codec->extradata, st->codec->extradata_size);
353
    }
354
355 72415b2a Stefano Sabatini
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
356 619d8e2e Michael Niedermayer
        GET_V(st->codec->width , tmp > 0)
357
        GET_V(st->codec->height, tmp > 0)
358 59729451 Aurelien Jacobs
        st->sample_aspect_ratio.num= ff_get_v(bc);
359
        st->sample_aspect_ratio.den= ff_get_v(bc);
360
        if((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)){
361
            av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n", st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
362 619d8e2e Michael Niedermayer
            return -1;
363
        }
364 7798b42d Kostya Shishkov
        ff_get_v(bc); /* csp type */
365 72415b2a Stefano Sabatini
    }else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
366 619d8e2e Michael Niedermayer
        GET_V(st->codec->sample_rate , tmp > 0)
367 eae213af Oded Shimon
        ff_get_v(bc); // samplerate_den
368 619d8e2e Michael Niedermayer
        GET_V(st->codec->channels, tmp > 0)
369
    }
370 5d97d9d5 Michael Niedermayer
    if(skip_reserved(bc, end) || get_checksum(bc)){
371 93951943 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "stream header %d checksum mismatch\n", stream_id);
372 619d8e2e Michael Niedermayer
        return -1;
373
    }
374 efd8f22a Michael Niedermayer
    stc->time_base= &nut->time_base[stc->time_base_id];
375
    av_set_pts_info(s->streams[stream_id], 63, stc->time_base->num, stc->time_base->den);
376 619d8e2e Michael Niedermayer
    return 0;
377
}
378
379 90c2295b Evgeniy Stepanov
static void set_disposition_bits(AVFormatContext* avf, char* value, int stream_id){
380
    int flag = 0, i;
381
    for (i=0; ff_nut_dispositions[i].flag; ++i) {
382
        if (!strcmp(ff_nut_dispositions[i].str, value))
383
            flag = ff_nut_dispositions[i].flag;
384
    }
385
    if (!flag)
386
        av_log(avf, AV_LOG_INFO, "unknown disposition type '%s'\n", value);
387
    for (i = 0; i < avf->nb_streams; ++i)
388
        if (stream_id == i || stream_id == -1)
389
            avf->streams[i]->disposition |= flag;
390
}
391
392 619d8e2e Michael Niedermayer
static int decode_info_header(NUTContext *nut){
393
    AVFormatContext *s= nut->avf;
394 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
395 e1c0b00b Anton Khirnov
    uint64_t tmp, chapter_start, chapter_len;
396
    unsigned int stream_id_plus1, count;
397 619d8e2e Michael Niedermayer
    int chapter_id, i;
398
    int64_t value, end;
399 7ebab679 Michael Niedermayer
    char name[256], str_value[1024], type_str[256];
400 0fca8bc8 Michael Niedermayer
    const char *type;
401 883fe4d5 Michael Niedermayer
    AVChapter *chapter= NULL;
402 00798e45 Aurelien Jacobs
    AVStream *st= NULL;
403 619d8e2e Michael Niedermayer
404 073811cd Michael Niedermayer
    end= get_packetheader(nut, bc, 1, INFO_STARTCODE);
405 5d97d9d5 Michael Niedermayer
    end += url_ftell(bc);
406 619d8e2e Michael Niedermayer
407
    GET_V(stream_id_plus1, tmp <= s->nb_streams)
408
    chapter_id   = get_s(bc);
409 7798b42d Kostya Shishkov
    chapter_start= ff_get_v(bc);
410
    chapter_len  = ff_get_v(bc);
411
    count        = ff_get_v(bc);
412 883fe4d5 Michael Niedermayer
413
    if(chapter_id && !stream_id_plus1){
414
        int64_t start= chapter_start / nut->time_base_count;
415 abd2256d Michael Niedermayer
        chapter= ff_new_chapter(s, chapter_id,
416
                                nut->time_base[chapter_start % nut->time_base_count],
417
                                start, start + chapter_len, NULL);
418 00798e45 Aurelien Jacobs
    } else if(stream_id_plus1)
419
        st= s->streams[stream_id_plus1 - 1];
420 883fe4d5 Michael Niedermayer
421 619d8e2e Michael Niedermayer
    for(i=0; i<count; i++){
422
        get_str(bc, name, sizeof(name));
423
        value= get_s(bc);
424
        if(value == -1){
425
            type= "UTF-8";
426
            get_str(bc, str_value, sizeof(str_value));
427
        }else if(value == -2){
428 0fca8bc8 Michael Niedermayer
            get_str(bc, type_str, sizeof(type_str));
429
            type= type_str;
430 619d8e2e Michael Niedermayer
            get_str(bc, str_value, sizeof(str_value));
431
        }else if(value == -3){
432
            type= "s";
433
            value= get_s(bc);
434
        }else if(value == -4){
435
            type= "t";
436 7798b42d Kostya Shishkov
            value= ff_get_v(bc);
437 619d8e2e Michael Niedermayer
        }else if(value < -4){
438
            type= "r";
439
            get_s(bc);
440
        }else{
441
            type= "v";
442
        }
443
444 d6f142a1 Diego Pettenò
        if (stream_id_plus1 > s->nb_streams) {
445 90c2295b Evgeniy Stepanov
            av_log(s, AV_LOG_ERROR, "invalid stream id for info packet\n");
446
            continue;
447
        }
448
449 00798e45 Aurelien Jacobs
        if(!strcmp(type, "UTF-8")){
450
            AVMetadata **metadata = NULL;
451
            if(chapter_id==0 && !strcmp(name, "Disposition"))
452 90c2295b Evgeniy Stepanov
                set_disposition_bits(s, str_value, stream_id_plus1 - 1);
453 00798e45 Aurelien Jacobs
            else if(chapter)          metadata= &chapter->metadata;
454
            else if(stream_id_plus1)  metadata= &st->metadata;
455
            else                      metadata= &s->metadata;
456
            if(metadata && strcasecmp(name,"Uses")
457
               && strcasecmp(name,"Depends") && strcasecmp(name,"Replaces"))
458 2ef6c124 Stefano Sabatini
                av_metadata_set2(metadata, name, str_value, 0);
459 883fe4d5 Michael Niedermayer
        }
460 619d8e2e Michael Niedermayer
    }
461
462 5d97d9d5 Michael Niedermayer
    if(skip_reserved(bc, end) || get_checksum(bc)){
463 93951943 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n");
464 619d8e2e Michael Niedermayer
        return -1;
465
    }
466
    return 0;
467
}
468
469 4d5be986 Michael Niedermayer
static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr){
470 619d8e2e Michael Niedermayer
    AVFormatContext *s= nut->avf;
471 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
472 4d5be986 Michael Niedermayer
    int64_t end, tmp;
473 619d8e2e Michael Niedermayer
474 faf7cbf1 Michael Niedermayer
    nut->last_syncpoint_pos= url_ftell(bc)-8;
475 619d8e2e Michael Niedermayer
476 073811cd Michael Niedermayer
    end= get_packetheader(nut, bc, 1, SYNCPOINT_STARTCODE);
477 5d97d9d5 Michael Niedermayer
    end += url_ftell(bc);
478 619d8e2e Michael Niedermayer
479 7798b42d Kostya Shishkov
    tmp= ff_get_v(bc);
480
    *back_ptr= nut->last_syncpoint_pos - 16*ff_get_v(bc);
481 4d5be986 Michael Niedermayer
    if(*back_ptr < 0)
482
        return -1;
483 619d8e2e Michael Niedermayer
484 103d74ea Oded Shimon
    ff_nut_reset_ts(nut, nut->time_base[tmp % nut->time_base_count], tmp / nut->time_base_count);
485 619d8e2e Michael Niedermayer
486 5d97d9d5 Michael Niedermayer
    if(skip_reserved(bc, end) || get_checksum(bc)){
487 faf7cbf1 Michael Niedermayer
        av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n");
488 619d8e2e Michael Niedermayer
        return -1;
489
    }
490 4d5be986 Michael Niedermayer
491
    *ts= tmp / s->nb_streams * av_q2d(nut->time_base[tmp % s->nb_streams])*AV_TIME_BASE;
492 4a3b5fe1 Michael Niedermayer
    ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts);
493 4d5be986 Michael Niedermayer
494 619d8e2e Michael Niedermayer
    return 0;
495
}
496
497 e8272029 Michael Niedermayer
static int find_and_decode_index(NUTContext *nut){
498
    AVFormatContext *s= nut->avf;
499 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
500 e8272029 Michael Niedermayer
    uint64_t tmp, end;
501
    int i, j, syncpoint_count;
502
    int64_t filesize= url_fsize(bc);
503
    int64_t *syncpoints;
504
    int8_t *has_keyframe;
505 c2a3dcaf Michael Niedermayer
    int ret= -1;
506 e8272029 Michael Niedermayer
507
    url_fseek(bc, filesize-12, SEEK_SET);
508
    url_fseek(bc, filesize-get_be64(bc), SEEK_SET);
509
    if(get_be64(bc) != INDEX_STARTCODE){
510
        av_log(s, AV_LOG_ERROR, "no index at the end\n");
511
        return -1;
512
    }
513
514 073811cd Michael Niedermayer
    end= get_packetheader(nut, bc, 1, INDEX_STARTCODE);
515 5d97d9d5 Michael Niedermayer
    end += url_ftell(bc);
516 e8272029 Michael Niedermayer
517 7798b42d Kostya Shishkov
    ff_get_v(bc); //max_pts
518 e8272029 Michael Niedermayer
    GET_V(syncpoint_count, tmp < INT_MAX/8 && tmp > 0)
519
    syncpoints= av_malloc(sizeof(int64_t)*syncpoint_count);
520
    has_keyframe= av_malloc(sizeof(int8_t)*(syncpoint_count+1));
521
    for(i=0; i<syncpoint_count; i++){
522 c2a3dcaf Michael Niedermayer
        syncpoints[i] = ff_get_v(bc);
523
        if(syncpoints[i] <= 0)
524
            goto fail;
525 e8272029 Michael Niedermayer
        if(i)
526
            syncpoints[i] += syncpoints[i-1];
527
    }
528
529
    for(i=0; i<s->nb_streams; i++){
530
        int64_t last_pts= -1;
531
        for(j=0; j<syncpoint_count;){
532 7798b42d Kostya Shishkov
            uint64_t x= ff_get_v(bc);
533 e8272029 Michael Niedermayer
            int type= x&1;
534
            int n= j;
535
            x>>=1;
536
            if(type){
537
                int flag= x&1;
538
                x>>=1;
539
                if(n+x >= syncpoint_count + 1){
540
                    av_log(s, AV_LOG_ERROR, "index overflow A\n");
541 c2a3dcaf Michael Niedermayer
                    goto fail;
542 e8272029 Michael Niedermayer
                }
543
                while(x--)
544
                    has_keyframe[n++]= flag;
545
                has_keyframe[n++]= !flag;
546
            }else{
547
                while(x != 1){
548
                    if(n>=syncpoint_count + 1){
549
                        av_log(s, AV_LOG_ERROR, "index overflow B\n");
550 c2a3dcaf Michael Niedermayer
                        goto fail;
551 e8272029 Michael Niedermayer
                    }
552
                    has_keyframe[n++]= x&1;
553
                    x>>=1;
554
                }
555
            }
556
            if(has_keyframe[0]){
557
                av_log(s, AV_LOG_ERROR, "keyframe before first syncpoint in index\n");
558 c2a3dcaf Michael Niedermayer
                goto fail;
559 e8272029 Michael Niedermayer
            }
560
            assert(n<=syncpoint_count+1);
561 b19e3983 Oded Shimon
            for(; j<n && j<syncpoint_count; j++){
562 e8272029 Michael Niedermayer
                if(has_keyframe[j]){
563 7798b42d Kostya Shishkov
                    uint64_t B, A= ff_get_v(bc);
564 e8272029 Michael Niedermayer
                    if(!A){
565 7798b42d Kostya Shishkov
                        A= ff_get_v(bc);
566
                        B= ff_get_v(bc);
567 e8272029 Michael Niedermayer
                        //eor_pts[j][i] = last_pts + A + B
568
                    }else
569
                        B= 0;
570
                    av_add_index_entry(
571
                        s->streams[i],
572
                        16*syncpoints[j-1],
573
                        last_pts + A,
574
                        0,
575
                        0,
576
                        AVINDEX_KEYFRAME);
577
                    last_pts += A + B;
578
                }
579
            }
580
        }
581
    }
582
583 5d97d9d5 Michael Niedermayer
    if(skip_reserved(bc, end) || get_checksum(bc)){
584 93951943 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "index checksum mismatch\n");
585 c2a3dcaf Michael Niedermayer
        goto fail;
586 e8272029 Michael Niedermayer
    }
587 c2a3dcaf Michael Niedermayer
    ret= 0;
588
fail:
589
    av_free(syncpoints);
590
    av_free(has_keyframe);
591
    return ret;
592 e8272029 Michael Niedermayer
}
593
594 619d8e2e Michael Niedermayer
static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
595
{
596
    NUTContext *nut = s->priv_data;
597 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
598 619d8e2e Michael Niedermayer
    int64_t pos;
599 5e534865 Diego Biurrun
    int initialized_stream_count;
600 619d8e2e Michael Niedermayer
601
    nut->avf= s;
602
603
    /* main header */
604
    pos=0;
605 7b0d75fc Michael Niedermayer
    do{
606 619d8e2e Michael Niedermayer
        pos= find_startcode(bc, MAIN_STARTCODE, pos)+1;
607
        if (pos<0+1){
608 93951943 Diego Biurrun
            av_log(s, AV_LOG_ERROR, "No main startcode found.\n");
609 619d8e2e Michael Niedermayer
            return -1;
610
        }
611 7b0d75fc Michael Niedermayer
    }while(decode_main_header(nut) < 0);
612 619d8e2e Michael Niedermayer
613
    /* stream headers */
614
    pos=0;
615 5e534865 Diego Biurrun
    for(initialized_stream_count=0; initialized_stream_count < s->nb_streams;){
616 619d8e2e Michael Niedermayer
        pos= find_startcode(bc, STREAM_STARTCODE, pos)+1;
617
        if (pos<0+1){
618 93951943 Diego Biurrun
            av_log(s, AV_LOG_ERROR, "Not all stream headers found.\n");
619 619d8e2e Michael Niedermayer
            return -1;
620
        }
621
        if(decode_stream_header(nut) >= 0)
622 5e534865 Diego Biurrun
            initialized_stream_count++;
623 619d8e2e Michael Niedermayer
    }
624
625
    /* info headers */
626
    pos=0;
627
    for(;;){
628
        uint64_t startcode= find_any_startcode(bc, pos);
629
        pos= url_ftell(bc);
630
631
        if(startcode==0){
632
            av_log(s, AV_LOG_ERROR, "EOF before video frames\n");
633
            return -1;
634
        }else if(startcode == SYNCPOINT_STARTCODE){
635
            nut->next_startcode= startcode;
636
            break;
637
        }else if(startcode != INFO_STARTCODE){
638
            continue;
639
        }
640
641
        decode_info_header(nut);
642
    }
643
644 faf7cbf1 Michael Niedermayer
    s->data_offset= pos-8;
645
646 071790c8 Michael Niedermayer
    if(!url_is_streamed(bc)){
647 e8272029 Michael Niedermayer
        int64_t orig_pos= url_ftell(bc);
648
        find_and_decode_index(nut);
649
        url_fseek(bc, orig_pos, SEEK_SET);
650
    }
651
    assert(nut->next_startcode == SYNCPOINT_STARTCODE);
652
653 619d8e2e Michael Niedermayer
    return 0;
654
}
655
656 3b4f69ae Michael Niedermayer
static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, uint8_t *header_idx, int frame_code){
657 619d8e2e Michael Niedermayer
    AVFormatContext *s= nut->avf;
658 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
659 619d8e2e Michael Niedermayer
    StreamContext *stc;
660
    int size, flags, size_mul, pts_delta, i, reserved_count;
661
    uint64_t tmp;
662
663
    if(url_ftell(bc) > nut->last_syncpoint_pos + nut->max_distance){
664 93951943 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "Last frame must have been damaged %"PRId64" > %"PRId64" + %d\n", url_ftell(bc), nut->last_syncpoint_pos, nut->max_distance);
665 619d8e2e Michael Niedermayer
        return -1;
666
    }
667
668
    flags          = nut->frame_code[frame_code].flags;
669
    size_mul       = nut->frame_code[frame_code].size_mul;
670
    size           = nut->frame_code[frame_code].size_lsb;
671
    *stream_id     = nut->frame_code[frame_code].stream_id;
672
    pts_delta      = nut->frame_code[frame_code].pts_delta;
673
    reserved_count = nut->frame_code[frame_code].reserved_count;
674 3b4f69ae Michael Niedermayer
    *header_idx    = nut->frame_code[frame_code].header_idx;
675 619d8e2e Michael Niedermayer
676
    if(flags & FLAG_INVALID)
677
        return -1;
678
    if(flags & FLAG_CODED)
679 7798b42d Kostya Shishkov
        flags ^= ff_get_v(bc);
680 619d8e2e Michael Niedermayer
    if(flags & FLAG_STREAM_ID){
681
        GET_V(*stream_id, tmp < s->nb_streams)
682
    }
683
    stc= &nut->stream[*stream_id];
684
    if(flags&FLAG_CODED_PTS){
685 7798b42d Kostya Shishkov
        int coded_pts= ff_get_v(bc);
686 619d8e2e Michael Niedermayer
//FIXME check last_pts validity?
687
        if(coded_pts < (1<<stc->msb_pts_shift)){
688 f13ea4e0 Michael Niedermayer
            *pts=ff_lsb2full(stc, coded_pts);
689 619d8e2e Michael Niedermayer
        }else
690
            *pts=coded_pts - (1<<stc->msb_pts_shift);
691
    }else
692
        *pts= stc->last_pts + pts_delta;
693
    if(flags&FLAG_SIZE_MSB){
694 7798b42d Kostya Shishkov
        size += size_mul*ff_get_v(bc);
695 619d8e2e Michael Niedermayer
    }
696 7eeebcc5 Michael Niedermayer
    if(flags&FLAG_MATCH_TIME)
697
        get_s(bc);
698 3b4f69ae Michael Niedermayer
    if(flags&FLAG_HEADER_IDX)
699
        *header_idx= ff_get_v(bc);
700 619d8e2e Michael Niedermayer
    if(flags&FLAG_RESERVED)
701 7798b42d Kostya Shishkov
        reserved_count= ff_get_v(bc);
702 619d8e2e Michael Niedermayer
    for(i=0; i<reserved_count; i++)
703 7798b42d Kostya Shishkov
        ff_get_v(bc);
704 3b4f69ae Michael Niedermayer
705
    if(*header_idx >= (unsigned)nut->header_count){
706
        av_log(s, AV_LOG_ERROR, "header_idx invalid\n");
707
        return -1;
708
    }
709
    if(size > 4096)
710
        *header_idx=0;
711
    size -= nut->header_len[*header_idx];
712
713 619d8e2e Michael Niedermayer
    if(flags&FLAG_CHECKSUM){
714
        get_be32(bc); //FIXME check this
715 06599638 Michael Niedermayer
    }else if(size > 2*nut->max_distance || FFABS(stc->last_pts - *pts) > stc->max_pts_distance){
716 2dbe0bd4 Michael Niedermayer
        av_log(s, AV_LOG_ERROR, "frame size > 2max_distance and no checksum\n");
717
        return -1;
718 619d8e2e Michael Niedermayer
    }
719
720
    stc->last_pts= *pts;
721 06599638 Michael Niedermayer
    stc->last_flags= flags;
722 619d8e2e Michael Niedermayer
723
    return size;
724
}
725
726
static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code){
727
    AVFormatContext *s= nut->avf;
728 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
729 06599638 Michael Niedermayer
    int size, stream_id, discard;
730 619d8e2e Michael Niedermayer
    int64_t pts, last_IP_pts;
731 06599638 Michael Niedermayer
    StreamContext *stc;
732 3b4f69ae Michael Niedermayer
    uint8_t header_idx;
733 619d8e2e Michael Niedermayer
734 3b4f69ae Michael Niedermayer
    size= decode_frame_header(nut, &pts, &stream_id, &header_idx, frame_code);
735 619d8e2e Michael Niedermayer
    if(size < 0)
736
        return -1;
737
738 06599638 Michael Niedermayer
    stc= &nut->stream[stream_id];
739
740
    if (stc->last_flags & FLAG_KEY)
741
        stc->skip_until_key_frame=0;
742 0a3b575b Michael Niedermayer
743 619d8e2e Michael Niedermayer
    discard= s->streams[ stream_id ]->discard;
744
    last_IP_pts= s->streams[ stream_id ]->last_IP_pts;
745 06599638 Michael Niedermayer
    if(  (discard >= AVDISCARD_NONKEY && !(stc->last_flags & FLAG_KEY))
746 619d8e2e Michael Niedermayer
       ||(discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE && last_IP_pts > pts)
747 0a3b575b Michael Niedermayer
       || discard >= AVDISCARD_ALL
748 06599638 Michael Niedermayer
       || stc->skip_until_key_frame){
749 619d8e2e Michael Niedermayer
        url_fskip(bc, size);
750
        return 1;
751
    }
752
753 3b4f69ae Michael Niedermayer
    av_new_packet(pkt, size + nut->header_len[header_idx]);
754
    memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]);
755
    pkt->pos= url_ftell(bc); //FIXME
756
    get_buffer(bc, pkt->data + nut->header_len[header_idx], size);
757
758 619d8e2e Michael Niedermayer
    pkt->stream_index = stream_id;
759 06599638 Michael Niedermayer
    if (stc->last_flags & FLAG_KEY)
760 cc947f04 Jean-Daniel Dupas
        pkt->flags |= AV_PKT_FLAG_KEY;
761 619d8e2e Michael Niedermayer
    pkt->pts = pts;
762
763
    return 0;
764
}
765
766
static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
767
{
768
    NUTContext *nut = s->priv_data;
769 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
770 619d8e2e Michael Niedermayer
    int i, frame_code=0, ret, skip;
771 4d5be986 Michael Niedermayer
    int64_t ts, back_ptr;
772 619d8e2e Michael Niedermayer
773
    for(;;){
774
        int64_t pos= url_ftell(bc);
775
        uint64_t tmp= nut->next_startcode;
776
        nut->next_startcode=0;
777
778
        if(tmp){
779
            pos-=8;
780
        }else{
781
            frame_code = get_byte(bc);
782 559fd1e7 Clemens Ladisch
            if(url_feof(bc))
783
                return -1;
784 619d8e2e Michael Niedermayer
            if(frame_code == 'N'){
785
                tmp= frame_code;
786
                for(i=1; i<8; i++)
787
                    tmp = (tmp<<8) + get_byte(bc);
788
            }
789
        }
790
        switch(tmp){
791
        case MAIN_STARTCODE:
792
        case STREAM_STARTCODE:
793
        case INDEX_STARTCODE:
794 073811cd Michael Niedermayer
            skip= get_packetheader(nut, bc, 0, tmp);
795 619d8e2e Michael Niedermayer
            url_fseek(bc, skip, SEEK_CUR);
796
            break;
797
        case INFO_STARTCODE:
798
            if(decode_info_header(nut)<0)
799
                goto resync;
800
            break;
801
        case SYNCPOINT_STARTCODE:
802 4d5be986 Michael Niedermayer
            if(decode_syncpoint(nut, &ts, &back_ptr)<0)
803 619d8e2e Michael Niedermayer
                goto resync;
804
            frame_code = get_byte(bc);
805
        case 0:
806
            ret= decode_frame(nut, pkt, frame_code);
807
            if(ret==0)
808
                return 0;
809
            else if(ret==1) //ok but discard packet
810
                break;
811
        default:
812
resync:
813
av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", pos);
814 8ba3e5d8 Michael Niedermayer
            tmp= find_any_startcode(bc, nut->last_syncpoint_pos+1);
815 619d8e2e Michael Niedermayer
            if(tmp==0)
816
                return -1;
817
av_log(s, AV_LOG_DEBUG, "sync\n");
818
            nut->next_startcode= tmp;
819
        }
820
    }
821
}
822
823 faf7cbf1 Michael Niedermayer
static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){
824
    NUTContext *nut = s->priv_data;
825 899681cd Björn Axelsson
    ByteIOContext *bc = s->pb;
826 4d5be986 Michael Niedermayer
    int64_t pos, pts, back_ptr;
827 faf7cbf1 Michael Niedermayer
av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%"PRId64",%"PRId64")\n", stream_index, *pos_arg, pos_limit);
828
829
    pos= *pos_arg;
830
    do{
831
        pos= find_startcode(bc, SYNCPOINT_STARTCODE, pos)+1;
832
        if(pos < 1){
833
            assert(nut->next_startcode == 0);
834 93951943 Diego Biurrun
            av_log(s, AV_LOG_ERROR, "read_timestamp failed.\n");
835 faf7cbf1 Michael Niedermayer
            return AV_NOPTS_VALUE;
836
        }
837 4d5be986 Michael Niedermayer
    }while(decode_syncpoint(nut, &pts, &back_ptr) < 0);
838 faf7cbf1 Michael Niedermayer
    *pos_arg = pos-1;
839
    assert(nut->last_syncpoint_pos == *pos_arg);
840
841 706da4af Måns Rullgård
    av_log(s, AV_LOG_DEBUG, "return %"PRId64" %"PRId64"\n", pts,back_ptr );
842 4d5be986 Michael Niedermayer
    if     (stream_index == -1) return pts;
843
    else if(stream_index == -2) return back_ptr;
844
845
assert(0);
846 faf7cbf1 Michael Niedermayer
}
847
848 4d5be986 Michael Niedermayer
static int read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags){
849
    NUTContext *nut = s->priv_data;
850
    AVStream *st= s->streams[stream_index];
851 52afa376 Michael Niedermayer
    Syncpoint dummy={.ts= pts*av_q2d(st->time_base)*AV_TIME_BASE};
852
    Syncpoint nopts_sp= {.ts= AV_NOPTS_VALUE, .back_ptr= AV_NOPTS_VALUE};
853
    Syncpoint *sp, *next_node[2]= {&nopts_sp, &nopts_sp};
854 4d5be986 Michael Niedermayer
    int64_t pos, pos2, ts;
855 0a3b575b Michael Niedermayer
    int i;
856 4d5be986 Michael Niedermayer
857 071790c8 Michael Niedermayer
    if(st->index_entries){
858
        int index= av_index_search_timestamp(st, pts, flags);
859
        if(index<0)
860
            return -1;
861
862
        pos2= st->index_entries[index].pos;
863
        ts  = st->index_entries[index].timestamp;
864
    }else{
865 f990f6e3 Vitor Sessak
        av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pts_cmp,
866
                     (void **) next_node);
867 706da4af Måns Rullgård
        av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n", next_node[0]->pos, next_node[1]->pos,
868 f32554fa Michael Niedermayer
                                                    next_node[0]->ts , next_node[1]->ts);
869
        pos= av_gen_search(s, -1, dummy.ts, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos,
870
                                            next_node[0]->ts , next_node[1]->ts, AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp);
871
872
        if(!(flags & AVSEEK_FLAG_BACKWARD)){
873
            dummy.pos= pos+16;
874
            next_node[1]= &nopts_sp;
875 f990f6e3 Vitor Sessak
            av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
876
                         (void **) next_node);
877 f32554fa Michael Niedermayer
            pos2= av_gen_search(s, -2, dummy.pos, next_node[0]->pos     , next_node[1]->pos, next_node[1]->pos,
878
                                                next_node[0]->back_ptr, next_node[1]->back_ptr, flags, &ts, nut_read_timestamp);
879
            if(pos2>=0)
880
                pos= pos2;
881 2cab6401 Diego Biurrun
            //FIXME dir but I think it does not matter
882 f32554fa Michael Niedermayer
        }
883
        dummy.pos= pos;
884 f990f6e3 Vitor Sessak
        sp= av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
885
                         NULL);
886 f32554fa Michael Niedermayer
887
        assert(sp);
888
        pos2= sp->back_ptr  - 15;
889 071790c8 Michael Niedermayer
    }
890
    av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos2);
891 899681cd Björn Axelsson
    pos= find_startcode(s->pb, SYNCPOINT_STARTCODE, pos2);
892
    url_fseek(s->pb, pos, SEEK_SET);
893 4d5be986 Michael Niedermayer
    av_log(NULL, AV_LOG_DEBUG, "SP: %"PRId64"\n", pos);
894 071790c8 Michael Niedermayer
    if(pos2 > pos || pos2 + 15 < pos){
895 4d5be986 Michael Niedermayer
        av_log(NULL, AV_LOG_ERROR, "no syncpoint at backptr pos\n");
896
    }
897 0a3b575b Michael Niedermayer
    for(i=0; i<s->nb_streams; i++)
898
        nut->stream[i].skip_until_key_frame=1;
899
900 4d5be986 Michael Niedermayer
    return 0;
901
}
902
903 619d8e2e Michael Niedermayer
static int nut_read_close(AVFormatContext *s)
904
{
905
    NUTContext *nut = s->priv_data;
906 27dbc47c Vitor Sessak
    int i;
907 619d8e2e Michael Niedermayer
908
    av_freep(&nut->time_base);
909
    av_freep(&nut->stream);
910 4b83fc0f Vitor Sessak
    ff_nut_free_sp(nut);
911 27dbc47c Vitor Sessak
    for(i = 1; i < nut->header_count; i++)
912
        av_freep(&nut->header[i]);
913 619d8e2e Michael Niedermayer
914
    return 0;
915
}
916
917 b250f9c6 Aurelien Jacobs
#if CONFIG_NUT_DEMUXER
918 619d8e2e Michael Niedermayer
AVInputFormat nut_demuxer = {
919
    "nut",
920 bde15e74 Stefano Sabatini
    NULL_IF_CONFIG_SMALL("NUT format"),
921 619d8e2e Michael Niedermayer
    sizeof(NUTContext),
922
    nut_probe,
923
    nut_read_header,
924
    nut_read_packet,
925
    nut_read_close,
926 4d5be986 Michael Niedermayer
    read_seek,
927 619d8e2e Michael Niedermayer
    .extensions = "nut",
928 43382b5f Anton Khirnov
    .metadata_conv = ff_nut_metadata_conv,
929 2e01def0 Stefano Sabatini
    .codec_tag = (const AVCodecTag * const []) { ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
930 619d8e2e Michael Niedermayer
};
931
#endif