Mercurial > libavformat.hg
comparison nut.c @ 885:da1d5db0ce5c libavformat
COSMETICS: Remove all trailing whitespace.
author | diego |
---|---|
date | Sat, 17 Dec 2005 18:14:38 +0000 |
parents | 91dcb9da9be6 |
children | d70e50f1495f |
comparison
equal
deleted
inserted
replaced
884:2ece9c9dd94c | 885:da1d5db0ce5c |
---|---|
40 | 40 |
41 //#define TRACE | 41 //#define TRACE |
42 | 42 |
43 //from /dev/random | 43 //from /dev/random |
44 | 44 |
45 #define MAIN_STARTCODE (0x7A561F5F04ADULL + (((uint64_t)('N'<<8) + 'M')<<48)) | 45 #define MAIN_STARTCODE (0x7A561F5F04ADULL + (((uint64_t)('N'<<8) + 'M')<<48)) |
46 #define STREAM_STARTCODE (0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48)) | 46 #define STREAM_STARTCODE (0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48)) |
47 #define KEYFRAME_STARTCODE (0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48)) | 47 #define KEYFRAME_STARTCODE (0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48)) |
48 #define INDEX_STARTCODE (0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48)) | 48 #define INDEX_STARTCODE (0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48)) |
49 #define INFO_STARTCODE (0xAB68B596BA78ULL + (((uint64_t)('N'<<8) + 'I')<<48)) | 49 #define INFO_STARTCODE (0xAB68B596BA78ULL + (((uint64_t)('N'<<8) + 'I')<<48)) |
50 | 50 |
51 #define ID_STRING "nut/multimedia container\0" | 51 #define ID_STRING "nut/multimedia container\0" |
52 | 52 |
53 #define MAX_DISTANCE (1024*16-1) | 53 #define MAX_DISTANCE (1024*16-1) |
54 #define MAX_SHORT_DISTANCE (1024*4-1) | 54 #define MAX_SHORT_DISTANCE (1024*4-1) |
113 | 113 |
114 void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale); | 114 void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale); |
115 | 115 |
116 static void update(NUTContext *nut, int stream_index, int64_t frame_start, int frame_type, int frame_code, int key_frame, int size, int64_t pts){ | 116 static void update(NUTContext *nut, int stream_index, int64_t frame_start, int frame_type, int frame_code, int key_frame, int size, int64_t pts){ |
117 StreamContext *stream= &nut->stream[stream_index]; | 117 StreamContext *stream= &nut->stream[stream_index]; |
118 | 118 |
119 stream->last_key_frame= key_frame; | 119 stream->last_key_frame= key_frame; |
120 nut->packet_start[ frame_type ]= frame_start; | 120 nut->packet_start[ frame_type ]= frame_start; |
121 stream->last_pts= pts; | 121 stream->last_pts= pts; |
122 } | 122 } |
123 | 123 |
124 static void reset(AVFormatContext *s, int64_t global_ts){ | 124 static void reset(AVFormatContext *s, int64_t global_ts){ |
125 NUTContext *nut = s->priv_data; | 125 NUTContext *nut = s->priv_data; |
126 int i; | 126 int i; |
127 | 127 |
128 for(i=0; i<s->nb_streams; i++){ | 128 for(i=0; i<s->nb_streams; i++){ |
129 StreamContext *stream= &nut->stream[i]; | 129 StreamContext *stream= &nut->stream[i]; |
130 | 130 |
131 stream->last_key_frame= 1; | 131 stream->last_key_frame= 1; |
132 | 132 |
133 stream->last_pts= av_rescale(global_ts, stream->rate_num*(int64_t)nut->rate_den, stream->rate_den*(int64_t)nut->rate_num); | 133 stream->last_pts= av_rescale(global_ts, stream->rate_num*(int64_t)nut->rate_den, stream->rate_den*(int64_t)nut->rate_num); |
134 } | 134 } |
135 } | 135 } |
161 int pred_count; | 161 int pred_count; |
162 | 162 |
163 for(key_frame=0; key_frame<2; key_frame++){ | 163 for(key_frame=0; key_frame<2; key_frame++){ |
164 if(intra_only && keyframe_0_esc && key_frame==0) | 164 if(intra_only && keyframe_0_esc && key_frame==0) |
165 continue; | 165 continue; |
166 | 166 |
167 { | 167 { |
168 FrameCode *ft= &nut->frame_code[start2]; | 168 FrameCode *ft= &nut->frame_code[start2]; |
169 ft->flags= FLAG_KEY_FRAME*key_frame; | 169 ft->flags= FLAG_KEY_FRAME*key_frame; |
170 ft->flags|= FLAG_DATA_SIZE; | 170 ft->flags|= FLAG_DATA_SIZE; |
171 ft->stream_id_plus1= stream_id + 1; | 171 ft->stream_id_plus1= stream_id + 1; |
256 return -1; | 256 return -1; |
257 } | 257 } |
258 | 258 |
259 static int get_str(ByteIOContext *bc, char *string, unsigned int maxlen){ | 259 static int get_str(ByteIOContext *bc, char *string, unsigned int maxlen){ |
260 unsigned int len= get_v(bc); | 260 unsigned int len= get_v(bc); |
261 | 261 |
262 if(len && maxlen) | 262 if(len && maxlen) |
263 get_buffer(bc, string, FFMIN(len, maxlen)); | 263 get_buffer(bc, string, FFMIN(len, maxlen)); |
264 while(len > maxlen){ | 264 while(len > maxlen){ |
265 get_byte(bc); | 265 get_byte(bc); |
266 len--; | 266 len--; |
267 } | 267 } |
268 | 268 |
269 if(maxlen) | 269 if(maxlen) |
270 string[FFMIN(len, maxlen-1)]= 0; | 270 string[FFMIN(len, maxlen-1)]= 0; |
271 | 271 |
272 if(maxlen == len) | 272 if(maxlen == len) |
273 return -1; | 273 return -1; |
274 else | 274 else |
275 return 0; | 275 return 0; |
276 } | 276 } |
283 } | 283 } |
284 | 284 |
285 static uint64_t get_vb(ByteIOContext *bc){ | 285 static uint64_t get_vb(ByteIOContext *bc){ |
286 uint64_t val=0; | 286 uint64_t val=0; |
287 unsigned int i= get_v(bc); | 287 unsigned int i= get_v(bc); |
288 | 288 |
289 if(i>8) | 289 if(i>8) |
290 return UINT64_MAX; | 290 return UINT64_MAX; |
291 | 291 |
292 while(i--) | 292 while(i--) |
293 val = (val<<8) + get_byte(bc); | 293 val = (val<<8) + get_byte(bc); |
294 | 294 |
295 //av_log(NULL, AV_LOG_DEBUG, "get_vb()= %lld\n", val); | 295 //av_log(NULL, AV_LOG_DEBUG, "get_vb()= %lld\n", val); |
296 return val; | 296 return val; |
297 } | 297 } |
298 | 298 |
299 #ifdef TRACE | 299 #ifdef TRACE |
342 unsigned long checksum= get_checksum(bc); | 342 unsigned long checksum= get_checksum(bc); |
343 return checksum != get_be32(bc); | 343 return checksum != get_be32(bc); |
344 } | 344 } |
345 | 345 |
346 /** | 346 /** |
347 * | 347 * |
348 */ | 348 */ |
349 static int get_length(uint64_t val){ | 349 static int get_length(uint64_t val){ |
350 int i; | 350 int i; |
351 | 351 |
352 for (i=7; val>>i; i+=7); | 352 for (i=7; val>>i; i+=7); |
354 return i; | 354 return i; |
355 } | 355 } |
356 | 356 |
357 static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){ | 357 static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){ |
358 uint64_t state=0; | 358 uint64_t state=0; |
359 | 359 |
360 if(pos >= 0) | 360 if(pos >= 0) |
361 url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream isnt seekable, but that shouldnt matter, as in this case we simply start where we are currently | 361 url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream isnt seekable, but that shouldnt matter, as in this case we simply start where we are currently |
362 | 362 |
363 while(!url_feof(bc)){ | 363 while(!url_feof(bc)){ |
364 state= (state<<8) | get_byte(bc); | 364 state= (state<<8) | get_byte(bc); |
414 /** | 414 /** |
415 * stores a string as vb. | 415 * stores a string as vb. |
416 */ | 416 */ |
417 static void put_str(ByteIOContext *bc, const char *string){ | 417 static void put_str(ByteIOContext *bc, const char *string){ |
418 int len= strlen(string); | 418 int len= strlen(string); |
419 | 419 |
420 put_v(bc, len); | 420 put_v(bc, len); |
421 put_buffer(bc, string, len); | 421 put_buffer(bc, string, len); |
422 } | 422 } |
423 | 423 |
424 static void put_s(ByteIOContext *bc, int64_t val){ | 424 static void put_s(ByteIOContext *bc, int64_t val){ |
426 else put_v(bc, 2*val-1); | 426 else put_v(bc, 2*val-1); |
427 } | 427 } |
428 | 428 |
429 static void put_vb(ByteIOContext *bc, uint64_t val){ | 429 static void put_vb(ByteIOContext *bc, uint64_t val){ |
430 int i; | 430 int i; |
431 | 431 |
432 for (i=8; val>>i; i+=8); | 432 for (i=8; val>>i; i+=8); |
433 | 433 |
434 put_v(bc, i>>3); | 434 put_v(bc, i>>3); |
435 for(i-=8; i>=0; i-=8) | 435 for(i-=8; i>=0; i-=8) |
436 put_byte(bc, (val>>i)&0xFF); | 436 put_byte(bc, (val>>i)&0xFF); |
437 } | 437 } |
438 | 438 |
439 #ifdef TRACE | 439 #ifdef TRACE |
440 static inline void put_v_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){ | 440 static inline void put_v_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){ |
441 printf("get_v %5lld / %llX in %s %s:%d\n", v, v, file, func, line); | 441 printf("get_v %5lld / %llX in %s %s:%d\n", v, v, file, func, line); |
442 | 442 |
443 put_v(bc, v); | 443 put_v(bc, v); |
444 } | 444 } |
445 | 445 |
446 static inline void put_s_trace(ByteIOContext *bc, int64_t v, char *file, char *func, int line){ | 446 static inline void put_s_trace(ByteIOContext *bc, int64_t v, char *file, char *func, int line){ |
447 printf("get_s %5lld / %llX in %s %s:%d\n", v, v, file, func, line); | 447 printf("get_s %5lld / %llX in %s %s:%d\n", v, v, file, func, line); |
448 | 448 |
449 put_s(bc, v); | 449 put_s(bc, v); |
450 } | 450 } |
451 | 451 |
452 static inline void put_vb_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){ | 452 static inline void put_vb_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){ |
453 printf("get_vb %5lld / %llX in %s %s:%d\n", v, v, file, func, line); | 453 printf("get_vb %5lld / %llX in %s %s:%d\n", v, v, file, func, line); |
454 | 454 |
455 put_vb(bc, v); | 455 put_vb(bc, v); |
456 } | 456 } |
457 #define put_v(bc, v) put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) | 457 #define put_v(bc, v) put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) |
458 #define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) | 458 #define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) |
459 #define put_vb(bc, v) put_vb_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) | 459 #define put_vb(bc, v) put_vb_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) |
462 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size, int calculate_checksum) | 462 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size, int calculate_checksum) |
463 { | 463 { |
464 put_flush_packet(bc); | 464 put_flush_packet(bc); |
465 nut->packet_start[2]= url_ftell(bc) - 8; | 465 nut->packet_start[2]= url_ftell(bc) - 8; |
466 nut->written_packet_size = max_size; | 466 nut->written_packet_size = max_size; |
467 | 467 |
468 /* packet header */ | 468 /* packet header */ |
469 put_v(bc, nut->written_packet_size); /* forward ptr */ | 469 put_v(bc, nut->written_packet_size); /* forward ptr */ |
470 | 470 |
471 if(calculate_checksum) | 471 if(calculate_checksum) |
472 init_checksum(bc, update_adler32, 0); | 472 init_checksum(bc, update_adler32, 0); |
480 */ | 480 */ |
481 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size, int calculate_checksum){ | 481 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size, int calculate_checksum){ |
482 int64_t start= nut->packet_start[2]; | 482 int64_t start= nut->packet_start[2]; |
483 int64_t cur= url_ftell(bc); | 483 int64_t cur= url_ftell(bc); |
484 int size= cur - start - get_length(nut->written_packet_size)/7 - 8; | 484 int size= cur - start - get_length(nut->written_packet_size)/7 - 8; |
485 | 485 |
486 if(calculate_checksum) | 486 if(calculate_checksum) |
487 size += 4; | 487 size += 4; |
488 | 488 |
489 if(size != nut->written_packet_size){ | 489 if(size != nut->written_packet_size){ |
490 int i; | 490 int i; |
491 | 491 |
492 assert( size <= nut->written_packet_size ); | 492 assert( size <= nut->written_packet_size ); |
493 | 493 |
494 url_fseek(bc, start + 8, SEEK_SET); | 494 url_fseek(bc, start + 8, SEEK_SET); |
495 for(i=get_length(size); i < get_length(nut->written_packet_size); i+=7) | 495 for(i=get_length(size); i < get_length(nut->written_packet_size); i+=7) |
496 put_byte(bc, 0x80); | 496 put_byte(bc, 0x80); |
497 put_v(bc, size); | 497 put_v(bc, size); |
498 | 498 |
499 url_fseek(bc, cur, SEEK_SET); | 499 url_fseek(bc, cur, SEEK_SET); |
500 nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ | 500 nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ |
501 | 501 |
502 if(calculate_checksum) | 502 if(calculate_checksum) |
503 put_be32(bc, get_checksum(bc)); | 503 put_be32(bc, get_checksum(bc)); |
504 } | 504 } |
505 | 505 |
506 return 0; | 506 return 0; |
507 } | 507 } |
508 | 508 |
509 static int nut_write_header(AVFormatContext *s) | 509 static int nut_write_header(AVFormatContext *s) |
510 { | 510 { |
512 ByteIOContext *bc = &s->pb; | 512 ByteIOContext *bc = &s->pb; |
513 AVCodecContext *codec; | 513 AVCodecContext *codec; |
514 int i, j, tmp_time, tmp_flags,tmp_stream, tmp_mul, tmp_size, tmp_fields; | 514 int i, j, tmp_time, tmp_flags,tmp_stream, tmp_mul, tmp_size, tmp_fields; |
515 | 515 |
516 nut->avf= s; | 516 nut->avf= s; |
517 | 517 |
518 nut->stream = | 518 nut->stream = |
519 av_mallocz(sizeof(StreamContext)*s->nb_streams); | 519 av_mallocz(sizeof(StreamContext)*s->nb_streams); |
520 | 520 |
521 | 521 |
522 put_buffer(bc, ID_STRING, strlen(ID_STRING)); | 522 put_buffer(bc, ID_STRING, strlen(ID_STRING)); |
523 put_byte(bc, 0); | 523 put_byte(bc, 0); |
524 nut->packet_start[2]= url_ftell(bc); | 524 nut->packet_start[2]= url_ftell(bc); |
525 | 525 |
526 /* main header */ | 526 /* main header */ |
527 put_be64(bc, MAIN_STARTCODE); | 527 put_be64(bc, MAIN_STARTCODE); |
528 put_packetheader(nut, bc, 120+5*256, 1); | 528 put_packetheader(nut, bc, 120+5*256, 1); |
529 put_v(bc, 2); /* version */ | 529 put_v(bc, 2); /* version */ |
530 put_v(bc, s->nb_streams); | 530 put_v(bc, s->nb_streams); |
531 put_v(bc, MAX_DISTANCE); | 531 put_v(bc, MAX_DISTANCE); |
532 put_v(bc, MAX_SHORT_DISTANCE); | 532 put_v(bc, MAX_SHORT_DISTANCE); |
533 | 533 |
534 put_v(bc, nut->rate_num=1); | 534 put_v(bc, nut->rate_num=1); |
535 put_v(bc, nut->rate_den=2); | 535 put_v(bc, nut->rate_den=2); |
536 put_v(bc, nut->short_startcode=0x4EFE79); | 536 put_v(bc, nut->short_startcode=0x4EFE79); |
537 | 537 |
538 build_frame_code(s); | 538 build_frame_code(s); |
539 assert(nut->frame_code['N'].flags == FLAG_INVALID); | 539 assert(nut->frame_code['N'].flags == FLAG_INVALID); |
540 | 540 |
541 tmp_time= tmp_flags= tmp_stream= tmp_mul= tmp_size= /*tmp_res=*/ INT_MAX; | 541 tmp_time= tmp_flags= tmp_stream= tmp_mul= tmp_size= /*tmp_res=*/ INT_MAX; |
542 for(i=0; i<256;){ | 542 for(i=0; i<256;){ |
543 tmp_fields=0; | 543 tmp_fields=0; |
544 tmp_size= 0; | 544 tmp_size= 0; |
545 if(tmp_time != nut->frame_code[i].timestamp_delta) tmp_fields=1; | 545 if(tmp_time != nut->frame_code[i].timestamp_delta) tmp_fields=1; |
552 tmp_flags = nut->frame_code[i].flags; | 552 tmp_flags = nut->frame_code[i].flags; |
553 tmp_stream= nut->frame_code[i].stream_id_plus1; | 553 tmp_stream= nut->frame_code[i].stream_id_plus1; |
554 tmp_mul = nut->frame_code[i].size_mul; | 554 tmp_mul = nut->frame_code[i].size_mul; |
555 tmp_size = nut->frame_code[i].size_lsb; | 555 tmp_size = nut->frame_code[i].size_lsb; |
556 // tmp_res = nut->frame_code[i].res; | 556 // tmp_res = nut->frame_code[i].res; |
557 | 557 |
558 for(j=0; i<256; j++,i++){ | 558 for(j=0; i<256; j++,i++){ |
559 if(nut->frame_code[i].timestamp_delta != tmp_time ) break; | 559 if(nut->frame_code[i].timestamp_delta != tmp_time ) break; |
560 if(nut->frame_code[i].flags != tmp_flags ) break; | 560 if(nut->frame_code[i].flags != tmp_flags ) break; |
561 if(nut->frame_code[i].stream_id_plus1 != tmp_stream) break; | 561 if(nut->frame_code[i].stream_id_plus1 != tmp_stream) break; |
562 if(nut->frame_code[i].size_mul != tmp_mul ) break; | 562 if(nut->frame_code[i].size_mul != tmp_mul ) break; |
574 if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/); | 574 if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/); |
575 if(tmp_fields>5) put_v(bc, j); | 575 if(tmp_fields>5) put_v(bc, j); |
576 } | 576 } |
577 | 577 |
578 update_packetheader(nut, bc, 0, 1); | 578 update_packetheader(nut, bc, 0, 1); |
579 | 579 |
580 /* stream headers */ | 580 /* stream headers */ |
581 for (i = 0; i < s->nb_streams; i++) | 581 for (i = 0; i < s->nb_streams; i++) |
582 { | 582 { |
583 int nom, denom, ssize; | 583 int nom, denom, ssize; |
584 | 584 |
585 codec = s->streams[i]->codec; | 585 codec = s->streams[i]->codec; |
586 | 586 |
587 put_be64(bc, STREAM_STARTCODE); | 587 put_be64(bc, STREAM_STARTCODE); |
588 put_packetheader(nut, bc, 120 + codec->extradata_size, 1); | 588 put_packetheader(nut, bc, 120 + codec->extradata_size, 1); |
589 put_v(bc, i /*s->streams[i]->index*/); | 589 put_v(bc, i /*s->streams[i]->index*/); |
590 switch(codec->codec_type){ | 590 switch(codec->codec_type){ |
591 case CODEC_TYPE_VIDEO: put_v(bc, 0); break; | 591 case CODEC_TYPE_VIDEO: put_v(bc, 0); break; |
604 { | 604 { |
605 put_vb(bc, codec_get_wav_tag(codec->codec_id)); | 605 put_vb(bc, codec_get_wav_tag(codec->codec_id)); |
606 } | 606 } |
607 else | 607 else |
608 put_vb(bc, 0); | 608 put_vb(bc, 0); |
609 | 609 |
610 ff_parse_specific_params(codec, &nom, &ssize, &denom); | 610 ff_parse_specific_params(codec, &nom, &ssize, &denom); |
611 | 611 |
612 nut->stream[i].rate_num= nom; | 612 nut->stream[i].rate_num= nom; |
613 nut->stream[i].rate_den= denom; | 613 nut->stream[i].rate_den= denom; |
614 av_set_pts_info(s->streams[i], 60, denom, nom); | 614 av_set_pts_info(s->streams[i], 60, denom, nom); |
622 else | 622 else |
623 nut->stream[i].msb_timestamp_shift = 14; | 623 nut->stream[i].msb_timestamp_shift = 14; |
624 put_v(bc, nut->stream[i].msb_timestamp_shift); | 624 put_v(bc, nut->stream[i].msb_timestamp_shift); |
625 put_v(bc, codec->has_b_frames); | 625 put_v(bc, codec->has_b_frames); |
626 put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */ | 626 put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */ |
627 | 627 |
628 if(codec->extradata_size){ | 628 if(codec->extradata_size){ |
629 put_v(bc, 1); | 629 put_v(bc, 1); |
630 put_v(bc, codec->extradata_size); | 630 put_v(bc, codec->extradata_size); |
631 put_buffer(bc, codec->extradata, codec->extradata_size); | 631 put_buffer(bc, codec->extradata, codec->extradata_size); |
632 } | 632 } |
633 put_v(bc, 0); /* end of codec specific headers */ | 633 put_v(bc, 0); /* end of codec specific headers */ |
634 | 634 |
635 switch(codec->codec_type) | 635 switch(codec->codec_type) |
636 { | 636 { |
637 case CODEC_TYPE_AUDIO: | 637 case CODEC_TYPE_AUDIO: |
638 put_v(bc, codec->sample_rate); | 638 put_v(bc, codec->sample_rate); |
639 put_v(bc, 1); | 639 put_v(bc, 1); |
653 } | 653 } |
654 | 654 |
655 /* info header */ | 655 /* info header */ |
656 put_be64(bc, INFO_STARTCODE); | 656 put_be64(bc, INFO_STARTCODE); |
657 put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+ | 657 put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+ |
658 strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1); | 658 strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1); |
659 if (s->author[0]) | 659 if (s->author[0]) |
660 { | 660 { |
661 put_v(bc, 9); /* type */ | 661 put_v(bc, 9); /* type */ |
662 put_str(bc, s->author); | 662 put_str(bc, s->author); |
663 } | 663 } |
679 /* encoder */ | 679 /* encoder */ |
680 if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)){ | 680 if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)){ |
681 put_v(bc, 13); /* type */ | 681 put_v(bc, 13); /* type */ |
682 put_str(bc, LIBAVFORMAT_IDENT); | 682 put_str(bc, LIBAVFORMAT_IDENT); |
683 } | 683 } |
684 | 684 |
685 put_v(bc, 0); /* eof info */ | 685 put_v(bc, 0); /* eof info */ |
686 update_packetheader(nut, bc, 0, 1); | 686 update_packetheader(nut, bc, 0, 1); |
687 | 687 |
688 put_flush_packet(bc); | 688 put_flush_packet(bc); |
689 | 689 |
690 return 0; | 690 return 0; |
691 } | 691 } |
692 | 692 |
693 static int64_t lsb2full(StreamContext *stream, int64_t lsb){ | 693 static int64_t lsb2full(StreamContext *stream, int64_t lsb){ |
694 int64_t mask = (1<<stream->msb_timestamp_shift)-1; | 694 int64_t mask = (1<<stream->msb_timestamp_shift)-1; |
710 int size= pkt->size; | 710 int size= pkt->size; |
711 int stream_index= pkt->stream_index; | 711 int stream_index= pkt->stream_index; |
712 | 712 |
713 enc = s->streams[stream_index]->codec; | 713 enc = s->streams[stream_index]->codec; |
714 key_frame = !!(pkt->flags & PKT_FLAG_KEY); | 714 key_frame = !!(pkt->flags & PKT_FLAG_KEY); |
715 | 715 |
716 frame_type=0; | 716 frame_type=0; |
717 if(frame_start + size + 20 - FFMAX(nut->packet_start[1], nut->packet_start[2]) > MAX_DISTANCE) | 717 if(frame_start + size + 20 - FFMAX(nut->packet_start[1], nut->packet_start[2]) > MAX_DISTANCE) |
718 frame_type=2; | 718 frame_type=2; |
719 if(key_frame && !stream->last_key_frame) | 719 if(key_frame && !stream->last_key_frame) |
720 frame_type=2; | 720 frame_type=2; |
743 size_lsb= nut->frame_code[i].size_lsb; | 743 size_lsb= nut->frame_code[i].size_lsb; |
744 time_delta= nut->frame_code[i].timestamp_delta; | 744 time_delta= nut->frame_code[i].timestamp_delta; |
745 flags= nut->frame_code[i].flags; | 745 flags= nut->frame_code[i].flags; |
746 | 746 |
747 assert(size_mul > size_lsb); | 747 assert(size_mul > size_lsb); |
748 | 748 |
749 if(stream_id_plus1 == 0) length+= get_length(stream_index); | 749 if(stream_id_plus1 == 0) length+= get_length(stream_index); |
750 else if(stream_id_plus1 - 1 != stream_index) | 750 else if(stream_id_plus1 - 1 != stream_index) |
751 continue; | 751 continue; |
752 fc_key_frame= !!(flags & FLAG_KEY_FRAME); | 752 fc_key_frame= !!(flags & FLAG_KEY_FRAME); |
753 | 753 |
762 }else if(size != size_lsb) | 762 }else if(size != size_lsb) |
763 continue; | 763 continue; |
764 | 764 |
765 if(full_pts && time_delta) | 765 if(full_pts && time_delta) |
766 continue; | 766 continue; |
767 | 767 |
768 if(!time_delta){ | 768 if(!time_delta){ |
769 length += get_length(coded_pts); | 769 length += get_length(coded_pts); |
770 }else{ | 770 }else{ |
771 if(time_delta != pts - stream->last_pts) | 771 if(time_delta != pts - stream->last_pts) |
772 continue; | 772 continue; |
807 else | 807 else |
808 assert(size == size_lsb); | 808 assert(size == size_lsb); |
809 if(size > MAX_DISTANCE){ | 809 if(size > MAX_DISTANCE){ |
810 assert(frame_type > 1); | 810 assert(frame_type > 1); |
811 } | 811 } |
812 | 812 |
813 put_buffer(bc, pkt->data, size); | 813 put_buffer(bc, pkt->data, size); |
814 | 814 |
815 update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts); | 815 update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts); |
816 | 816 |
817 return 0; | 817 return 0; |
818 } | 818 } |
819 | 819 |
820 static int nut_write_trailer(AVFormatContext *s) | 820 static int nut_write_trailer(AVFormatContext *s) |
821 { | 821 { |
836 update_packetheader(nut, bc, 0, 1); | 836 update_packetheader(nut, bc, 0, 1); |
837 } | 837 } |
838 #endif | 838 #endif |
839 | 839 |
840 put_flush_packet(bc); | 840 put_flush_packet(bc); |
841 | 841 |
842 av_freep(&nut->stream); | 842 av_freep(&nut->stream); |
843 | 843 |
844 return 0; | 844 return 0; |
845 } | 845 } |
846 #endif //CONFIG_MUXERS | 846 #endif //CONFIG_MUXERS |
861 static int decode_main_header(NUTContext *nut){ | 861 static int decode_main_header(NUTContext *nut){ |
862 AVFormatContext *s= nut->avf; | 862 AVFormatContext *s= nut->avf; |
863 ByteIOContext *bc = &s->pb; | 863 ByteIOContext *bc = &s->pb; |
864 uint64_t tmp; | 864 uint64_t tmp; |
865 int i, j, tmp_stream, tmp_mul, tmp_time, tmp_size, count, tmp_res; | 865 int i, j, tmp_stream, tmp_mul, tmp_time, tmp_size, count, tmp_res; |
866 | 866 |
867 get_packetheader(nut, bc, 1); | 867 get_packetheader(nut, bc, 1); |
868 | 868 |
869 tmp = get_v(bc); | 869 tmp = get_v(bc); |
870 if (tmp != 2){ | 870 if (tmp != 2){ |
871 av_log(s, AV_LOG_ERROR, "bad version (%"PRId64")\n", tmp); | 871 av_log(s, AV_LOG_ERROR, "bad version (%"PRId64")\n", tmp); |
872 return -1; | 872 return -1; |
873 } | 873 } |
874 | 874 |
875 nut->stream_count = get_v(bc); | 875 nut->stream_count = get_v(bc); |
876 if(nut->stream_count > MAX_STREAMS){ | 876 if(nut->stream_count > MAX_STREAMS){ |
877 av_log(s, AV_LOG_ERROR, "too many streams\n"); | 877 av_log(s, AV_LOG_ERROR, "too many streams\n"); |
878 return -1; | 878 return -1; |
879 } | 879 } |
884 nut->short_startcode= get_v(bc); | 884 nut->short_startcode= get_v(bc); |
885 if(nut->short_startcode>>16 != 'N'){ | 885 if(nut->short_startcode>>16 != 'N'){ |
886 av_log(s, AV_LOG_ERROR, "invalid short startcode %X\n", nut->short_startcode); | 886 av_log(s, AV_LOG_ERROR, "invalid short startcode %X\n", nut->short_startcode); |
887 return -1; | 887 return -1; |
888 } | 888 } |
889 | 889 |
890 for(i=0; i<256;){ | 890 for(i=0; i<256;){ |
891 int tmp_flags = get_v(bc); | 891 int tmp_flags = get_v(bc); |
892 int tmp_fields= get_v(bc); | 892 int tmp_fields= get_v(bc); |
893 if(tmp_fields>0) tmp_time = get_s(bc); | 893 if(tmp_fields>0) tmp_time = get_s(bc); |
894 if(tmp_fields>1) tmp_mul = get_v(bc); | 894 if(tmp_fields>1) tmp_mul = get_v(bc); |
897 else tmp_size = 0; | 897 else tmp_size = 0; |
898 if(tmp_fields>4) tmp_res = get_v(bc); | 898 if(tmp_fields>4) tmp_res = get_v(bc); |
899 else tmp_res = 0; | 899 else tmp_res = 0; |
900 if(tmp_fields>5) count = get_v(bc); | 900 if(tmp_fields>5) count = get_v(bc); |
901 else count = tmp_mul - tmp_size; | 901 else count = tmp_mul - tmp_size; |
902 | 902 |
903 while(tmp_fields-- > 6) | 903 while(tmp_fields-- > 6) |
904 get_v(bc); | 904 get_v(bc); |
905 | 905 |
906 if(count == 0 || i+count > 256){ | 906 if(count == 0 || i+count > 256){ |
907 av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); | 907 av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); |
908 return -1; | 908 return -1; |
909 } | 909 } |
910 if(tmp_stream > nut->stream_count + 1){ | 910 if(tmp_stream > nut->stream_count + 1){ |
938 AVFormatContext *s= nut->avf; | 938 AVFormatContext *s= nut->avf; |
939 ByteIOContext *bc = &s->pb; | 939 ByteIOContext *bc = &s->pb; |
940 int class, nom, denom, stream_id; | 940 int class, nom, denom, stream_id; |
941 uint64_t tmp; | 941 uint64_t tmp; |
942 AVStream *st; | 942 AVStream *st; |
943 | 943 |
944 get_packetheader(nut, bc, 1); | 944 get_packetheader(nut, bc, 1); |
945 stream_id= get_v(bc); | 945 stream_id= get_v(bc); |
946 if(stream_id >= nut->stream_count || s->streams[stream_id]) | 946 if(stream_id >= nut->stream_count || s->streams[stream_id]) |
947 return -1; | 947 return -1; |
948 | 948 |
949 st = av_new_stream(s, stream_id); | 949 st = av_new_stream(s, stream_id); |
950 if (!st) | 950 if (!st) |
951 return AVERROR_NOMEM; | 951 return AVERROR_NOMEM; |
952 | 952 |
953 class = get_v(bc); | 953 class = get_v(bc); |
991 while(get_v(bc) != 0){ | 991 while(get_v(bc) != 0){ |
992 st->codec->extradata_size= get_v(bc); | 992 st->codec->extradata_size= get_v(bc); |
993 if((unsigned)st->codec->extradata_size > (1<<30)) | 993 if((unsigned)st->codec->extradata_size > (1<<30)) |
994 return -1; | 994 return -1; |
995 st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); | 995 st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
996 get_buffer(bc, st->codec->extradata, st->codec->extradata_size); | 996 get_buffer(bc, st->codec->extradata, st->codec->extradata_size); |
997 // url_fskip(bc, get_v(bc)); | 997 // url_fskip(bc, get_v(bc)); |
998 } | 998 } |
999 | 999 |
1000 if (st->codec->codec_type == CODEC_TYPE_VIDEO) /* VIDEO */ | 1000 if (st->codec->codec_type == CODEC_TYPE_VIDEO) /* VIDEO */ |
1001 { | 1001 { |
1002 st->codec->width = get_v(bc); | 1002 st->codec->width = get_v(bc); |
1003 st->codec->height = get_v(bc); | 1003 st->codec->height = get_v(bc); |
1004 st->codec->sample_aspect_ratio.num= get_v(bc); | 1004 st->codec->sample_aspect_ratio.num= get_v(bc); |
1022 } | 1022 } |
1023 | 1023 |
1024 static int decode_info_header(NUTContext *nut){ | 1024 static int decode_info_header(NUTContext *nut){ |
1025 AVFormatContext *s= nut->avf; | 1025 AVFormatContext *s= nut->avf; |
1026 ByteIOContext *bc = &s->pb; | 1026 ByteIOContext *bc = &s->pb; |
1027 | 1027 |
1028 get_packetheader(nut, bc, 1); | 1028 get_packetheader(nut, bc, 1); |
1029 | 1029 |
1030 for(;;){ | 1030 for(;;){ |
1031 int id= get_v(bc); | 1031 int id= get_v(bc); |
1032 char *name, *type, custom_name[256], custom_type[256]; | 1032 char *name, *type, custom_name[256], custom_type[256]; |
1048 } | 1048 } |
1049 if(!name){ | 1049 if(!name){ |
1050 get_str(bc, custom_name, sizeof(custom_name)); | 1050 get_str(bc, custom_name, sizeof(custom_name)); |
1051 name= custom_name; | 1051 name= custom_name; |
1052 } | 1052 } |
1053 | 1053 |
1054 if(!strcmp(type, "v")){ | 1054 if(!strcmp(type, "v")){ |
1055 get_v(bc); | 1055 get_v(bc); |
1056 }else{ | 1056 }else{ |
1057 if(!strcmp(name, "Author")) | 1057 if(!strcmp(name, "Author")) |
1058 get_str(bc, s->author, sizeof(s->author)); | 1058 get_str(bc, s->author, sizeof(s->author)); |
1079 ByteIOContext *bc = &s->pb; | 1079 ByteIOContext *bc = &s->pb; |
1080 int64_t pos; | 1080 int64_t pos; |
1081 int inited_stream_count; | 1081 int inited_stream_count; |
1082 | 1082 |
1083 nut->avf= s; | 1083 nut->avf= s; |
1084 | 1084 |
1085 /* main header */ | 1085 /* main header */ |
1086 pos=0; | 1086 pos=0; |
1087 for(;;){ | 1087 for(;;){ |
1088 pos= find_startcode(bc, MAIN_STARTCODE, pos)+1; | 1088 pos= find_startcode(bc, MAIN_STARTCODE, pos)+1; |
1089 if (pos<0){ | 1089 if (pos<0){ |
1091 return -1; | 1091 return -1; |
1092 } | 1092 } |
1093 if(decode_main_header(nut) >= 0) | 1093 if(decode_main_header(nut) >= 0) |
1094 break; | 1094 break; |
1095 } | 1095 } |
1096 | 1096 |
1097 | 1097 |
1098 s->bit_rate = 0; | 1098 s->bit_rate = 0; |
1099 | 1099 |
1100 nut->stream = av_malloc(sizeof(StreamContext)*nut->stream_count); | 1100 nut->stream = av_malloc(sizeof(StreamContext)*nut->stream_count); |
1101 | 1101 |
1102 /* stream headers */ | 1102 /* stream headers */ |
1145 return -1; | 1145 return -1; |
1146 } | 1146 } |
1147 | 1147 |
1148 if(frame_type) | 1148 if(frame_type) |
1149 nut->packet_start[ frame_type ]= frame_start; //otherwise 1 goto 1 may happen | 1149 nut->packet_start[ frame_type ]= frame_start; //otherwise 1 goto 1 may happen |
1150 | 1150 |
1151 flags= nut->frame_code[frame_code].flags; | 1151 flags= nut->frame_code[frame_code].flags; |
1152 size_mul= nut->frame_code[frame_code].size_mul; | 1152 size_mul= nut->frame_code[frame_code].size_mul; |
1153 size_lsb= nut->frame_code[frame_code].size_lsb; | 1153 size_lsb= nut->frame_code[frame_code].size_lsb; |
1154 stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1; | 1154 stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1; |
1155 time_delta= nut->frame_code[frame_code].timestamp_delta; | 1155 time_delta= nut->frame_code[frame_code].timestamp_delta; |
1156 | 1156 |
1157 if(stream_id==-1) | 1157 if(stream_id==-1) |
1158 stream_id= get_v(bc); | 1158 stream_id= get_v(bc); |
1159 if(stream_id >= s->nb_streams){ | 1159 if(stream_id >= s->nb_streams){ |
1160 av_log(s, AV_LOG_ERROR, "illegal stream_id\n"); | 1160 av_log(s, AV_LOG_ERROR, "illegal stream_id\n"); |
1161 return -1; | 1161 return -1; |
1187 } | 1187 } |
1188 | 1188 |
1189 if(*key_frame_ret){ | 1189 if(*key_frame_ret){ |
1190 // av_log(s, AV_LOG_DEBUG, "stream:%d start:%lld pts:%lld length:%lld\n",stream_id, frame_start, av_pts, frame_start - nut->stream[stream_id].last_sync_pos); | 1190 // av_log(s, AV_LOG_DEBUG, "stream:%d start:%lld pts:%lld length:%lld\n",stream_id, frame_start, av_pts, frame_start - nut->stream[stream_id].last_sync_pos); |
1191 av_add_index_entry( | 1191 av_add_index_entry( |
1192 s->streams[stream_id], | 1192 s->streams[stream_id], |
1193 frame_start, | 1193 frame_start, |
1194 pts, | 1194 pts, |
1195 frame_start - nut->stream[stream_id].last_sync_pos, | 1195 frame_start - nut->stream[stream_id].last_sync_pos, |
1196 AVINDEX_KEYFRAME); | 1196 AVINDEX_KEYFRAME); |
1197 nut->stream[stream_id].last_sync_pos= frame_start; | 1197 nut->stream[stream_id].last_sync_pos= frame_start; |
1198 // assert(nut->packet_start == frame_start); | 1198 // assert(nut->packet_start == frame_start); |
1199 } | 1199 } |
1200 | 1200 |
1201 assert(size_mul > size_lsb); | 1201 assert(size_mul > size_lsb); |
1202 size= size_lsb; | 1202 size= size_lsb; |
1203 if(flags & FLAG_DATA_SIZE) | 1203 if(flags & FLAG_DATA_SIZE) |
1204 size+= size_mul*get_v(bc); | 1204 size+= size_mul*get_v(bc); |
1205 | 1205 |
1206 #ifdef TRACE | 1206 #ifdef TRACE |
1207 av_log(s, AV_LOG_DEBUG, "fs:%lld fc:%d ft:%d kf:%d pts:%lld size:%d mul:%d lsb:%d flags:%d delta:%d\n", frame_start, frame_code, frame_type, *key_frame_ret, pts, size, size_mul, size_lsb, flags, time_delta); | 1207 av_log(s, AV_LOG_DEBUG, "fs:%lld fc:%d ft:%d kf:%d pts:%lld size:%d mul:%d lsb:%d flags:%d delta:%d\n", frame_start, frame_code, frame_type, *key_frame_ret, pts, size, size_mul, size_lsb, flags, time_delta); |
1208 #endif | 1208 #endif |
1209 | 1209 |
1210 if(frame_type==0 && url_ftell(bc) - nut->packet_start[2] + size > nut->max_distance){ | 1210 if(frame_type==0 && url_ftell(bc) - nut->packet_start[2] + size > nut->max_distance){ |
1211 av_log(s, AV_LOG_ERROR, "frame size too large\n"); | 1211 av_log(s, AV_LOG_ERROR, "frame size too large\n"); |
1212 return -1; | 1212 return -1; |
1213 } | 1213 } |
1214 | 1214 |
1215 *stream_id_ret = stream_id; | 1215 *stream_id_ret = stream_id; |
1216 *pts_ret = pts; | 1216 *pts_ret = pts; |
1217 | 1217 |
1218 update(nut, stream_id, frame_start, frame_type, frame_code, *key_frame_ret, size, pts); | 1218 update(nut, stream_id, frame_start, frame_type, frame_code, *key_frame_ret, size, pts); |
1219 | 1219 |
1223 static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type, int64_t frame_start){ | 1223 static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type, int64_t frame_start){ |
1224 AVFormatContext *s= nut->avf; | 1224 AVFormatContext *s= nut->avf; |
1225 ByteIOContext *bc = &s->pb; | 1225 ByteIOContext *bc = &s->pb; |
1226 int size, stream_id, key_frame, discard; | 1226 int size, stream_id, key_frame, discard; |
1227 int64_t pts, last_IP_pts; | 1227 int64_t pts, last_IP_pts; |
1228 | 1228 |
1229 size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, frame_start); | 1229 size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, frame_start); |
1230 if(size < 0) | 1230 if(size < 0) |
1231 return -1; | 1231 return -1; |
1232 | 1232 |
1233 discard= s->streams[ stream_id ]->discard; | 1233 discard= s->streams[ stream_id ]->discard; |
1334 return AV_NOPTS_VALUE; | 1334 return AV_NOPTS_VALUE; |
1335 | 1335 |
1336 url_fseek(bc, -8, SEEK_CUR); | 1336 url_fseek(bc, -8, SEEK_CUR); |
1337 for(i=0; i<s->nb_streams; i++) | 1337 for(i=0; i<s->nb_streams; i++) |
1338 nut->stream[i].last_sync_pos= url_ftell(bc); | 1338 nut->stream[i].last_sync_pos= url_ftell(bc); |
1339 | 1339 |
1340 for(;;){ | 1340 for(;;){ |
1341 int frame_type=0; | 1341 int frame_type=0; |
1342 int64_t pos= url_ftell(bc); | 1342 int64_t pos= url_ftell(bc); |
1343 uint64_t tmp=0; | 1343 uint64_t tmp=0; |
1344 | 1344 |
1345 if(pos > pos_limit || url_feof(bc)) | 1345 if(pos > pos_limit || url_feof(bc)) |
1346 return AV_NOPTS_VALUE; | 1346 return AV_NOPTS_VALUE; |
1347 | 1347 |
1348 frame_code = get_byte(bc); | 1348 frame_code = get_byte(bc); |
1349 if(frame_code == 'N'){ | 1349 if(frame_code == 'N'){ |
1368 frame_code = get_byte(bc); | 1368 frame_code = get_byte(bc); |
1369 case 0: | 1369 case 0: |
1370 size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, pos); | 1370 size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, pos); |
1371 if(size < 0) | 1371 if(size < 0) |
1372 goto resync; | 1372 goto resync; |
1373 | 1373 |
1374 stream= &nut->stream[stream_id]; | 1374 stream= &nut->stream[stream_id]; |
1375 if(stream_id != stream_index || !key_frame || pos < *pos_arg){ | 1375 if(stream_id != stream_index || !key_frame || pos < *pos_arg){ |
1376 url_fseek(bc, size, SEEK_CUR); | 1376 url_fseek(bc, size, SEEK_CUR); |
1377 break; | 1377 break; |
1378 } | 1378 } |
1379 | 1379 |
1380 *pos_arg= pos; | 1380 *pos_arg= pos; |
1381 return pts; | 1381 return pts; |
1382 default: | 1382 default: |
1383 resync: | 1383 resync: |
1384 av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", nut->packet_start[2]+1); | 1384 av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", nut->packet_start[2]+1); |