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