2 * NUT (de)muxer based on initial draft
3 * Copyright (c) 2003 Alex Beregszaszi
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.
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.
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
19 * NUT DRAFT can be found in MPlayer CVS at DOCS/tech/mpcf.txt
21 * Compatible with draft version 20030906
28 * - correct rate denom/nom and sample_mul
29 * - correct timestamp handling
31 * - info and index packet reading support
32 * - startcode searching for broken streams
34 * - handling of codec specific headers
40 #include "mpegaudio.h"
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')
57 static int bytes_left(ByteIOContext *bc)
59 return bc->buf_end - bc->buf_ptr;
62 static uint64_t get_v(ByteIOContext *bc)
66 // for (; bytes_left(s)*8 > 0; )
67 for(; bytes_left(bc) > 0; )
69 int tmp = get_byte(bc);
72 val= (val<<7) + tmp - 0x80;
74 return (val<<7) + tmp;
79 static int64_t get_s(ByteIOContext *bc)
81 int64_t v = get_v(bc) + 1;
89 static int get_b(ByteIOContext *bc, char *data, int maxlen)
94 for (i = 0; i < len && i < maxlen; i++)
95 data[i] = get_byte(bc);
99 for (i = 0; i < len; i++)
106 static int get_bi(ByteIOContext *bc)
111 if(len > 4) return -1;
114 for (i = 0; i < len; i++) {
115 val |= get_byte(bc) << (i * 8);
121 static int get_packetheader(NUTContext *nut, ByteIOContext *bc)
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);
135 static int get_length(uint64_t val){
142 return 7; //not reached
145 static int put_v(ByteIOContext *bc, uint64_t val)
149 // if (bytes_left(s)*8 < 9)
152 if (bytes_left(bc) < 1)
155 val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
158 for (i-=7; i>0; i-=7){
159 put_byte(bc, 0x80 | (val>>i));
162 put_byte(bc, val&0x7f);
167 static int put_s(ByteIOContext *bc, uint64_t val)
170 return put_v(bc, -2*val);
172 return put_v(bc, 2*val-1);
175 static int put_b(ByteIOContext *bc, char *data, int len)
180 for (i = 0; i < len; i++)
181 put_byte(bc, data[i]);
186 static int put_bi(ByteIOContext *bc, int val)
193 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size)
195 put_flush_packet(bc);
196 nut->curr_frame_start = url_ftell(bc);
197 nut->curr_frame_size = max_size;
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);
205 nut->last_frame_size = nut->curr_frame_size;
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;
215 assert( size <= nut->curr_frame_size );
217 url_fseek(bc, start, SEEK_SET);
219 if(get_length(size) < get_length(nut->curr_frame_size))
221 nut->curr_frame_size= size;
222 dprintf("Packet update: size: %d\n", size);
224 url_fseek(bc, cur, SEEK_SET);
229 static int nut_write_header(AVFormatContext *s)
231 NUTContext *nut = s->priv_data;
232 ByteIOContext *bc = &s->pb;
233 AVCodecContext *codec;
235 int stream_length = 0;
237 for (i = 0; i < s->nb_streams; i++)
239 if (stream_length < (s->streams[i]->duration * (AV_TIME_BASE / 1000)))
240 stream_length = s->streams[i]->duration * (AV_TIME_BASE / 1000);
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 */
252 update_packetheader(nut, bc, 0);
255 for (i = 0; i < s->nb_streams; i++)
257 codec = &s->streams[i]->codec;
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)
267 int tmp = codec_get_bmp_tag(codec->codec_id);
270 else if (codec->codec_type == CODEC_TYPE_AUDIO)
272 int tmp = codec_get_wav_tag(codec->codec_id);
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 */
283 put_v(bc, 0); /* no codec specific headers */
285 switch(codec->codec_type)
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 */
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 */
303 update_packetheader(nut, bc, 0);
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));
313 put_v(bc, 5); /* type */
314 put_b(bc, s->author, strlen(s->author));
318 put_v(bc, 6); /* type */
319 put_b(bc, s->title, strlen(s->title));
323 put_v(bc, 7); /* type */
324 put_b(bc, s->comment, strlen(s->comment));
328 put_v(bc, 8); /* type */
329 put_b(bc, s->copyright, strlen(s->copyright));
332 put_v(bc, 9); /* type */
333 put_b(bc, LIBAVFORMAT_IDENT "\0", strlen(LIBAVFORMAT_IDENT));
335 put_v(bc, 0); /* eof info */
337 put_be32(bc, 0); /* FIXME: checksum */
338 update_packetheader(nut, bc, 0);
341 put_flush_packet(bc);
346 static int nut_write_packet(AVFormatContext *s, int stream_index,
347 const uint8_t *buf, int size, int64_t pts)
349 NUTContext *nut = s->priv_data;
350 ByteIOContext *bc = &s->pb;
355 if (stream_index > s->nb_streams)
358 enc = &s->streams[stream_index]->codec;
359 key_frame = enc->coded_frame->key_frame;
362 put_be64(bc, KEYFRAME_STARTCODE);
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
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);
378 put_buffer(bc, buf, size);
380 put_flush_packet(bc);
385 static int nut_write_trailer(AVFormatContext *s)
387 ByteIOContext *bc = &s->pb;
393 for (i = 0; s->nb_streams; i++)
395 put_be64(bc, INDEX_STARTCODE);
396 put_packetheader(nut, bc, 64);
397 put_v(bc, s->streams[i]->id);
399 put_be32(bc, 0); /* FIXME: checksum */
400 update_packetheader(nut, bc, 0);
404 put_flush_packet(bc);
409 static int nut_probe(AVProbeData *p)
415 for (i = 0; i < p->buf_size; i++) {
417 code = (code << 8) | c;
418 if (code == MAIN_STARTCODE)
419 return AVPROBE_SCORE_MAX;
424 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
426 NUTContext *nut = s->priv_data;
427 ByteIOContext *bc = &s->pb;
429 int cur_stream, nb_streams;
433 if (tmp != MAIN_STARTCODE)
434 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp);
435 get_packetheader(nut, bc);
439 fprintf(stderr, "bad version (%Ld)\n", tmp);
441 nb_streams = get_v(bc);
443 s->file_size = get_v(bc);
444 s->duration = get_v(bc) / (AV_TIME_BASE / 1000);
446 get_be32(bc); /* checkusm */
451 for (cur_stream = 0; cur_stream < nb_streams; cur_stream++)
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));
462 return AVERROR_NOMEM;
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");
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");
480 fprintf(stderr, "Unknown stream class (%d)\n", class);
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 */
491 get_v(bc); /* FIXME: codec specific data headers */
493 if (class == 0) /* VIDEO */
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 */
502 if (class == 32) /* AUDIO */
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 */
513 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
515 NUTContext *nut = s->priv_data;
516 ByteIOContext *bc = &s->pb;
517 int id, timestamp, size;
526 if (tmp & 0x80) /* zero bit set? */
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)
534 tmp = get_byte(bc); /* flags */
537 fprintf(stderr, "error in zero bit / startcode %LX\n", tmp);
539 get_packetheader(nut, bc);
541 if (((tmp & 0x60)>>5) > 3) /* priority <= 3 */
542 fprintf(stderr, "sanity check failed!\n");
545 timestamp = get_s(bc);
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);
553 av_new_packet(pkt, size);
554 get_buffer(bc, pkt->data, size);
555 pkt->stream_index = id;
557 pkt->flags |= PKT_FLAG_KEY;
558 pkt->pts = timestamp;
563 static AVInputFormat nut_iformat = {
575 static AVOutputFormat nut_oformat = {
583 #elif defined(CONFIG_MP3LAME)
586 CODEC_ID_MP2, /* AC3 needs liba52 decoder */
596 av_register_input_format(&nut_iformat);
597 av_register_output_format(&nut_oformat);