]> git.sesse.net Git - ffmpeg/blob - libavformat/nut.c
f905410d88a71f1a48c3b64b5bd09cc9cf95d1d1
[ffmpeg] / libavformat / nut.c
1 /*
2  * "NUT" Container Format muxer and demuxer (DRAFT-20031003)
3  * Copyright (c) 2003 Alex Beregszaszi
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * NUT DRAFT can be found in MPlayer CVS at DOCS/tech/mpcf.txt
20  *
21  * AND http://people.fsn.hu/~alex/nut/ (TeX, pdf, ps, dvi, ..)
22  *
23  */
24
25 /*
26  * TODO:
27  * - checksumming
28  * - optimal timestamp handling
29  * - index writing
30  * - info and index packet reading support
31  * - startcode searching for broken streams
32  * - subpacket support
33 */
34
35 //#define DEBUG 1
36
37 #include "avformat.h"
38 #include "mpegaudio.h"
39 #include "avi.h"
40
41 //from /dev/random
42
43 #define     MAIN_STARTCODE (0xF9526A6200000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'M')
44 #define   STREAM_STARTCODE (0xD667773F00000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'S')
45 #define KEYFRAME_STARTCODE (0xCB86308700000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'K')
46 #define    INDEX_STARTCODE (0xEBFCDE0E00000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'X')
47 #define     INFO_STARTCODE (0xA37B643500000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'I')
48
49 typedef struct {
50     int curr_frame_start;
51     int last_frame_size;
52     int curr_frame_size;
53     int *msb_timestamp_shift;
54     int64_t *last_msb_timestamp;
55 } NUTContext;
56
57 static int bytes_left(ByteIOContext *bc)
58 {
59     return bc->buf_end - bc->buf_ptr;
60 }
61
62 static uint64_t get_v(ByteIOContext *bc)
63 {
64     uint64_t val = 0;
65
66     for(; bytes_left(bc) > 0; )
67     {
68         int tmp = get_byte(bc);
69
70         if (tmp&0x80)
71             val= (val<<7) + tmp - 0x80;
72         else
73             return (val<<7) + tmp;
74     }
75     return -1;
76 }
77
78 static int64_t get_s(ByteIOContext *bc)
79 {
80     int64_t v = get_v(bc) + 1;
81
82     if (v&1)
83         return -(v>>1);
84     else
85         return (v>>1);
86 }
87
88 static int get_b(ByteIOContext *bc, char *data, int maxlen)
89 {
90     int i, len;
91     
92     len = get_v(bc);
93     for (i = 0; i < len && i < maxlen; i++)
94         data[i] = get_byte(bc);
95     /* skip remaining bytes */
96     url_fskip(bc, len-i);
97
98     return 0;
99 }
100
101 static int get_bi(ByteIOContext *bc)
102 {
103    int i, len, val = 0;
104     
105     len = get_v(bc);
106     for (i = 0; i < len && i <= 4; i++)
107         val |= get_byte(bc) << (i * 8);
108     /* skip remaining bytes */
109     url_fskip(bc, len-i);
110
111     return val;
112 }
113
114 static int get_packetheader(NUTContext *nut, ByteIOContext *bc)
115 {
116     nut->curr_frame_start = url_ftell(bc);
117     nut->curr_frame_size = get_v(bc);
118     nut->last_frame_size = get_v(bc);
119     dprintf("Packet: fwd: %d bwd: %d\n",
120         nut->curr_frame_size, nut->last_frame_size);
121     
122     return 0;
123 }
124
125 /**
126  * 
127  */
128 static int get_length(uint64_t val){
129     int i;
130
131     for (i=7; ; i+=7)
132         if ((val>>i) == 0)
133             return i;
134
135     return 7; //not reached
136 }
137
138 #ifdef CONFIG_ENCODERS
139 static int put_v(ByteIOContext *bc, uint64_t val)
140 {
141     int i;
142
143 //    if (bytes_left(s)*8 < 9)
144 //      return -1;
145
146     if (bytes_left(bc) < 1)
147         return -1;
148
149     val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
150     i= get_length(val);
151
152     for (i-=7; i>0; i-=7){
153         put_byte(bc, 0x80 | (val>>i));
154     }
155
156     put_byte(bc, val&0x7f);
157
158     return 0;
159 }
160
161 static int put_s(ByteIOContext *bc, uint64_t val)
162 {
163     if (val<=0)
164         return put_v(bc, -2*val);
165     else
166         return put_v(bc, 2*val-1);
167 }
168
169 static int put_b(ByteIOContext *bc, char *data, int len)
170 {
171     int i;
172     
173     put_v(bc, len);
174     for (i = 0; i < len; i++)
175         put_byte(bc, data[i]);
176
177     return 0;
178 }
179
180 static int put_bi(ByteIOContext *bc, int val)
181 {
182     put_v(bc, 4);
183     put_le32(bc, val);
184     return 0;
185 }
186
187 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size)
188 {
189     put_flush_packet(bc);
190     nut->curr_frame_start = url_ftell(bc);
191     nut->curr_frame_size = max_size;
192     
193     /* packet header */
194     put_v(bc, nut->curr_frame_size); /* forward ptr */
195     put_v(bc, nut->last_frame_size); /* backward ptr */
196     dprintf("Packet: fwd: %d, bwd: %d\n",
197         nut->curr_frame_size, nut->last_frame_size);
198
199     nut->last_frame_size = nut->curr_frame_size;
200     
201     return 0;
202 }
203
204 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size){
205     offset_t start= nut->curr_frame_start;
206     offset_t cur= url_ftell(bc);
207     int size= cur - start + additional_size;
208     
209     assert( size <= nut->curr_frame_size );
210     
211     url_fseek(bc, start, SEEK_SET);
212     put_v(bc, size);
213     if(get_length(size) < get_length(nut->curr_frame_size))
214         put_byte(bc, 0x80);
215     nut->curr_frame_size= size;
216     dprintf("Packet update: size: %d\n", size);
217
218     url_fseek(bc, cur, SEEK_SET);    
219     
220     return 0;
221 }
222
223 static int nut_write_header(AVFormatContext *s)
224 {
225     NUTContext *nut = s->priv_data;
226     ByteIOContext *bc = &s->pb;
227     AVCodecContext *codec;
228     int i;
229
230     /* main header */
231     put_be64(bc, MAIN_STARTCODE);
232     put_packetheader(nut, bc, 120);
233     put_v(bc, 0); /* version */
234     put_v(bc, s->nb_streams);
235     put_be32(bc, 0); /* FIXME: checksum */
236     
237     update_packetheader(nut, bc, 0);
238     
239     nut->msb_timestamp_shift =  
240         av_mallocz(sizeof(nut->msb_timestamp_shift)*s->nb_streams);
241     nut->last_msb_timestamp =
242         av_mallocz(sizeof(nut->last_msb_timestamp)*s->nb_streams);
243     
244     /* stream headers */
245     for (i = 0; i < s->nb_streams; i++)
246     {
247         int nom, denom;
248
249         codec = &s->streams[i]->codec;
250         
251         put_be64(bc, STREAM_STARTCODE);
252         put_packetheader(nut, bc, 120);
253         put_v(bc, i /*s->streams[i]->index*/);
254         put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);
255         if (codec->codec_tag)
256             put_bi(bc, codec->codec_tag);
257         else if (codec->codec_type == CODEC_TYPE_VIDEO)
258         {
259             int tmp = codec_get_bmp_tag(codec->codec_id);
260             put_bi(bc, tmp);
261         }
262         else if (codec->codec_type == CODEC_TYPE_AUDIO)
263         {
264             int tmp = codec_get_wav_tag(codec->codec_id);
265             put_bi(bc, tmp);
266         }
267
268         if (codec->codec_type == CODEC_TYPE_VIDEO)
269         {
270             nom = codec->frame_rate;
271             denom = codec->frame_rate_base;
272         }
273         else
274         {
275             nom = codec->sample_rate/8;
276             denom = 8;
277         }
278         put_v(bc, codec->bit_rate);
279         put_v(bc, 0); /* no language code */
280         put_v(bc, nom);
281         put_v(bc, denom);
282         nut->msb_timestamp_shift[i] = 0;
283         put_v(bc, nut->msb_timestamp_shift[i]);
284         put_v(bc, 0); /* shuffle type */
285         put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
286         
287         put_v(bc, 0); /* no codec specific headers */
288         
289         switch(codec->codec_type)
290         {
291             case CODEC_TYPE_AUDIO:
292                 put_v(bc, (codec->sample_rate * denom) / nom);
293                 put_v(bc, codec->channels);
294                 put_be32(bc, 0); /* FIXME: checksum */
295                 break;
296             case CODEC_TYPE_VIDEO:
297                 put_v(bc, codec->width);
298                 put_v(bc, codec->height);
299                 put_v(bc, 0); /* aspected w */
300                 put_v(bc, 0); /* aspected h */
301                 put_v(bc, 0); /* csp type -- unknown */
302                 put_be32(bc, 0); /* FIXME: checksum */
303                 break;
304             default:
305                 break;
306         }
307         update_packetheader(nut, bc, 0);
308     }
309
310 #if 0
311     /* info header */
312     put_be64(bc, INFO_STARTCODE);
313     put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+
314         strlen(s->comment)+strlen(s->copyright)); 
315     if (s->author[0])
316     {
317         put_v(bc, 5); /* type */
318         put_b(bc, s->author, strlen(s->author));
319     }
320     if (s->title[0])
321     {
322         put_v(bc, 6); /* type */
323         put_b(bc, s->title, strlen(s->title));
324     }
325     if (s->comment[0])
326     {
327         put_v(bc, 7); /* type */
328         put_b(bc, s->comment, strlen(s->comment));
329     }
330     if (s->copyright[0])
331     {
332         put_v(bc, 8); /* type */
333         put_b(bc, s->copyright, strlen(s->copyright));
334     }
335     /* encoder */
336     put_v(bc, 9); /* type */
337     put_b(bc, LIBAVFORMAT_IDENT "\0", strlen(LIBAVFORMAT_IDENT));
338     
339     put_v(bc, 0); /* eof info */
340
341     put_be32(bc, 0); /* FIXME: checksum */
342     update_packetheader(nut, bc, 0);
343 #endif
344         
345     put_flush_packet(bc);
346     
347     return 0;
348 }
349
350 static int nut_write_packet(AVFormatContext *s, int stream_index, 
351                             const uint8_t *buf, int size, int64_t pts)
352 {
353     NUTContext *nut = s->priv_data;
354     ByteIOContext *bc = &s->pb;
355     int key_frame = 0, flags, msb_pts = 0;
356     AVCodecContext *enc;
357     int64_t lsb_pts;
358
359     if (stream_index > s->nb_streams)
360         return 1;
361
362     enc = &s->streams[stream_index]->codec;
363     // FIXME, lavc reports always keyframes for audio, which will make
364     // _huge_ overhead
365     if (enc->codec_type == CODEC_TYPE_VIDEO)
366         key_frame = enc->coded_frame->key_frame;
367
368     if (key_frame /*||
369         ((pts - (nut->last_msb_timestamp[stream_index] <<
370         nut->msb_timestamp_shift[stream_index])) > 1024)*/)
371     {
372         msb_pts = 1;
373         nut->last_msb_timestamp[stream_index] = pts >> nut->msb_timestamp_shift[stream_index];
374     }
375
376     lsb_pts = pts - (nut->last_msb_timestamp[stream_index] << nut->msb_timestamp_shift[stream_index]);
377     
378     flags=0;
379     flags<<=2; flags|=1; //priority
380     flags<<=1; flags|=0; //checksum
381     flags<<=1; flags|=msb_pts; //msb_timestamp_flag
382     flags<<=2; flags|=1; //subpacket_type
383     flags<<=1; flags|=0; //reserved
384
385     if (key_frame)
386         put_be64(bc, KEYFRAME_STARTCODE);
387     put_byte(bc, flags);
388
389     put_packetheader(nut, bc, size+20);
390     put_v(bc, stream_index);
391     if (msb_pts)
392         put_v(bc, nut->last_msb_timestamp[stream_index]);
393     put_v(bc, lsb_pts); /* lsb_timestamp */
394     update_packetheader(nut, bc, size);
395     
396     put_buffer(bc, buf, size);
397     
398     put_flush_packet(bc);
399
400     return 0;
401 }
402
403 static int nut_write_trailer(AVFormatContext *s)
404 {
405     NUTContext *nut = s->priv_data;
406     ByteIOContext *bc = &s->pb;
407 #if 0
408     int i;
409
410     /* WRITE INDEX */
411
412     for (i = 0; s->nb_streams; i++)
413     {
414         put_be64(bc, INDEX_STARTCODE);
415         put_packetheader(nut, bc, 64);
416         put_v(bc, s->streams[i]->id);
417         put_v(bc, ...);
418         put_be32(bc, 0); /* FIXME: checksum */
419         update_packetheader(nut, bc, 0);
420     }
421 #endif
422
423     put_flush_packet(bc);
424     
425     if (nut->last_msb_timestamp)
426         av_free(nut->last_msb_timestamp);
427     if (nut->msb_timestamp_shift)
428         av_free(nut->msb_timestamp_shift);
429
430     return 0;
431 }
432 #endif //CONFIG_ENCODERS
433
434 static int nut_probe(AVProbeData *p)
435 {
436     int i;
437     uint64_t code;
438
439     code = 0xff;
440     for (i = 0; i < p->buf_size; i++) {
441         int c = p->buf[i];
442         code = (code << 8) | c;
443         if (code == MAIN_STARTCODE)
444             return AVPROBE_SCORE_MAX;
445     }
446     return 0;
447 }
448
449 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
450 {
451     NUTContext *nut = s->priv_data;
452     ByteIOContext *bc = &s->pb;
453     uint64_t tmp;
454     int cur_stream, nb_streams;
455     
456     /* main header */
457     tmp = get_be64(bc);
458     if (tmp != MAIN_STARTCODE)
459         av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp);
460     get_packetheader(nut, bc);
461     
462     tmp = get_v(bc);
463     if (tmp != 0)
464         av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp);
465     
466     nb_streams = get_v(bc);
467     get_be32(bc); /* checkusm */
468     
469     s->bit_rate = 0;
470
471     nut->msb_timestamp_shift =  
472         av_malloc(sizeof(nut->msb_timestamp_shift)*s->nb_streams);
473     nut->last_msb_timestamp =
474         av_malloc(sizeof(nut->last_msb_timestamp)*s->nb_streams);
475     
476     /* stream header */
477     for (cur_stream = 0; cur_stream < nb_streams; cur_stream++)
478     {
479         int class, nom, denom;
480         AVStream *st;
481         
482         tmp = get_be64(bc);
483         if (tmp != STREAM_STARTCODE)
484             av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp);
485         get_packetheader(nut, bc);
486         st = av_new_stream(s, get_v(bc));
487         if (!st)
488             return AVERROR_NOMEM;
489         class = get_v(bc);
490         tmp = get_bi(bc);
491         switch(class)
492         {
493             case 0:
494                 st->codec.codec_type = CODEC_TYPE_VIDEO;
495                 st->codec.codec_id = codec_get_bmp_id(tmp);
496                 if (st->codec.codec_id == CODEC_ID_NONE)
497                     av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
498                 break;
499             case 32:
500                 st->codec.codec_type = CODEC_TYPE_AUDIO;
501                 st->codec.codec_id = codec_get_wav_id(tmp);
502                 if (st->codec.codec_id == CODEC_ID_NONE)
503                     av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
504                 break;
505             default:
506                 av_log(s, AV_LOG_ERROR, "Unknown stream class (%d)\n", class);
507                 return -1;
508         }
509         s->bit_rate += get_v(bc);
510         get_b(bc, NULL, 0); /* language code */
511         nom = get_v(bc);
512         denom = get_v(bc);
513         nut->msb_timestamp_shift[cur_stream] = get_v(bc);
514         get_v(bc); /* shuffle type */
515         get_byte(bc); /* flags */
516
517         /* codec specific data headers */
518         while(get_v(bc) != 0)
519             url_fskip(bc, get_v(bc));
520         
521         if (class == 0) /* VIDEO */
522         {
523             st->codec.width = get_v(bc);
524             st->codec.height = get_v(bc);
525             get_v(bc); /* aspected w */
526             get_v(bc); /* aspected h */
527             get_v(bc); /* csp type */
528             get_be32(bc); /* checksum */
529
530             st->codec.frame_rate = nom;
531             st->codec.frame_rate_base = denom;
532         }
533         if (class == 32) /* AUDIO */
534         {
535             st->codec.sample_rate = (get_v(bc) * nom) / denom;
536             st->codec.channels = get_v(bc);
537             get_be32(bc); /* checksum */
538         }
539     }    
540     
541     return 0;
542 }
543
544 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
545 {
546     NUTContext *nut = s->priv_data;
547     ByteIOContext *bc = &s->pb;
548     int id, size;
549     int key_frame = 0;
550     uint64_t tmp;
551     int64_t pts = 0;
552
553     if (url_feof(bc))
554         return -1;
555     
556     tmp = get_byte(bc);
557     if (tmp & 0x80) /* zero bit set? */
558     {
559         tmp<<=8 ; tmp |= get_byte(bc);
560         tmp<<=16; tmp |= get_be16(bc);
561         tmp<<=32; tmp |= get_be32(bc);
562         if (tmp == KEYFRAME_STARTCODE)
563         {
564             key_frame = 1;
565             tmp = get_byte(bc); /* flags */
566         }
567         else
568             av_log(s, AV_LOG_ERROR, "error in zero bit / startcode %LX\n", tmp);
569     }
570     get_packetheader(nut, bc);
571 #if 0
572     if (((tmp & 0x60)>>5) > 3) /* priority <= 3 */
573         av_log(s, AV_LOG_ERROR, "sanity check failed!\n");
574 #endif
575     id = get_v(bc);
576     if ((tmp & 0x8) >> 3)
577         pts = get_v(bc) << nut->msb_timestamp_shift[id];
578     pts += get_v(bc);
579     
580     size = (nut->curr_frame_size - (url_ftell(bc)-nut->curr_frame_start));
581     dprintf("flags: 0x%llx, timestamp: %llx, packet size: %d\n", tmp, pts, size);
582     
583     if (size < 0)
584         return -1;
585
586     av_new_packet(pkt, size);
587     get_buffer(bc, pkt->data, size);
588     pkt->stream_index = id;
589     if (key_frame)
590         pkt->flags |= PKT_FLAG_KEY;
591     pkt->pts = pts;
592
593     return 0;
594 }
595
596 static AVInputFormat nut_iformat = {
597     "nut",
598     "nut format",
599     sizeof(NUTContext),
600     nut_probe,
601     nut_read_header,
602     nut_read_packet,
603 //    nut_read_close,
604 //    nut_read_seek,
605     .extensions = "nut",
606 };
607
608 #ifdef CONFIG_ENCODERS
609 static AVOutputFormat nut_oformat = {
610     "nut",
611     "nut format",
612     "video/x-nut",
613     "nut",
614     sizeof(NUTContext),
615 #ifdef CONFIG_VORBIS
616     CODEC_ID_VORBIS,
617 #elif defined(CONFIG_MP3LAME)
618     CODEC_ID_MP3,
619 #else
620     CODEC_ID_MP2, /* AC3 needs liba52 decoder */
621 #endif
622     CODEC_ID_MPEG4,
623     nut_write_header,
624     nut_write_packet,
625     nut_write_trailer,
626 };
627 #endif //CONFIG_ENCODERS
628
629 int nut_init(void)
630 {
631     av_register_input_format(&nut_iformat);
632 #ifdef CONFIG_ENCODERS
633     av_register_output_format(&nut_oformat);
634 #endif //CONFIG_ENCODERS
635     return 0;
636 }