8fc24111dec5ed2c3128c8d7db3a31d5ba6404f1
[ffmpeg.git] / 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 } NUTContext;
54
55 static int bytes_left(ByteIOContext *bc)
56 {
57     return bc->buf_end - bc->buf_ptr;
58 }
59
60 static uint64_t get_v(ByteIOContext *bc)
61 {
62     uint64_t val = 0;
63
64     for(; bytes_left(bc) > 0; )
65     {
66         int tmp = get_byte(bc);
67
68         if (tmp&0x80)
69             val= (val<<7) + tmp - 0x80;
70         else
71             return (val<<7) + tmp;
72     }
73     return -1;
74 }
75
76 static int64_t get_s(ByteIOContext *bc)
77 {
78     int64_t v = get_v(bc) + 1;
79
80     if (v&1)
81         return -(v>>1);
82     else
83         return (v>>1);
84 }
85
86 static int get_b(ByteIOContext *bc, char *data, int maxlen)
87 {
88     int i, len;
89     
90     len = get_v(bc);
91     for (i = 0; i < len && i < maxlen; i++)
92         data[i] = get_byte(bc);
93     /* skip remaining bytes */
94     url_fskip(bc, len-i);
95
96     return 0;
97 }
98
99 static int get_bi(ByteIOContext *bc)
100 {
101    int i, len, val = 0;
102     
103     len = get_v(bc);
104     for (i = 0; i < len && i <= 4; i++)
105         val |= get_byte(bc) << (i * 8);
106     /* skip remaining bytes */
107     url_fskip(bc, len-i);
108
109     return val;
110 }
111
112 static int get_packetheader(NUTContext *nut, ByteIOContext *bc)
113 {
114     nut->curr_frame_start = url_ftell(bc);
115     nut->curr_frame_size = get_v(bc);
116     nut->last_frame_size = get_v(bc);
117     dprintf("Packet: fwd: %d bwd: %d\n",
118         nut->curr_frame_size, nut->last_frame_size);
119     
120     return 0;
121 }
122
123 /**
124  * 
125  */
126 static int get_length(uint64_t val){
127     int i;
128
129     for (i=7; ; i+=7)
130         if ((val>>i) == 0)
131             return i;
132
133     return 7; //not reached
134 }
135
136 static int put_v(ByteIOContext *bc, uint64_t val)
137 {
138     int i;
139
140 //    if (bytes_left(s)*8 < 9)
141 //      return -1;
142
143     if (bytes_left(bc) < 1)
144         return -1;
145
146     val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
147     i= get_length(val);
148
149     for (i-=7; i>0; i-=7){
150         put_byte(bc, 0x80 | (val>>i));
151     }
152
153     put_byte(bc, val&0x7f);
154
155     return 0;
156 }
157
158 static int put_s(ByteIOContext *bc, uint64_t val)
159 {
160     if (val<=0)
161         return put_v(bc, -2*val);
162     else
163         return put_v(bc, 2*val-1);
164 }
165
166 static int put_b(ByteIOContext *bc, char *data, int len)
167 {
168     int i;
169     
170     put_v(bc, len);
171     for (i = 0; i < len; i++)
172         put_byte(bc, data[i]);
173
174     return 0;
175 }
176
177 static int put_bi(ByteIOContext *bc, int val)
178 {
179     put_v(bc, 4);
180     put_le32(bc, val);
181     return 0;
182 }
183
184 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size)
185 {
186     put_flush_packet(bc);
187     nut->curr_frame_start = url_ftell(bc);
188     nut->curr_frame_size = max_size;
189     
190     /* packet header */
191     put_v(bc, nut->curr_frame_size); /* forward ptr */
192     put_v(bc, nut->last_frame_size); /* backward ptr */
193     dprintf("Packet: fwd: %d, bwd: %d\n",
194         nut->curr_frame_size, nut->last_frame_size);
195
196     nut->last_frame_size = nut->curr_frame_size;
197     
198     return 0;
199 }
200
201 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size){
202     offset_t start= nut->curr_frame_start;
203     offset_t cur= url_ftell(bc);
204     int size= cur - start + additional_size;
205     
206     assert( size <= nut->curr_frame_size );
207     
208     url_fseek(bc, start, SEEK_SET);
209     put_v(bc, size);
210     if(get_length(size) < get_length(nut->curr_frame_size))
211         put_byte(bc, 0x80);
212     nut->curr_frame_size= size;
213     dprintf("Packet update: size: %d\n", size);
214
215     url_fseek(bc, cur, SEEK_SET);    
216     
217     return 0;
218 }
219
220 static int nut_write_header(AVFormatContext *s)
221 {
222     NUTContext *nut = s->priv_data;
223     ByteIOContext *bc = &s->pb;
224     AVCodecContext *codec;
225     int i;
226
227     /* main header */
228     put_be64(bc, MAIN_STARTCODE);
229     put_packetheader(nut, bc, 120);
230     put_v(bc, 0); /* version */
231     put_v(bc, s->nb_streams);
232     put_be32(bc, 0); /* FIXME: checksum */
233     
234     update_packetheader(nut, bc, 0);
235     
236     /* stream headers */
237     for (i = 0; i < s->nb_streams; i++)
238     {
239         int nom, denom;
240
241         codec = &s->streams[i]->codec;
242         
243         put_be64(bc, STREAM_STARTCODE);
244         put_packetheader(nut, bc, 120);
245         put_v(bc, i /*s->streams[i]->index*/);
246         put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);
247         if (codec->codec_tag)
248             put_bi(bc, codec->codec_tag);
249         else if (codec->codec_type == CODEC_TYPE_VIDEO)
250         {
251             int tmp = codec_get_bmp_tag(codec->codec_id);
252             put_bi(bc, tmp);
253             nom = codec->frame_rate;
254             denom = codec->frame_rate_base;
255         }
256         else if (codec->codec_type == CODEC_TYPE_AUDIO)
257         {
258             int tmp = codec_get_wav_tag(codec->codec_id);
259             put_bi(bc, tmp);
260             nom = codec->sample_rate/8;
261             denom = 8;
262         }
263         put_v(bc, codec->bit_rate);
264         put_v(bc, 0); /* no language code */
265         put_v(bc, nom);
266         put_v(bc, denom);
267         put_v(bc, 0); /* msb timestamp_shift */
268         put_v(bc, 0); /* shuffle type */
269         put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
270         
271         put_v(bc, 0); /* no codec specific headers */
272         
273         switch(codec->codec_type)
274         {
275             case CODEC_TYPE_AUDIO:
276                 put_v(bc, (codec->sample_rate * denom) / nom);
277                 put_v(bc, codec->channels);
278                 put_be32(bc, 0); /* FIXME: checksum */
279                 break;
280             case CODEC_TYPE_VIDEO:
281                 put_v(bc, codec->width);
282                 put_v(bc, codec->height);
283                 put_v(bc, 0); /* aspected w */
284                 put_v(bc, 0); /* aspected h */
285                 put_v(bc, 0); /* csp type -- unknown */
286                 put_be32(bc, 0); /* FIXME: checksum */
287                 break;
288             default:
289                 break;
290         }
291         update_packetheader(nut, bc, 0);
292     }
293
294 #if 0
295     /* info header */
296     put_be64(bc, INFO_STARTCODE);
297     put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+
298         strlen(s->comment)+strlen(s->copyright)); 
299     if (s->author[0])
300     {
301         put_v(bc, 5); /* type */
302         put_b(bc, s->author, strlen(s->author));
303     }
304     if (s->title[0])
305     {
306         put_v(bc, 6); /* type */
307         put_b(bc, s->title, strlen(s->title));
308     }
309     if (s->comment[0])
310     {
311         put_v(bc, 7); /* type */
312         put_b(bc, s->comment, strlen(s->comment));
313     }
314     if (s->copyright[0])
315     {
316         put_v(bc, 8); /* type */
317         put_b(bc, s->copyright, strlen(s->copyright));
318     }
319     /* encoder */
320     put_v(bc, 9); /* type */
321     put_b(bc, LIBAVFORMAT_IDENT "\0", strlen(LIBAVFORMAT_IDENT));
322     
323     put_v(bc, 0); /* eof info */
324
325     put_be32(bc, 0); /* FIXME: checksum */
326     update_packetheader(nut, bc, 0);
327 #endif
328         
329     put_flush_packet(bc);
330     
331     return 0;
332 }
333
334 static int nut_write_packet(AVFormatContext *s, int stream_index, 
335                             const uint8_t *buf, int size, int64_t pts)
336 {
337     NUTContext *nut = s->priv_data;
338     ByteIOContext *bc = &s->pb;
339     int key_frame = 0;
340     int flags;
341     AVCodecContext *enc;
342
343     if (stream_index > s->nb_streams)
344         return 1;
345
346     enc = &s->streams[stream_index]->codec;
347     key_frame = enc->coded_frame->key_frame;
348
349     if (key_frame)
350         put_be64(bc, KEYFRAME_STARTCODE);
351     
352     flags=0;
353     flags<<=2; flags|=1; //priority
354     flags<<=1; flags|=0; //checksum
355     flags<<=1; flags|=0; //msb_timestamp_flag
356     flags<<=2; flags|=1; //subpacket_type
357     flags<<=1; flags|=0; //reserved
358
359     put_byte(bc, flags);
360
361     put_packetheader(nut, bc, size+20);
362     put_v(bc, stream_index);
363     put_s(bc, pts); /* lsb_timestamp */
364     update_packetheader(nut, bc, size);
365     
366     put_buffer(bc, buf, size);
367     
368     put_flush_packet(bc);
369
370     return 0;
371 }
372
373 static int nut_write_trailer(AVFormatContext *s)
374 {
375     ByteIOContext *bc = &s->pb;
376 #if 0
377     int i;
378
379     /* WRITE INDEX */
380
381     for (i = 0; s->nb_streams; i++)
382     {
383         put_be64(bc, INDEX_STARTCODE);
384         put_packetheader(nut, bc, 64);
385         put_v(bc, s->streams[i]->id);
386         put_v(bc, ...);
387         put_be32(bc, 0); /* FIXME: checksum */
388         update_packetheader(nut, bc, 0);
389     }
390 #endif
391
392     put_flush_packet(bc);
393
394     return 0;
395 }
396
397 static int nut_probe(AVProbeData *p)
398 {
399     int i;
400     uint64_t code;
401
402     code = 0xff;
403     for (i = 0; i < p->buf_size; i++) {
404         int c = p->buf[i];
405         code = (code << 8) | c;
406         if (code == MAIN_STARTCODE)
407             return AVPROBE_SCORE_MAX;
408     }
409     return 0;
410 }
411
412 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
413 {
414     NUTContext *nut = s->priv_data;
415     ByteIOContext *bc = &s->pb;
416     uint64_t tmp;
417     int cur_stream, nb_streams;
418     
419     /* main header */
420     tmp = get_be64(bc);
421     if (tmp != MAIN_STARTCODE)
422         fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp);
423     get_packetheader(nut, bc);
424     
425     tmp = get_v(bc);
426     if (tmp != 0)
427         fprintf(stderr, "bad version (%Ld)\n", tmp);
428     
429     nb_streams = get_v(bc);
430     get_be32(bc); /* checkusm */
431     
432     s->bit_rate = 0;
433     
434     /* stream header */
435     for (cur_stream = 0; cur_stream < nb_streams; cur_stream++)
436     {
437         int class, nom, denom;
438         AVStream *st;
439         
440         tmp = get_be64(bc);
441         if (tmp != STREAM_STARTCODE)
442             fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp);
443         get_packetheader(nut, bc);
444         st = av_new_stream(s, get_v(bc));
445         if (!st)
446             return AVERROR_NOMEM;
447         class = get_v(bc);
448         tmp = get_bi(bc);
449         switch(class)
450         {
451             case 0:
452                 st->codec.codec_type = CODEC_TYPE_VIDEO;
453                 st->codec.codec_id = codec_get_bmp_id(tmp);
454                 if (st->codec.codec_id == CODEC_ID_NONE)
455                     fprintf(stderr, "Unknown codec?!\n");
456                 break;
457             case 32:
458                 st->codec.codec_type = CODEC_TYPE_AUDIO;
459                 st->codec.codec_id = codec_get_wav_id(tmp);
460                 if (st->codec.codec_id == CODEC_ID_NONE)
461                     fprintf(stderr, "Unknown codec?!\n");
462                 break;
463             default:
464                 fprintf(stderr, "Unknown stream class (%d)\n", class);
465                 return -1;
466         }
467         s->bit_rate += get_v(bc);
468         get_b(bc, NULL, 0); /* language code */
469         nom = get_v(bc);
470         denom = get_v(bc);
471         get_v(bc); /* FIXME: msb timestamp base */
472         get_v(bc); /* shuffle type */
473         get_byte(bc); /* flags */
474
475         /* codec specific data headers */
476         while(get_v(bc) != 0)
477             url_fskip(bc, get_v(bc));
478         
479         if (class == 0) /* VIDEO */
480         {
481             st->codec.width = get_v(bc);
482             st->codec.height = get_v(bc);
483             get_v(bc); /* aspected w */
484             get_v(bc); /* aspected h */
485             get_v(bc); /* csp type */
486             get_be32(bc); /* checksum */
487
488             st->codec.frame_rate = nom;
489             st->codec.frame_rate_base = denom;
490         }
491         if (class == 32) /* AUDIO */
492         {
493             st->codec.sample_rate = (get_v(bc) * nom) / denom;
494             st->codec.channels = get_v(bc);
495             get_be32(bc); /* checksum */
496         }
497     }    
498     
499     return 0;
500 }
501
502 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
503 {
504     NUTContext *nut = s->priv_data;
505     ByteIOContext *bc = &s->pb;
506     int id, timestamp, size;
507     int key_frame = 0;
508     uint64_t tmp;
509
510
511     if (url_feof(bc))
512         return -1;
513     
514     tmp = get_byte(bc);
515     if (tmp & 0x80) /* zero bit set? */
516     {
517         tmp<<=8 ; tmp |= get_byte(bc);
518         tmp<<=16; tmp |= get_be16(bc);
519         tmp<<=32; tmp |= get_be32(bc);
520         if (tmp == KEYFRAME_STARTCODE)
521         {
522             key_frame = 1;
523             tmp = get_byte(bc); /* flags */
524         }
525         else
526             fprintf(stderr, "error in zero bit / startcode %LX\n", tmp);
527     }
528     get_packetheader(nut, bc);
529 #if 0
530     if (((tmp & 0x60)>>5) > 3) /* priority <= 3 */
531         fprintf(stderr, "sanity check failed!\n");
532 #endif
533     id = get_v(bc);
534     timestamp = get_s(bc);
535     
536     size = (nut->curr_frame_size - (url_ftell(bc)-nut->curr_frame_start));
537     dprintf("flags: 0x%Lx, timestamp: %d, packet size: %d\n", tmp, timestamp, size);
538     
539     if (size < 0)
540         return -1;
541
542     av_new_packet(pkt, size);
543     get_buffer(bc, pkt->data, size);
544     pkt->stream_index = id;
545     if (key_frame)
546         pkt->flags |= PKT_FLAG_KEY;
547     pkt->pts = timestamp;
548
549     return 0;
550 }
551
552 static AVInputFormat nut_iformat = {
553     "nut",
554     "nut format",
555     sizeof(NUTContext),
556     nut_probe,
557     nut_read_header,
558     nut_read_packet,
559 //    nut_read_close,
560 //    nut_read_seek,
561     .extensions = "nut",
562 };
563
564 static AVOutputFormat nut_oformat = {
565     "nut",
566     "nut format",
567     "video/x-nut",
568     "nut",
569     sizeof(NUTContext),
570 #ifdef CONFIG_VORBIS
571     CODEC_ID_VORBIS,
572 #elif defined(CONFIG_MP3LAME)
573     CODEC_ID_MP3,
574 #else
575     CODEC_ID_MP2, /* AC3 needs liba52 decoder */
576 #endif
577     CODEC_ID_MPEG4,
578     nut_write_header,
579     nut_write_packet,
580     nut_write_trailer,
581 };
582
583 int nut_init(void)
584 {
585     av_register_input_format(&nut_iformat);
586     av_register_output_format(&nut_oformat);
587     return 0;
588 }