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)
95 for (i = 0; i < len; i++) {
97 val |= get_byte(bc) << (i * 8);
102 static int get_packetheader(NUTContext *nut, ByteIOContext *bc)
104 nut->curr_frame_start = url_ftell(bc);
105 nut->curr_frame_size = get_v(bc);
106 nut->last_frame_size = get_v(bc);
107 dprintf("Packet: fwd: %d bwd: %d\n",
108 nut->curr_frame_size, nut->last_frame_size);
116 static int get_length(uint64_t val){
123 return 7; //not reached
126 static int put_v(ByteIOContext *bc, uint64_t val)
130 // if (bytes_left(s)*8 < 9)
133 if (bytes_left(bc) < 1)
136 val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
139 for (i-=7; i>0; i-=7){
140 put_byte(bc, 0x80 | (val>>i));
143 put_byte(bc, val&0x7f);
148 static int put_s(ByteIOContext *bc, uint64_t val)
151 return put_v(bc, -2*val);
153 return put_v(bc, 2*val-1);
156 static int put_b(ByteIOContext *bc, char *data, int len)
161 for (i = 0; i < len; i++)
162 put_byte(bc, data[i]);
167 static int put_bi(ByteIOContext *bc, int val)
174 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size)
176 put_flush_packet(bc);
177 nut->curr_frame_start = url_ftell(bc);
178 nut->curr_frame_size = max_size;
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);
186 nut->last_frame_size = nut->curr_frame_size;
191 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size){
192 offset_t start= nut->curr_frame_start;
193 offset_t cur= url_ftell(bc);
194 int size= cur - start + additional_size;
196 assert( size <= nut->curr_frame_size );
198 url_fseek(bc, start, SEEK_SET);
200 if(get_length(size) < get_length(nut->curr_frame_size))
202 nut->curr_frame_size= size;
203 dprintf("Packet update: size: %d\n", size);
205 url_fseek(bc, cur, SEEK_SET);
210 static int nut_write_header(AVFormatContext *s)
212 NUTContext *nut = s->priv_data;
213 ByteIOContext *bc = &s->pb;
214 AVCodecContext *codec;
216 int stream_length = 0;
218 for (i = 0; i < s->nb_streams; i++)
220 if (stream_length < (s->streams[i]->duration * (AV_TIME_BASE / 1000)))
221 stream_length = s->streams[i]->duration * (AV_TIME_BASE / 1000);
225 put_be64(bc, MAIN_STARTCODE);
226 put_packetheader(nut, bc, 120);
227 put_v(bc, 0); /* version */
228 put_v(bc, s->nb_streams);
229 put_v(bc, 0); /* file size */
230 put_v(bc, stream_length); /* len in msec */
231 put_be32(bc, 0); /* FIXME: checksum */
233 update_packetheader(nut, bc, 0);
236 for (i = 0; i < s->nb_streams; i++)
238 codec = &s->streams[i]->codec;
240 put_be64(bc, STREAM_STARTCODE);
241 put_packetheader(nut, bc, 120);
242 put_v(bc, i /*s->streams[i]->index*/);
243 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);
244 if (codec->codec_tag)
245 put_bi(bc, codec->codec_tag);
246 else if (codec->codec_type == CODEC_TYPE_VIDEO)
248 int tmp = codec_get_bmp_tag(codec->codec_id);
251 else if (codec->codec_type == CODEC_TYPE_AUDIO)
253 int tmp = codec_get_wav_tag(codec->codec_id);
256 put_v(bc, codec->bit_rate);
257 put_v(bc, 0); /* no language code */
258 put_v(bc, codec->frame_rate_base);
259 put_v(bc, codec->frame_rate);
260 put_v(bc, 0); /* timestamp_shift */
261 put_v(bc, 0); /* shuffle type */
262 put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
264 put_v(bc, 0); /* no codec specific headers */
266 switch(codec->codec_type)
268 case CODEC_TYPE_AUDIO:
269 put_v(bc, codec->sample_rate / (double)(codec->frame_rate_base / codec->frame_rate));
270 put_v(bc, codec->channels);
271 put_be32(bc, 0); /* FIXME: checksum */
273 case CODEC_TYPE_VIDEO:
274 put_v(bc, codec->width);
275 put_v(bc, codec->height);
276 put_v(bc, 0); /* aspected w */
277 put_v(bc, 0); /* aspected h */
278 put_v(bc, 0); /* csp type -- unknown */
279 put_be32(bc, 0); /* FIXME: checksum */
284 update_packetheader(nut, bc, 0);
289 put_be64(bc, INFO_STARTCODE);
290 put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+
291 strlen(s->comment)+strlen(s->copyright));
294 put_v(bc, 5); /* type */
295 put_b(bc, s->author, strlen(s->author));
299 put_v(bc, 6); /* type */
300 put_b(bc, s->title, strlen(s->title));
304 put_v(bc, 7); /* type */
305 put_b(bc, s->comment, strlen(s->comment));
309 put_v(bc, 8); /* type */
310 put_b(bc, s->copyright, strlen(s->copyright));
313 put_v(bc, 9); /* type */
314 put_b(bc, LIBAVFORMAT_IDENT "\0", strlen(LIBAVFORMAT_IDENT));
316 put_v(bc, 0); /* eof info */
318 put_be32(bc, 0); /* FIXME: checksum */
319 update_packetheader(nut, bc, 0);
322 put_flush_packet(bc);
327 static int nut_write_packet(AVFormatContext *s, int stream_index,
328 uint8_t *buf, int size, int force_pts)
330 NUTContext *nut = s->priv_data;
331 ByteIOContext *bc = &s->pb;
336 if (stream_index > s->nb_streams)
339 enc = &s->streams[stream_index]->codec;
340 if (enc->codec_type == CODEC_TYPE_VIDEO)
341 key_frame = enc->coded_frame->key_frame;
344 put_be64(bc, KEYFRAME_STARTCODE);
347 flags<<=2; flags|=1; //priority
348 flags<<=1; flags|=0; //checksum
349 flags<<=1; flags|=0; //msb_timestamp_flag
350 flags<<=2; flags|=1; //subpacket_type
351 flags<<=1; flags|=0; //reserved
355 put_packetheader(nut, bc, size+20);
356 put_v(bc, stream_index);
357 put_s(bc, force_pts); /* lsb_timestamp */
358 update_packetheader(nut, bc, size);
360 put_buffer(bc, buf, size);
362 put_flush_packet(bc);
367 static int nut_write_trailer(AVFormatContext *s)
369 ByteIOContext *bc = &s->pb;
375 for (i = 0; s->nb_streams; i++)
377 put_be64(bc, INDEX_STARTCODE);
378 put_packetheader(nut, bc, 64);
379 put_v(bc, s->streams[i]->id);
381 put_be32(bc, 0); /* FIXME: checksum */
382 update_packetheader(nut, bc, 0);
386 put_flush_packet(bc);
391 static int nut_probe(AVProbeData *p)
397 for (i = 0; i < p->buf_size; i++) {
399 code = (code << 8) | c;
400 code &= 0xFFFFFFFFFFFFFFFFULL;
401 if (code == MAIN_STARTCODE)
402 return AVPROBE_SCORE_MAX;
407 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
409 NUTContext *nut = s->priv_data;
410 ByteIOContext *bc = &s->pb;
412 int cur_stream, nb_streams;
416 if (tmp != MAIN_STARTCODE)
417 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp);
418 get_packetheader(nut, bc);
422 fprintf(stderr, "bad version (%Ld)\n", tmp);
424 nb_streams = get_v(bc);
426 s->file_size = get_v(bc);
427 s->duration = get_v(bc) / (AV_TIME_BASE / 1000);
429 get_be32(bc); /* checkusm */
434 for (cur_stream = 0; cur_stream < nb_streams; cur_stream++)
440 if (tmp != STREAM_STARTCODE)
441 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp);
442 get_packetheader(nut, bc);
443 st = av_new_stream(s, get_v(bc));
445 return AVERROR_NOMEM;
450 st->codec.codec_type = CODEC_TYPE_VIDEO;
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");
457 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");
464 fprintf(stderr, "Unknown stream class (%d)\n", class);
467 s->bit_rate += get_v(bc);
468 tmp = get_v(bc); /* language code */
471 st->codec.frame_rate_base = get_v(bc);
472 st->codec.frame_rate = get_v(bc);
473 get_v(bc); /* FIXME: msb timestamp base */
474 get_v(bc); /* shuffle type */
475 get_byte(bc); /* flags */
477 get_v(bc); /* FIXME: codec specific data headers */
479 if (class == 0) /* VIDEO */
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_le32(bc); /* checksum */
488 if (class == 32) /* AUDIO */
490 st->codec.sample_rate = get_v(bc) * (double)(st->codec.frame_rate_base / st->codec.frame_rate);
491 st->codec.channels = get_v(bc);
492 get_le32(bc); /* checksum */
499 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
501 NUTContext *nut = s->priv_data;
502 ByteIOContext *bc = &s->pb;
503 int id, timestamp, size;
512 if (tmp & 0x80) /* zero bit set? */
514 tmp<<=8 ; tmp |= get_byte(bc);
515 tmp<<=16; tmp |= get_be16(bc);
516 tmp<<=32; tmp |= get_be32(bc);
517 if (tmp == KEYFRAME_STARTCODE)
520 tmp = get_byte(bc); /* flags */
523 fprintf(stderr, "error in zero bit / startcode %LX\n", tmp);
525 get_packetheader(nut, bc);
527 if (((tmp & 0x60)>>5) > 3) /* priority <= 3 */
528 fprintf(stderr, "sanity check failed!\n");
531 timestamp = get_s(bc);
533 size = (nut->curr_frame_size - (url_ftell(bc)-nut->curr_frame_start));
534 dprintf("flags: 0x%Lx, timestamp: %d, packet size: %d\n", tmp, timestamp, size);
539 av_new_packet(pkt, size);
540 get_buffer(bc, pkt->data, size);
541 pkt->stream_index = id;
543 pkt->flags |= PKT_FLAG_KEY;
544 pkt->pts = timestamp;
549 static AVInputFormat nut_iformat = {
561 static AVOutputFormat nut_oformat = {
569 #elif defined(CONFIG_MP3LAME)
572 CODEC_ID_MP2, /* AC3 needs liba52 decoder */
582 av_register_input_format(&nut_iformat);
583 av_register_output_format(&nut_oformat);