]> git.sesse.net Git - ffmpeg/blob - libavformat/nut.c
id3v2 writer
[ffmpeg] / libavformat / nut.c
1 /*
2  * "NUT" Container Format muxer and demuxer (DRAFT-200403??)
3  * Copyright (c) 2003 Alex Beregszaszi
4  * Copyright (c) 2004 Michael Niedermayer
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  * Visit the official site at http://www.nut.hu/
24  *
25  */
26
27 /*
28  * TODO:
29  * - index writing
30  * - index packet reading support
31 */
32
33 //#define DEBUG 1
34
35 #include <limits.h>
36 #include "avformat.h"
37 #include "mpegaudio.h"
38 #include "riff.h"
39 #include "adler32.h"
40
41 #undef NDEBUG
42 #include <assert.h>
43
44 //#define TRACE
45
46 //from /dev/random
47
48 #define     MAIN_STARTCODE (0x7A561F5F04ADULL + (((uint64_t)('N'<<8) + 'M')<<48))
49 #define   STREAM_STARTCODE (0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48))
50 #define KEYFRAME_STARTCODE (0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48))
51 #define    INDEX_STARTCODE (0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48))
52 #define     INFO_STARTCODE (0xAB68B596BA78ULL + (((uint64_t)('N'<<8) + 'I')<<48))
53
54 #define ID_STRING "nut/multimedia container\0"
55
56 #define MAX_DISTANCE (1024*16-1)
57 #define MAX_SHORT_DISTANCE (1024*4-1)
58
59 #define FLAG_DATA_SIZE       1
60 #define FLAG_KEY_FRAME       2
61 #define FLAG_INVALID         4
62
63 typedef struct {
64     uint8_t flags;
65     uint8_t stream_id_plus1;
66     uint16_t size_mul;
67     uint16_t size_lsb;
68     int16_t timestamp_delta;
69     uint8_t reserved_count;
70 } FrameCode;
71
72 typedef struct {
73     int last_key_frame;
74     int msb_timestamp_shift;
75     int rate_num;
76     int rate_den;
77     int64_t last_pts;
78     int64_t last_sync_pos;                    ///<pos of last 1/2 type frame
79     int decode_delay;
80 } StreamContext;
81
82 typedef struct {
83     AVFormatContext *avf;
84     int written_packet_size;
85     int64_t packet_start[3]; //0-> startcode less, 1-> short startcode 2-> long startcodes
86     FrameCode frame_code[256];
87     unsigned int stream_count;
88     uint64_t next_startcode;     ///< stores the next startcode if it has alraedy been parsed but the stream isnt seekable
89     StreamContext *stream;
90     int max_distance;
91     int max_short_distance;
92     int rate_num;
93     int rate_den;
94     int short_startcode;
95 } NUTContext;
96
97 static char *info_table[][2]={
98         {NULL                   ,  NULL }, // end
99         {NULL                   ,  NULL },
100         {NULL                   , "UTF8"},
101         {NULL                   , "v"},
102         {NULL                   , "s"},
103         {"StreamId"             , "v"},
104         {"SegmentId"            , "v"},
105         {"StartTimestamp"       , "v"},
106         {"EndTimestamp"         , "v"},
107         {"Author"               , "UTF8"},
108         {"Title"                , "UTF8"},
109         {"Description"          , "UTF8"},
110         {"Copyright"            , "UTF8"},
111         {"Encoder"              , "UTF8"},
112         {"Keyword"              , "UTF8"},
113         {"Cover"                , "JPEG"},
114         {"Cover"                , "PNG"},
115 };
116
117 static void update(NUTContext *nut, int stream_index, int64_t frame_start, int frame_type, int frame_code, int key_frame, int size, int64_t pts){
118     StreamContext *stream= &nut->stream[stream_index];
119
120     stream->last_key_frame= key_frame;
121     nut->packet_start[ frame_type ]= frame_start;
122     stream->last_pts= pts;
123 }
124
125 static void reset(AVFormatContext *s, int64_t global_ts){
126     NUTContext *nut = s->priv_data;
127     int i;
128
129     for(i=0; i<s->nb_streams; i++){
130         StreamContext *stream= &nut->stream[i];
131
132         stream->last_key_frame= 1;
133
134         stream->last_pts= av_rescale(global_ts, stream->rate_num*(int64_t)nut->rate_den, stream->rate_den*(int64_t)nut->rate_num);
135     }
136 }
137
138 static void build_frame_code(AVFormatContext *s){
139     NUTContext *nut = s->priv_data;
140     int key_frame, index, pred, stream_id;
141     int start=0;
142     int end= 255;
143     int keyframe_0_esc= s->nb_streams > 2;
144     int pred_table[10];
145
146     if(keyframe_0_esc){
147         /* keyframe = 0 escape */
148         FrameCode *ft= &nut->frame_code[start];
149         ft->flags= FLAG_DATA_SIZE;
150         ft->stream_id_plus1= 0;
151         ft->size_mul=1;
152         ft->timestamp_delta=0;
153         start++;
154     }
155
156     for(stream_id= 0; stream_id<s->nb_streams; stream_id++){
157         int start2= start + (end-start)*stream_id / s->nb_streams;
158         int end2  = start + (end-start)*(stream_id+1) / s->nb_streams;
159         AVCodecContext *codec = s->streams[stream_id]->codec;
160         int is_audio= codec->codec_type == CODEC_TYPE_AUDIO;
161         int intra_only= /*codec->intra_only || */is_audio;
162         int pred_count;
163
164         for(key_frame=0; key_frame<2; key_frame++){
165             if(intra_only && keyframe_0_esc && key_frame==0)
166                 continue;
167
168             {
169                 FrameCode *ft= &nut->frame_code[start2];
170                 ft->flags= FLAG_KEY_FRAME*key_frame;
171                 ft->flags|= FLAG_DATA_SIZE;
172                 ft->stream_id_plus1= stream_id + 1;
173                 ft->size_mul=1;
174                 ft->timestamp_delta=0;
175                 start2++;
176             }
177         }
178
179         key_frame= intra_only;
180 #if 1
181         if(is_audio){
182             int frame_bytes= codec->frame_size*(int64_t)codec->bit_rate / (8*codec->sample_rate);
183             int pts;
184             for(pts=0; pts<2; pts++){
185                 for(pred=0; pred<2; pred++){
186                     FrameCode *ft= &nut->frame_code[start2];
187                     ft->flags= FLAG_KEY_FRAME*key_frame;
188                     ft->stream_id_plus1= stream_id + 1;
189                     ft->size_mul=frame_bytes + 2;
190                     ft->size_lsb=frame_bytes + pred;
191                     ft->timestamp_delta=pts;
192                     start2++;
193                 }
194             }
195         }else{
196             FrameCode *ft= &nut->frame_code[start2];
197             ft->flags= FLAG_KEY_FRAME | FLAG_DATA_SIZE;
198             ft->stream_id_plus1= stream_id + 1;
199             ft->size_mul=1;
200             ft->timestamp_delta=1;
201             start2++;
202         }
203 #endif
204
205         if(codec->has_b_frames){
206             pred_count=5;
207             pred_table[0]=-2;
208             pred_table[1]=-1;
209             pred_table[2]=1;
210             pred_table[3]=3;
211             pred_table[4]=4;
212         }else if(codec->codec_id == CODEC_ID_VORBIS){
213             pred_count=3;
214             pred_table[0]=2;
215             pred_table[1]=9;
216             pred_table[2]=16;
217         }else{
218             pred_count=1;
219             pred_table[0]=1;
220         }
221
222         for(pred=0; pred<pred_count; pred++){
223             int start3= start2 + (end2-start2)*pred / pred_count;
224             int end3  = start2 + (end2-start2)*(pred+1) / pred_count;
225
226             for(index=start3; index<end3; index++){
227                 FrameCode *ft= &nut->frame_code[index];
228                 ft->flags= FLAG_KEY_FRAME*key_frame;
229                 ft->flags|= FLAG_DATA_SIZE;
230                 ft->stream_id_plus1= stream_id + 1;
231 //FIXME use single byte size and pred from last
232                 ft->size_mul= end3-start3;
233                 ft->size_lsb= index - start3;
234                 ft->timestamp_delta= pred_table[pred];
235             }
236         }
237     }
238     memmove(&nut->frame_code['N'+1], &nut->frame_code['N'], sizeof(FrameCode)*(255-'N'));
239     nut->frame_code['N'].flags= FLAG_INVALID;
240 }
241
242 static uint64_t get_v(ByteIOContext *bc)
243 {
244     uint64_t val = 0;
245
246     for(;;)
247     {
248         int tmp = get_byte(bc);
249
250         if (tmp&0x80)
251             val= (val<<7) + tmp - 0x80;
252         else{
253 //av_log(NULL, AV_LOG_DEBUG, "get_v()= %"PRId64"\n", (val<<7) + tmp);
254             return (val<<7) + tmp;
255         }
256     }
257     return -1;
258 }
259
260 static int get_str(ByteIOContext *bc, char *string, unsigned int maxlen){
261     unsigned int len= get_v(bc);
262
263     if(len && maxlen)
264         get_buffer(bc, string, FFMIN(len, maxlen));
265     while(len > maxlen){
266         get_byte(bc);
267         len--;
268     }
269
270     if(maxlen)
271         string[FFMIN(len, maxlen-1)]= 0;
272
273     if(maxlen == len)
274         return -1;
275     else
276         return 0;
277 }
278
279 static int64_t get_s(ByteIOContext *bc){
280     int64_t v = get_v(bc) + 1;
281
282     if (v&1) return -(v>>1);
283     else     return  (v>>1);
284 }
285
286 static uint64_t get_vb(ByteIOContext *bc){
287     uint64_t val=0;
288     unsigned int i= get_v(bc);
289
290     if(i>8)
291         return UINT64_MAX;
292
293     while(i--)
294         val = (val<<8) + get_byte(bc);
295
296 //av_log(NULL, AV_LOG_DEBUG, "get_vb()= %"PRId64"\n", val);
297     return val;
298 }
299
300 #ifdef TRACE
301 static inline uint64_t get_v_trace(ByteIOContext *bc, char *file, char *func, int line){
302     uint64_t v= get_v(bc);
303
304     printf("get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
305     return v;
306 }
307
308 static inline int64_t get_s_trace(ByteIOContext *bc, char *file, char *func, int line){
309     int64_t v= get_s(bc);
310
311     printf("get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
312     return v;
313 }
314
315 static inline uint64_t get_vb_trace(ByteIOContext *bc, char *file, char *func, int line){
316     uint64_t v= get_vb(bc);
317
318     printf("get_vb %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
319     return v;
320 }
321 #define get_v(bc)  get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
322 #define get_s(bc)  get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
323 #define get_vb(bc)  get_vb_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
324 #endif
325
326
327 static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int calculate_checksum)
328 {
329     int64_t start, size;
330     start= url_ftell(bc) - 8;
331
332     size= get_v(bc);
333
334     init_checksum(bc, calculate_checksum ? av_adler32_update : NULL, 1);
335
336     nut->packet_start[2] = start;
337     nut->written_packet_size= size;
338
339     return size;
340 }
341
342 static int check_checksum(ByteIOContext *bc){
343     unsigned long checksum= get_checksum(bc);
344     return checksum != get_be32(bc);
345 }
346
347 /**
348  *
349  */
350 static int get_length(uint64_t val){
351     int i;
352
353     for (i=7; val>>i; i+=7);
354
355     return i;
356 }
357
358 static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){
359     uint64_t state=0;
360
361     if(pos >= 0)
362         url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream isnt seekable, but that shouldnt matter, as in this case we simply start where we are currently
363
364     while(!url_feof(bc)){
365         state= (state<<8) | get_byte(bc);
366         if((state>>56) != 'N')
367             continue;
368         switch(state){
369         case MAIN_STARTCODE:
370         case STREAM_STARTCODE:
371         case KEYFRAME_STARTCODE:
372         case INFO_STARTCODE:
373         case INDEX_STARTCODE:
374             return state;
375         }
376     }
377
378     return 0;
379 }
380
381 /**
382  * find the given startcode.
383  * @param code the startcode
384  * @param pos the start position of the search, or -1 if the current position
385  * @returns the position of the startcode or -1 if not found
386  */
387 static int64_t find_startcode(ByteIOContext *bc, uint64_t code, int64_t pos){
388     for(;;){
389         uint64_t startcode= find_any_startcode(bc, pos);
390         if(startcode == code)
391             return url_ftell(bc) - 8;
392         else if(startcode == 0)
393             return -1;
394         pos=-1;
395     }
396 }
397
398 static int64_t lsb2full(StreamContext *stream, int64_t lsb){
399     int64_t mask = (1<<stream->msb_timestamp_shift)-1;
400     int64_t delta= stream->last_pts - mask/2;
401     return  ((lsb - delta)&mask) + delta;
402 }
403
404 #ifdef CONFIG_MUXERS
405
406 static void put_v(ByteIOContext *bc, uint64_t val)
407 {
408     int i;
409
410 //av_log(NULL, AV_LOG_DEBUG, "put_v()= %"PRId64"\n", val);
411     val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
412     i= get_length(val);
413
414     for (i-=7; i>0; i-=7){
415         put_byte(bc, 0x80 | (val>>i));
416     }
417
418     put_byte(bc, val&0x7f);
419 }
420
421 /**
422  * stores a string as vb.
423  */
424 static void put_str(ByteIOContext *bc, const char *string){
425     int len= strlen(string);
426
427     put_v(bc, len);
428     put_buffer(bc, string, len);
429 }
430
431 static void put_s(ByteIOContext *bc, int64_t val){
432     if (val<=0) put_v(bc, -2*val  );
433     else        put_v(bc,  2*val-1);
434 }
435
436 static void put_vb(ByteIOContext *bc, uint64_t val){
437     int i;
438
439     for (i=8; val>>i; i+=8);
440
441     put_v(bc, i>>3);
442     for(i-=8; i>=0; i-=8)
443         put_byte(bc, (val>>i)&0xFF);
444 }
445
446 #ifdef TRACE
447 static inline void put_v_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){
448     printf("get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
449
450     put_v(bc, v);
451 }
452
453 static inline void put_s_trace(ByteIOContext *bc, int64_t v, char *file, char *func, int line){
454     printf("get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
455
456     put_s(bc, v);
457 }
458
459 static inline void put_vb_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){
460     printf("get_vb %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
461
462     put_vb(bc, v);
463 }
464 #define put_v(bc, v)  put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
465 #define put_s(bc, v)  put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
466 #define put_vb(bc, v)  put_vb_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
467 #endif
468
469 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size, int calculate_checksum)
470 {
471     put_flush_packet(bc);
472     nut->packet_start[2]= url_ftell(bc) - 8;
473     nut->written_packet_size = max_size;
474
475     /* packet header */
476     put_v(bc, nut->written_packet_size); /* forward ptr */
477
478     if(calculate_checksum)
479         init_checksum(bc, av_adler32_update, 1);
480
481     return 0;
482 }
483
484 /**
485  *
486  * must not be called more then once per packet
487  */
488 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size, int calculate_checksum){
489     int64_t start= nut->packet_start[2];
490     int64_t cur= url_ftell(bc);
491     int size= cur - start - get_length(nut->written_packet_size)/7 - 8;
492
493     if(calculate_checksum)
494         size += 4;
495
496     if(size != nut->written_packet_size){
497         int i;
498
499         assert( size <= nut->written_packet_size );
500
501         url_fseek(bc, start + 8, SEEK_SET);
502         for(i=get_length(size); i < get_length(nut->written_packet_size); i+=7)
503             put_byte(bc, 0x80);
504         put_v(bc, size);
505
506         url_fseek(bc, cur, SEEK_SET);
507         nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ
508
509         if(calculate_checksum)
510             put_be32(bc, get_checksum(bc));
511     }
512
513     return 0;
514 }
515
516 static int nut_write_header(AVFormatContext *s)
517 {
518     NUTContext *nut = s->priv_data;
519     ByteIOContext *bc = &s->pb;
520     AVCodecContext *codec;
521     int i, j, tmp_time, tmp_flags,tmp_stream, tmp_mul, tmp_size, tmp_fields;
522
523     if (strcmp(s->filename, "./data/b-libav.nut")) {
524         av_log(s, AV_LOG_ERROR, " libavformat NUT is non-compliant and disabled\n");
525         return -1;
526     }
527
528     nut->avf= s;
529
530     nut->stream =
531         av_mallocz(sizeof(StreamContext)*s->nb_streams);
532
533
534     put_buffer(bc, ID_STRING, strlen(ID_STRING));
535     put_byte(bc, 0);
536     nut->packet_start[2]= url_ftell(bc);
537
538     /* main header */
539     put_be64(bc, MAIN_STARTCODE);
540     put_packetheader(nut, bc, 120+5*256, 1);
541     put_v(bc, 2); /* version */
542     put_v(bc, s->nb_streams);
543     put_v(bc, MAX_DISTANCE);
544     put_v(bc, MAX_SHORT_DISTANCE);
545
546     put_v(bc, nut->rate_num=1);
547     put_v(bc, nut->rate_den=2);
548     put_v(bc, nut->short_startcode=0x4EFE79);
549
550     build_frame_code(s);
551     assert(nut->frame_code['N'].flags == FLAG_INVALID);
552
553     tmp_time= tmp_flags= tmp_stream= tmp_mul= tmp_size= /*tmp_res=*/ INT_MAX;
554     for(i=0; i<256;){
555         tmp_fields=0;
556         tmp_size= 0;
557         if(tmp_time   != nut->frame_code[i].timestamp_delta) tmp_fields=1;
558         if(tmp_mul    != nut->frame_code[i].size_mul       ) tmp_fields=2;
559         if(tmp_stream != nut->frame_code[i].stream_id_plus1) tmp_fields=3;
560         if(tmp_size   != nut->frame_code[i].size_lsb       ) tmp_fields=4;
561 //        if(tmp_res    != nut->frame_code[i].res            ) tmp_fields=5;
562
563         tmp_time  = nut->frame_code[i].timestamp_delta;
564         tmp_flags = nut->frame_code[i].flags;
565         tmp_stream= nut->frame_code[i].stream_id_plus1;
566         tmp_mul   = nut->frame_code[i].size_mul;
567         tmp_size  = nut->frame_code[i].size_lsb;
568 //        tmp_res   = nut->frame_code[i].res;
569
570         for(j=0; i<256; j++,i++){
571             if(nut->frame_code[i].timestamp_delta != tmp_time  ) break;
572             if(nut->frame_code[i].flags           != tmp_flags ) break;
573             if(nut->frame_code[i].stream_id_plus1 != tmp_stream) break;
574             if(nut->frame_code[i].size_mul        != tmp_mul   ) break;
575             if(nut->frame_code[i].size_lsb        != tmp_size+j) break;
576 //            if(nut->frame_code[i].res             != tmp_res   ) break;
577         }
578         if(j != tmp_mul - tmp_size) tmp_fields=6;
579
580         put_v(bc, tmp_flags);
581         put_v(bc, tmp_fields);
582         if(tmp_fields>0) put_s(bc, tmp_time);
583         if(tmp_fields>1) put_v(bc, tmp_mul);
584         if(tmp_fields>2) put_v(bc, tmp_stream);
585         if(tmp_fields>3) put_v(bc, tmp_size);
586         if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/);
587         if(tmp_fields>5) put_v(bc, j);
588     }
589
590     update_packetheader(nut, bc, 0, 1);
591
592     /* stream headers */
593     for (i = 0; i < s->nb_streams; i++)
594     {
595         int nom, denom, ssize;
596
597         codec = s->streams[i]->codec;
598
599         put_be64(bc, STREAM_STARTCODE);
600         put_packetheader(nut, bc, 120 + codec->extradata_size, 1);
601         put_v(bc, i /*s->streams[i]->index*/);
602         switch(codec->codec_type){
603         case CODEC_TYPE_VIDEO: put_v(bc, 0); break;
604         case CODEC_TYPE_AUDIO: put_v(bc, 1); break;
605 //        case CODEC_TYPE_TEXT : put_v(bc, 2); break;
606         case CODEC_TYPE_DATA : put_v(bc, 3); break;
607         default: return -1;
608         }
609         if (codec->codec_tag)
610             put_vb(bc, codec->codec_tag);
611         else if (codec->codec_type == CODEC_TYPE_VIDEO)
612         {
613             put_vb(bc, codec_get_bmp_tag(codec->codec_id));
614         }
615         else if (codec->codec_type == CODEC_TYPE_AUDIO)
616         {
617             put_vb(bc, codec_get_wav_tag(codec->codec_id));
618         }
619         else
620             put_vb(bc, 0);
621
622         ff_parse_specific_params(codec, &nom, &ssize, &denom);
623
624         nut->stream[i].rate_num= nom;
625         nut->stream[i].rate_den= denom;
626         av_set_pts_info(s->streams[i], 60, denom, nom);
627
628         put_v(bc, codec->bit_rate);
629         put_vb(bc, 0); /* no language code */
630         put_v(bc, nom);
631         put_v(bc, denom);
632         if(nom / denom < 1000)
633             nut->stream[i].msb_timestamp_shift = 7;
634         else
635             nut->stream[i].msb_timestamp_shift = 14;
636         put_v(bc, nut->stream[i].msb_timestamp_shift);
637         put_v(bc, codec->has_b_frames);
638         put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
639
640         if(codec->extradata_size){
641             put_v(bc, 1);
642             put_v(bc, codec->extradata_size);
643             put_buffer(bc, codec->extradata, codec->extradata_size);
644         }
645         put_v(bc, 0); /* end of codec specific headers */
646
647         switch(codec->codec_type)
648         {
649             case CODEC_TYPE_AUDIO:
650                 put_v(bc, codec->sample_rate);
651                 put_v(bc, 1);
652                 put_v(bc, codec->channels);
653                 break;
654             case CODEC_TYPE_VIDEO:
655                 put_v(bc, codec->width);
656                 put_v(bc, codec->height);
657                 put_v(bc, codec->sample_aspect_ratio.num);
658                 put_v(bc, codec->sample_aspect_ratio.den);
659                 put_v(bc, 0); /* csp type -- unknown */
660                 break;
661             default:
662                 break;
663         }
664         update_packetheader(nut, bc, 0, 1);
665     }
666
667     /* info header */
668     put_be64(bc, INFO_STARTCODE);
669     put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+
670         strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1);
671     if (s->author[0])
672     {
673         put_v(bc, 9); /* type */
674         put_str(bc, s->author);
675     }
676     if (s->title[0])
677     {
678         put_v(bc, 10); /* type */
679         put_str(bc, s->title);
680     }
681     if (s->comment[0])
682     {
683         put_v(bc, 11); /* type */
684         put_str(bc, s->comment);
685     }
686     if (s->copyright[0])
687     {
688         put_v(bc, 12); /* type */
689         put_str(bc, s->copyright);
690     }
691     /* encoder */
692     if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)){
693         put_v(bc, 13); /* type */
694         put_str(bc, LIBAVFORMAT_IDENT);
695     }
696
697     put_v(bc, 0); /* eof info */
698     update_packetheader(nut, bc, 0, 1);
699
700     put_flush_packet(bc);
701
702     return 0;
703 }
704
705 static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
706 {
707     NUTContext *nut = s->priv_data;
708     StreamContext *stream= &nut->stream[pkt->stream_index];
709     ByteIOContext *bc = &s->pb;
710     int key_frame = 0, full_pts=0;
711     AVCodecContext *enc;
712     int64_t coded_pts;
713     int frame_type, best_length, frame_code, flags, i, size_mul, size_lsb, time_delta;
714     const int64_t frame_start= url_ftell(bc);
715     int64_t pts= pkt->pts;
716     int size= pkt->size;
717     int stream_index= pkt->stream_index;
718
719     enc = s->streams[stream_index]->codec;
720     key_frame = !!(pkt->flags & PKT_FLAG_KEY);
721
722     frame_type=0;
723     if(frame_start + size + 20 - FFMAX(nut->packet_start[1], nut->packet_start[2]) > MAX_DISTANCE)
724         frame_type=2;
725     if(key_frame && !stream->last_key_frame)
726         frame_type=2;
727
728     if(frame_type>1){
729         int64_t global_ts= av_rescale(pts, stream->rate_den*(int64_t)nut->rate_num, stream->rate_num*(int64_t)nut->rate_den);
730         reset(s, global_ts);
731         put_be64(bc, KEYFRAME_STARTCODE);
732         put_v(bc, global_ts);
733     }
734     assert(stream->last_pts != AV_NOPTS_VALUE);
735     coded_pts = pts & ((1<<stream->msb_timestamp_shift)-1);
736     if(lsb2full(stream, coded_pts) != pts)
737         full_pts=1;
738
739     if(full_pts)
740         coded_pts= pts + (1<<stream->msb_timestamp_shift);
741
742     best_length=INT_MAX;
743     frame_code= -1;
744     for(i=0; i<256; i++){
745         int stream_id_plus1= nut->frame_code[i].stream_id_plus1;
746         int fc_key_frame;
747         int length=0;
748         size_mul= nut->frame_code[i].size_mul;
749         size_lsb= nut->frame_code[i].size_lsb;
750         time_delta= nut->frame_code[i].timestamp_delta;
751         flags= nut->frame_code[i].flags;
752
753         assert(size_mul > size_lsb);
754
755         if(stream_id_plus1 == 0) length+= get_length(stream_index);
756         else if(stream_id_plus1 - 1 != stream_index)
757             continue;
758         fc_key_frame= !!(flags & FLAG_KEY_FRAME);
759
760         assert(key_frame==0 || key_frame==1);
761         if(fc_key_frame != key_frame)
762             continue;
763
764         if(flags & FLAG_DATA_SIZE){
765             if(size % size_mul != size_lsb)
766                 continue;
767             length += get_length(size / size_mul);
768         }else if(size != size_lsb)
769             continue;
770
771         if(full_pts && time_delta)
772             continue;
773
774         if(!time_delta){
775             length += get_length(coded_pts);
776         }else{
777             if(time_delta != pts - stream->last_pts)
778                 continue;
779         }
780
781         if(length < best_length){
782             best_length= length;
783             frame_code=i;
784         }
785 //    av_log(s, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d %d %d\n", key_frame, frame_type, full_pts, size, stream_index, flags, size_mul, size_lsb, stream_id_plus1, length);
786     }
787
788     assert(frame_code != -1);
789     flags= nut->frame_code[frame_code].flags;
790     size_mul= nut->frame_code[frame_code].size_mul;
791     size_lsb= nut->frame_code[frame_code].size_lsb;
792     time_delta= nut->frame_code[frame_code].timestamp_delta;
793 #ifdef TRACE
794     best_length /= 7;
795     best_length ++; //frame_code
796     if(frame_type==2){
797         best_length += 8; // startcode
798     }
799     av_log(s, AV_LOG_DEBUG, "kf:%d ft:%d pt:%d fc:%2X len:%2d size:%d stream:%d flag:%d mul:%d lsb:%d s+1:%d pts_delta:%d pts:%"PRId64" fs:%"PRId64"\n", key_frame, frame_type, full_pts ? 1 : 0, frame_code, best_length, size, stream_index, flags, size_mul, size_lsb, nut->frame_code[frame_code].stream_id_plus1,(int)(pts - stream->last_pts), pts, frame_start);
800 //    av_log(s, AV_LOG_DEBUG, "%d %d %d\n", stream->lru_pts_delta[0], stream->lru_pts_delta[1], stream->lru_pts_delta[2]);
801 #endif
802
803     assert(frame_type != 1); //short startcode not implemented yet
804     put_byte(bc, frame_code);
805
806     if(nut->frame_code[frame_code].stream_id_plus1 == 0)
807         put_v(bc, stream_index);
808     if (!time_delta){
809         put_v(bc, coded_pts);
810     }
811     if(flags & FLAG_DATA_SIZE)
812         put_v(bc, size / size_mul);
813     else
814         assert(size == size_lsb);
815     if(size > MAX_DISTANCE){
816         assert(frame_type > 1);
817     }
818
819     put_buffer(bc, pkt->data, size);
820
821     update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts);
822
823     return 0;
824 }
825
826 static int nut_write_trailer(AVFormatContext *s)
827 {
828     NUTContext *nut = s->priv_data;
829     ByteIOContext *bc = &s->pb;
830
831 #if 0
832     int i;
833
834     /* WRITE INDEX */
835
836     for (i = 0; s->nb_streams; i++)
837     {
838         put_be64(bc, INDEX_STARTCODE);
839         put_packetheader(nut, bc, 64, 1);
840         put_v(bc, s->streams[i]->id);
841         put_v(bc, ...);
842         update_packetheader(nut, bc, 0, 1);
843     }
844 #endif
845
846     put_flush_packet(bc);
847
848     av_freep(&nut->stream);
849
850     return 0;
851 }
852 #endif //CONFIG_MUXERS
853
854 static int nut_probe(AVProbeData *p)
855 {
856     int i;
857     uint64_t code= 0xff;
858
859     for (i = 0; i < p->buf_size; i++) {
860         code = (code << 8) | p->buf[i];
861         if (code == MAIN_STARTCODE)
862             return AVPROBE_SCORE_MAX;
863     }
864     return 0;
865 }
866
867 static int decode_main_header(NUTContext *nut){
868     AVFormatContext *s= nut->avf;
869     ByteIOContext *bc = &s->pb;
870     uint64_t tmp;
871     int i, j, tmp_stream, tmp_mul, tmp_time, tmp_size, count, tmp_res;
872
873     get_packetheader(nut, bc, 1);
874
875     tmp = get_v(bc);
876     if (tmp != 2){
877         av_log(s, AV_LOG_ERROR, "bad version (%"PRId64")\n", tmp);
878         return -1;
879     }
880
881     nut->stream_count = get_v(bc);
882     if(nut->stream_count > MAX_STREAMS){
883         av_log(s, AV_LOG_ERROR, "too many streams\n");
884         return -1;
885     }
886     nut->max_distance = get_v(bc);
887     nut->max_short_distance = get_v(bc);
888     nut->rate_num= get_v(bc);
889     nut->rate_den= get_v(bc);
890     nut->short_startcode= get_v(bc);
891     if(nut->short_startcode>>16 != 'N'){
892         av_log(s, AV_LOG_ERROR, "invalid short startcode %X\n", nut->short_startcode);
893         return -1;
894     }
895
896     for(i=0; i<256;){
897         int tmp_flags = get_v(bc);
898         int tmp_fields= get_v(bc);
899         if(tmp_fields>0) tmp_time  = get_s(bc);
900         if(tmp_fields>1) tmp_mul   = get_v(bc);
901         if(tmp_fields>2) tmp_stream= get_v(bc);
902         if(tmp_fields>3) tmp_size  = get_v(bc);
903         else             tmp_size  = 0;
904         if(tmp_fields>4) tmp_res   = get_v(bc);
905         else             tmp_res   = 0;
906         if(tmp_fields>5) count     = get_v(bc);
907         else             count     = tmp_mul - tmp_size;
908
909         while(tmp_fields-- > 6)
910            get_v(bc);
911
912         if(count == 0 || i+count > 256){
913             av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i);
914             return -1;
915         }
916         if(tmp_stream > nut->stream_count + 1){
917             av_log(s, AV_LOG_ERROR, "illegal stream number\n");
918             return -1;
919         }
920
921         for(j=0; j<count; j++,i++){
922             nut->frame_code[i].flags           = tmp_flags ;
923             nut->frame_code[i].timestamp_delta = tmp_time  ;
924             nut->frame_code[i].stream_id_plus1 = tmp_stream;
925             nut->frame_code[i].size_mul        = tmp_mul   ;
926             nut->frame_code[i].size_lsb        = tmp_size+j;
927             nut->frame_code[i].reserved_count  = tmp_res   ;
928         }
929     }
930     if(nut->frame_code['N'].flags != FLAG_INVALID){
931         av_log(s, AV_LOG_ERROR, "illegal frame_code table\n");
932         return -1;
933     }
934
935     if(check_checksum(bc)){
936         av_log(s, AV_LOG_ERROR, "Main header checksum mismatch\n");
937         return -1;
938     }
939
940     return 0;
941 }
942
943 static int decode_stream_header(NUTContext *nut){
944     AVFormatContext *s= nut->avf;
945     ByteIOContext *bc = &s->pb;
946     int class, nom, denom, stream_id;
947     uint64_t tmp;
948     AVStream *st;
949
950     get_packetheader(nut, bc, 1);
951     stream_id= get_v(bc);
952     if(stream_id >= nut->stream_count || s->streams[stream_id])
953         return -1;
954
955     st = av_new_stream(s, stream_id);
956     if (!st)
957         return AVERROR_NOMEM;
958
959     class = get_v(bc);
960     tmp = get_vb(bc);
961     st->codec->codec_tag= tmp;
962     switch(class)
963     {
964         case 0:
965             st->codec->codec_type = CODEC_TYPE_VIDEO;
966             st->codec->codec_id = codec_get_bmp_id(tmp);
967             if (st->codec->codec_id == CODEC_ID_NONE)
968                 av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
969             break;
970         case 1:
971         case 32: //compatibility
972             st->codec->codec_type = CODEC_TYPE_AUDIO;
973             st->codec->codec_id = codec_get_wav_id(tmp);
974             if (st->codec->codec_id == CODEC_ID_NONE)
975                 av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
976             break;
977         case 2:
978 //            st->codec->codec_type = CODEC_TYPE_TEXT;
979 //            break;
980         case 3:
981             st->codec->codec_type = CODEC_TYPE_DATA;
982             break;
983         default:
984             av_log(s, AV_LOG_ERROR, "Unknown stream class (%d)\n", class);
985             return -1;
986     }
987     s->bit_rate += get_v(bc);
988     get_vb(bc); /* language code */
989     nom = get_v(bc);
990     denom = get_v(bc);
991     nut->stream[stream_id].msb_timestamp_shift = get_v(bc);
992     st->codec->has_b_frames=
993     nut->stream[stream_id].decode_delay= get_v(bc);
994     get_byte(bc); /* flags */
995
996     /* codec specific data headers */
997     while(get_v(bc) != 0){
998         st->codec->extradata_size= get_v(bc);
999         if((unsigned)st->codec->extradata_size > (1<<30))
1000             return -1;
1001         st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1002         get_buffer(bc, st->codec->extradata, st->codec->extradata_size);
1003 //            url_fskip(bc, get_v(bc));
1004     }
1005
1006     if (st->codec->codec_type == CODEC_TYPE_VIDEO) /* VIDEO */
1007     {
1008         st->codec->width = get_v(bc);
1009         st->codec->height = get_v(bc);
1010         st->codec->sample_aspect_ratio.num= get_v(bc);
1011         st->codec->sample_aspect_ratio.den= get_v(bc);
1012         get_v(bc); /* csp type */
1013     }
1014     if (st->codec->codec_type == CODEC_TYPE_AUDIO) /* AUDIO */
1015     {
1016         st->codec->sample_rate = get_v(bc);
1017         get_v(bc); // samplerate_den
1018         st->codec->channels = get_v(bc);
1019     }
1020     if(check_checksum(bc)){
1021         av_log(s, AV_LOG_ERROR, "Stream header %d checksum mismatch\n", stream_id);
1022         return -1;
1023     }
1024     av_set_pts_info(s->streams[stream_id], 60, denom, nom);
1025     nut->stream[stream_id].rate_num= nom;
1026     nut->stream[stream_id].rate_den= denom;
1027     return 0;
1028 }
1029
1030 static int decode_info_header(NUTContext *nut){
1031     AVFormatContext *s= nut->avf;
1032     ByteIOContext *bc = &s->pb;
1033
1034     get_packetheader(nut, bc, 1);
1035
1036     for(;;){
1037         int id= get_v(bc);
1038         char *name, *type, custom_name[256], custom_type[256];
1039
1040         if(!id)
1041             break;
1042         else if(id >= sizeof(info_table)/sizeof(info_table[0])){
1043             av_log(s, AV_LOG_ERROR, "info id is too large %d %zd\n", id, sizeof(info_table)/sizeof(info_table[0]));
1044             return -1;
1045         }
1046
1047         type= info_table[id][1];
1048         name= info_table[id][0];
1049 //av_log(s, AV_LOG_DEBUG, "%d %s %s\n", id, type, name);
1050
1051         if(!type){
1052             get_str(bc, custom_type, sizeof(custom_type));
1053             type= custom_type;
1054         }
1055         if(!name){
1056             get_str(bc, custom_name, sizeof(custom_name));
1057             name= custom_name;
1058         }
1059
1060         if(!strcmp(type, "v")){
1061             get_v(bc);
1062         }else{
1063             if(!strcmp(name, "Author"))
1064                 get_str(bc, s->author, sizeof(s->author));
1065             else if(!strcmp(name, "Title"))
1066                 get_str(bc, s->title, sizeof(s->title));
1067             else if(!strcmp(name, "Copyright"))
1068                 get_str(bc, s->copyright, sizeof(s->copyright));
1069             else if(!strcmp(name, "Description"))
1070                 get_str(bc, s->comment, sizeof(s->comment));
1071             else
1072                 get_str(bc, NULL, 0);
1073         }
1074     }
1075     if(check_checksum(bc)){
1076         av_log(s, AV_LOG_ERROR, "Info header checksum mismatch\n");
1077         return -1;
1078     }
1079     return 0;
1080 }
1081
1082 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
1083 {
1084     NUTContext *nut = s->priv_data;
1085     ByteIOContext *bc = &s->pb;
1086     int64_t pos;
1087     int inited_stream_count;
1088
1089     nut->avf= s;
1090
1091     /* main header */
1092     pos=0;
1093     for(;;){
1094         pos= find_startcode(bc, MAIN_STARTCODE, pos)+1;
1095         if (pos<0){
1096             av_log(s, AV_LOG_ERROR, "no main startcode found\n");
1097             return -1;
1098         }
1099         if(decode_main_header(nut) >= 0)
1100             break;
1101     }
1102
1103
1104     s->bit_rate = 0;
1105
1106     nut->stream = av_malloc(sizeof(StreamContext)*nut->stream_count);
1107
1108     /* stream headers */
1109     pos=0;
1110     for(inited_stream_count=0; inited_stream_count < nut->stream_count;){
1111         pos= find_startcode(bc, STREAM_STARTCODE, pos)+1;
1112         if (pos<0+1){
1113             av_log(s, AV_LOG_ERROR, "not all stream headers found\n");
1114             return -1;
1115         }
1116         if(decode_stream_header(nut) >= 0)
1117             inited_stream_count++;
1118     }
1119
1120     /* info headers */
1121     pos=0;
1122     for(;;){
1123         uint64_t startcode= find_any_startcode(bc, pos);
1124         pos= url_ftell(bc);
1125
1126         if(startcode==0){
1127             av_log(s, AV_LOG_ERROR, "EOF before video frames\n");
1128             return -1;
1129         }else if(startcode == KEYFRAME_STARTCODE){
1130             nut->next_startcode= startcode;
1131             break;
1132         }else if(startcode != INFO_STARTCODE){
1133             continue;
1134         }
1135
1136         decode_info_header(nut);
1137     }
1138
1139     return 0;
1140 }
1141
1142 static int decode_frame_header(NUTContext *nut, int *key_frame_ret, int64_t *pts_ret, int *stream_id_ret, int frame_code, int frame_type, int64_t frame_start){
1143     AVFormatContext *s= nut->avf;
1144     StreamContext *stream;
1145     ByteIOContext *bc = &s->pb;
1146     int size, flags, size_mul, size_lsb, stream_id, time_delta;
1147     int64_t pts = 0;
1148
1149     if(frame_type < 2 && frame_start - nut->packet_start[2] > nut->max_distance){
1150         av_log(s, AV_LOG_ERROR, "last frame must have been damaged\n");
1151         return -1;
1152     }
1153
1154     if(frame_type)
1155         nut->packet_start[ frame_type ]= frame_start; //otherwise 1 goto 1 may happen
1156
1157     flags= nut->frame_code[frame_code].flags;
1158     size_mul= nut->frame_code[frame_code].size_mul;
1159     size_lsb= nut->frame_code[frame_code].size_lsb;
1160     stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1;
1161     time_delta= nut->frame_code[frame_code].timestamp_delta;
1162
1163     if(stream_id==-1)
1164         stream_id= get_v(bc);
1165     if(stream_id >= s->nb_streams){
1166         av_log(s, AV_LOG_ERROR, "illegal stream_id\n");
1167         return -1;
1168     }
1169     stream= &nut->stream[stream_id];
1170
1171 //    av_log(s, AV_LOG_DEBUG, "ft:%d ppts:%d %d %d\n", frame_type, stream->lru_pts_delta[0], stream->lru_pts_delta[1], stream->lru_pts_delta[2]);
1172
1173     *key_frame_ret= !!(flags & FLAG_KEY_FRAME);
1174
1175     if(!time_delta){
1176         int64_t mask = (1<<stream->msb_timestamp_shift)-1;
1177         pts= get_v(bc);
1178         if(pts > mask){
1179             pts -= mask+1;
1180         }else{
1181             if(stream->last_pts == AV_NOPTS_VALUE){
1182                 av_log(s, AV_LOG_ERROR, "no reference pts available\n");
1183                 return -1;
1184             }
1185             pts= lsb2full(stream, pts);
1186         }
1187     }else{
1188         if(stream->last_pts == AV_NOPTS_VALUE){
1189             av_log(s, AV_LOG_ERROR, "no reference pts available\n");
1190             return -1;
1191         }
1192         pts= stream->last_pts + time_delta;
1193     }
1194
1195     if(*key_frame_ret){
1196 //        av_log(s, AV_LOG_DEBUG, "stream:%d start:%"PRId64" pts:%"PRId64" length:%"PRId64"\n",stream_id, frame_start, av_pts, frame_start - nut->stream[stream_id].last_sync_pos);
1197         av_add_index_entry(
1198             s->streams[stream_id],
1199             frame_start,
1200             pts,
1201             0,
1202             frame_start - nut->stream[stream_id].last_sync_pos,
1203             AVINDEX_KEYFRAME);
1204         nut->stream[stream_id].last_sync_pos= frame_start;
1205 //                assert(nut->packet_start == frame_start);
1206     }
1207
1208     assert(size_mul > size_lsb);
1209     size= size_lsb;
1210     if(flags & FLAG_DATA_SIZE)
1211         size+= size_mul*get_v(bc);
1212
1213 #ifdef TRACE
1214 av_log(s, AV_LOG_DEBUG, "fs:%"PRId64" fc:%d ft:%d kf:%d pts:%"PRId64" size:%d mul:%d lsb:%d flags:%d delta:%d\n", frame_start, frame_code, frame_type, *key_frame_ret, pts, size, size_mul, size_lsb, flags, time_delta);
1215 #endif
1216
1217     if(frame_type==0 && url_ftell(bc) - nut->packet_start[2] + size > nut->max_distance){
1218         av_log(s, AV_LOG_ERROR, "frame size too large\n");
1219         return -1;
1220     }
1221
1222     *stream_id_ret = stream_id;
1223     *pts_ret = pts;
1224
1225     update(nut, stream_id, frame_start, frame_type, frame_code, *key_frame_ret, size, pts);
1226
1227     return size;
1228 }
1229
1230 static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type, int64_t frame_start){
1231     AVFormatContext *s= nut->avf;
1232     ByteIOContext *bc = &s->pb;
1233     int size, stream_id, key_frame, discard;
1234     int64_t pts, last_IP_pts;
1235
1236     size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, frame_start);
1237     if(size < 0)
1238         return -1;
1239
1240     discard= s->streams[ stream_id ]->discard;
1241     last_IP_pts= s->streams[ stream_id ]->last_IP_pts;
1242     if(  (discard >= AVDISCARD_NONKEY && !key_frame)
1243        ||(discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE && last_IP_pts > pts)
1244        || discard >= AVDISCARD_ALL){
1245         url_fskip(bc, size);
1246         return 1;
1247     }
1248
1249     av_get_packet(bc, pkt, size);
1250     pkt->stream_index = stream_id;
1251     if (key_frame)
1252         pkt->flags |= PKT_FLAG_KEY;
1253     pkt->pts = pts;
1254
1255     return 0;
1256 }
1257
1258 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
1259 {
1260     NUTContext *nut = s->priv_data;
1261     ByteIOContext *bc = &s->pb;
1262     int i, frame_code=0, ret;
1263
1264     for(;;){
1265         int64_t pos= url_ftell(bc);
1266         int frame_type= 0;
1267         uint64_t tmp= nut->next_startcode;
1268         nut->next_startcode=0;
1269
1270         if (url_feof(bc))
1271             return -1;
1272
1273         if(tmp){
1274             pos-=8;
1275         }else{
1276             frame_code = get_byte(bc);
1277             if(frame_code == 'N'){
1278                 tmp= frame_code;
1279                 for(i=1; i<8; i++)
1280                     tmp = (tmp<<8) + get_byte(bc);
1281             }
1282         }
1283         switch(tmp){
1284         case MAIN_STARTCODE:
1285         case STREAM_STARTCODE:
1286         case INDEX_STARTCODE:
1287             get_packetheader(nut, bc, 0);
1288             assert(nut->packet_start[2] == pos);
1289             url_fseek(bc, nut->written_packet_size, SEEK_CUR);
1290             break;
1291         case INFO_STARTCODE:
1292             if(decode_info_header(nut)<0)
1293                 goto resync;
1294             break;
1295         case KEYFRAME_STARTCODE:
1296             frame_type = 2;
1297             reset(s, get_v(bc));
1298             frame_code = get_byte(bc);
1299         case 0:
1300             ret= decode_frame(nut, pkt, frame_code, frame_type, pos);
1301             if(ret==0)
1302                 return 0;
1303             else if(ret==1) //ok but discard packet
1304                 break;
1305         default:
1306 resync:
1307 av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", nut->packet_start[2]+1);
1308             tmp= find_any_startcode(bc, nut->packet_start[2]+1);
1309             if(tmp==0)
1310                 return -1;
1311 av_log(s, AV_LOG_DEBUG, "sync\n");
1312             nut->next_startcode= tmp;
1313         }
1314     }
1315 }
1316
1317 static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){
1318     NUTContext *nut = s->priv_data;
1319     StreamContext *stream;
1320     ByteIOContext *bc = &s->pb;
1321     int64_t pos, pts;
1322     uint64_t code;
1323     int frame_code,step, stream_id, i,size, key_frame;
1324 av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%"PRId64",%"PRId64")\n", stream_index, *pos_arg, pos_limit);
1325
1326     if(*pos_arg < 0)
1327         return AV_NOPTS_VALUE;
1328
1329     pos= *pos_arg;
1330     step= FFMIN(16*1024, pos);
1331     do{
1332         pos-= step;
1333         code= find_any_startcode(bc, pos);
1334
1335         if(code && url_ftell(bc) - 8 <= *pos_arg)
1336             break;
1337         step= FFMIN(2*step, pos);
1338     }while(step);
1339
1340     if(!code) //nothing found, not even after pos_arg
1341         return AV_NOPTS_VALUE;
1342
1343     url_fseek(bc, -8, SEEK_CUR);
1344     for(i=0; i<s->nb_streams; i++)
1345         nut->stream[i].last_sync_pos= url_ftell(bc);
1346
1347     for(;;){
1348         int frame_type=0;
1349         int64_t pos= url_ftell(bc);
1350         uint64_t tmp=0;
1351
1352         if(pos > pos_limit || url_feof(bc))
1353             return AV_NOPTS_VALUE;
1354
1355         frame_code = get_byte(bc);
1356         if(frame_code == 'N'){
1357             tmp= frame_code;
1358             for(i=1; i<8; i++)
1359                 tmp = (tmp<<8) + get_byte(bc);
1360         }
1361 //av_log(s, AV_LOG_DEBUG, "before switch %"PRIX64" at=%"PRId64"\n", tmp, pos);
1362
1363         switch(tmp){
1364         case MAIN_STARTCODE:
1365         case STREAM_STARTCODE:
1366         case INDEX_STARTCODE:
1367         case INFO_STARTCODE:
1368             get_packetheader(nut, bc, 0);
1369             assert(nut->packet_start[2]==pos);
1370             url_fseek(bc, nut->written_packet_size, SEEK_CUR);
1371             break;
1372         case KEYFRAME_STARTCODE:
1373             frame_type=2;
1374             reset(s, get_v(bc));
1375             frame_code = get_byte(bc);
1376         case 0:
1377             size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, pos);
1378             if(size < 0)
1379                 goto resync;
1380
1381             stream= &nut->stream[stream_id];
1382             if(stream_id != stream_index || !key_frame || pos < *pos_arg){
1383                 url_fseek(bc, size, SEEK_CUR);
1384                 break;
1385             }
1386
1387             *pos_arg= pos;
1388             return pts;
1389         default:
1390 resync:
1391 av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", nut->packet_start[2]+1);
1392             if(!find_any_startcode(bc, nut->packet_start[2]+1))
1393                 return AV_NOPTS_VALUE;
1394
1395             url_fseek(bc, -8, SEEK_CUR);
1396         }
1397     }
1398     return AV_NOPTS_VALUE;
1399 }
1400
1401 static int nut_read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
1402 //    NUTContext *nut = s->priv_data;
1403     int64_t pos;
1404
1405     if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
1406         return -1;
1407
1408     pos= url_ftell(&s->pb);
1409     nut_read_timestamp(s, stream_index, &pos, pos-1);
1410
1411     return 0;
1412 }
1413
1414 static int nut_read_close(AVFormatContext *s)
1415 {
1416     NUTContext *nut = s->priv_data;
1417
1418     av_freep(&nut->stream);
1419
1420     return 0;
1421 }
1422
1423 #ifdef CONFIG_NUT_DEMUXER
1424 AVInputFormat nut_demuxer = {
1425     "nut",
1426     "nut format",
1427     sizeof(NUTContext),
1428     nut_probe,
1429     nut_read_header,
1430     nut_read_packet,
1431     nut_read_close,
1432     nut_read_seek,
1433     nut_read_timestamp,
1434     .extensions = "nut",
1435 };
1436 #endif
1437 #ifdef CONFIG_NUT_MUXER
1438 AVOutputFormat nut_muxer = {
1439     "nut",
1440     "nut format",
1441     "video/x-nut",
1442     "nut",
1443     sizeof(NUTContext),
1444 #ifdef CONFIG_LIBVORBIS
1445     CODEC_ID_VORBIS,
1446 #elif defined(CONFIG_LIBMP3LAME)
1447     CODEC_ID_MP3,
1448 #else
1449     CODEC_ID_MP2, /* AC3 needs liba52 decoder */
1450 #endif
1451     CODEC_ID_MPEG4,
1452     nut_write_header,
1453     nut_write_packet,
1454     nut_write_trailer,
1455     .flags = AVFMT_GLOBALHEADER,
1456 };
1457 #endif