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