Statistics
| Branch: | Revision:

ffmpeg / libavformat / nutdec.c @ 03700d39

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