ffmpeg / libavformat / nut.c @ 8c653280
History  View  Annotate  Download (13.7 KB)
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 021111307 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*val1); 
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 
uint8_t *buf, int size, int force_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, force_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/xnut",

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 
} 