comparison nut.c @ 418:41da3366d341 libavformat

checksuming for nut & nice checksum API for libavformat
author michael
date Mon, 05 Apr 2004 12:02:10 +0000
parents e26aacf263be
children 51c25922a543
comparison
equal deleted inserted replaced
417:5a89e49ff688 418:41da3366d341
23 * 23 *
24 */ 24 */
25 25
26 /* 26 /*
27 * TODO: 27 * TODO:
28 * - checksumming
29 * - seeking 28 * - seeking
30 * - index writing 29 * - index writing
31 * - index packet reading support 30 * - index packet reading support
32 * - startcode searching for broken streams 31 * - startcode searching for broken streams
33 */ 32 */
282 return -1; 281 return -1;
283 else 282 else
284 return 0; 283 return 0;
285 } 284 }
286 285
287 static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int prefix_length) 286 static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int prefix_length, int calculate_checksum)
288 { 287 {
289 int64_t start, size, last_size; 288 int64_t start, size, last_size;
290 start= url_ftell(bc) - prefix_length; 289 start= url_ftell(bc) - prefix_length;
291 290
292 if(start != nut->packet_start + nut->written_packet_size){ 291 if(start != nut->packet_start + nut->written_packet_size){
293 av_log(nut->avf, AV_LOG_ERROR, "get_packetheader called at weird position\n"); 292 av_log(nut->avf, AV_LOG_ERROR, "get_packetheader called at weird position\n");
294 return -1; 293 return -1;
295 } 294 }
295
296 if(calculate_checksum)
297 init_checksum(bc, update_adler32, 0);
296 298
297 size= get_v(bc); 299 size= get_v(bc);
298 last_size= get_v(bc); 300 last_size= get_v(bc);
299 if(nut->written_packet_size != last_size){ 301 if(nut->written_packet_size != last_size){
300 av_log(nut->avf, AV_LOG_ERROR, "packet size missmatch %d != %lld at %lld\n", nut->written_packet_size, last_size, start); 302 av_log(nut->avf, AV_LOG_ERROR, "packet size missmatch %d != %lld at %lld\n", nut->written_packet_size, last_size, start);
306 nut->written_packet_size= size; 308 nut->written_packet_size= size;
307 309
308 return size; 310 return size;
309 } 311 }
310 312
313 static int check_checksum(ByteIOContext *bc){
314 unsigned long checksum= get_checksum(bc);
315 return checksum != get_be32(bc);
316 }
317
311 /** 318 /**
312 * 319 *
313 */ 320 */
314 static int get_length(uint64_t val){ 321 static int get_length(uint64_t val){
315 int i; 322 int i;
350 put_buffer(bc, string, len); 357 put_buffer(bc, string, len);
351 358
352 return 0; 359 return 0;
353 } 360 }
354 361
355 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size) 362 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size, int calculate_checksum)
356 { 363 {
357 put_flush_packet(bc); 364 put_flush_packet(bc);
358 nut->last_packet_start= nut->packet_start; 365 nut->last_packet_start= nut->packet_start;
359 nut->packet_start+= nut->written_packet_size; 366 nut->packet_start+= nut->written_packet_size;
360 nut->packet_size_pos = url_ftell(bc); 367 nut->packet_size_pos = url_ftell(bc);
361 nut->written_packet_size = max_size; 368 nut->written_packet_size = max_size;
369
370 if(calculate_checksum)
371 init_checksum(bc, update_adler32, 0);
362 372
363 /* packet header */ 373 /* packet header */
364 put_v(bc, nut->written_packet_size); /* forward ptr */ 374 put_v(bc, nut->written_packet_size); /* forward ptr */
365 put_v(bc, nut->packet_start - nut->last_packet_start); /* backward ptr */ 375 put_v(bc, nut->packet_start - nut->last_packet_start); /* backward ptr */
366 376
367 return 0; 377 return 0;
368 } 378 }
369 379
370 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size){ 380 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size, int calculate_checksum){
371 int64_t start= nut->packet_start; 381 int64_t start= nut->packet_start;
372 int64_t cur= url_ftell(bc); 382 int64_t cur= url_ftell(bc);
373 int size= cur - start + additional_size; 383 int size= cur - start + additional_size;
384
385 if(calculate_checksum)
386 size += 4;
374 387
375 if(size != nut->written_packet_size){ 388 if(size != nut->written_packet_size){
376 int i; 389 int i;
377 390
378 assert( size <= nut->written_packet_size ); 391 assert( size <= nut->written_packet_size );
382 put_byte(bc, 0x80); 395 put_byte(bc, 0x80);
383 put_v(bc, size); 396 put_v(bc, size);
384 397
385 url_fseek(bc, cur, SEEK_SET); 398 url_fseek(bc, cur, SEEK_SET);
386 nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ 399 nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ
400
401 if(calculate_checksum)
402 put_be32(bc, get_checksum(bc));
387 } 403 }
388 404
389 return 0; 405 return 0;
390 } 406 }
391 407
403 419
404 av_set_pts_info(s, 60, 1, AV_TIME_BASE); 420 av_set_pts_info(s, 60, 1, AV_TIME_BASE);
405 421
406 /* main header */ 422 /* main header */
407 put_be64(bc, MAIN_STARTCODE); 423 put_be64(bc, MAIN_STARTCODE);
408 put_packetheader(nut, bc, 120+5*256); 424 put_packetheader(nut, bc, 120+5*256, 1);
409 put_v(bc, 1); /* version */ 425 put_v(bc, 1); /* version */
410 put_v(bc, s->nb_streams); 426 put_v(bc, s->nb_streams);
411 put_v(bc, 3); /* checksum threshold */ 427 put_v(bc, 3);
412 428
413 build_frame_code(s); 429 build_frame_code(s);
414 assert(nut->frame_code['N'].flags == 1); 430 assert(nut->frame_code['N'].flags == 1);
415 for(i=0; i<256;){ 431 for(i=0; i<256;){
416 int tmp_flags = nut->frame_code[i].flags; 432 int tmp_flags = nut->frame_code[i].flags;
433 } 449 }
434 } 450 }
435 put_v(bc, j); 451 put_v(bc, j);
436 } 452 }
437 453
438 put_be32(bc, 0); /* FIXME: checksum */ 454 update_packetheader(nut, bc, 0, 1);
439
440 update_packetheader(nut, bc, 0);
441 455
442 /* stream headers */ 456 /* stream headers */
443 for (i = 0; i < s->nb_streams; i++) 457 for (i = 0; i < s->nb_streams; i++)
444 { 458 {
445 int nom, denom, gcd; 459 int nom, denom, gcd;
446 460
447 codec = &s->streams[i]->codec; 461 codec = &s->streams[i]->codec;
448 462
449 put_be64(bc, STREAM_STARTCODE); 463 put_be64(bc, STREAM_STARTCODE);
450 put_packetheader(nut, bc, 120 + codec->extradata_size); 464 put_packetheader(nut, bc, 120 + codec->extradata_size, 1);
451 put_v(bc, i /*s->streams[i]->index*/); 465 put_v(bc, i /*s->streams[i]->index*/);
452 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0); 466 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);
453 if (codec->codec_tag) 467 if (codec->codec_tag)
454 put_v(bc, codec->codec_tag); 468 put_v(bc, codec->codec_tag);
455 else if (codec->codec_type == CODEC_TYPE_VIDEO) 469 else if (codec->codec_type == CODEC_TYPE_VIDEO)
518 put_v(bc, 0); /* csp type -- unknown */ 532 put_v(bc, 0); /* csp type -- unknown */
519 break; 533 break;
520 default: 534 default:
521 break; 535 break;
522 } 536 }
523 put_be32(bc, 0); /* FIXME: checksum */ 537 update_packetheader(nut, bc, 0, 1);
524 update_packetheader(nut, bc, 0);
525 } 538 }
526 539
527 /* info header */ 540 /* info header */
528 put_be64(bc, INFO_STARTCODE); 541 put_be64(bc, INFO_STARTCODE);
529 put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+ 542 put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+
530 strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT)); 543 strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1);
531 if (s->author[0]) 544 if (s->author[0])
532 { 545 {
533 put_v(bc, 9); /* type */ 546 put_v(bc, 9); /* type */
534 put_str(bc, s->author); 547 put_str(bc, s->author);
535 } 548 }
551 /* encoder */ 564 /* encoder */
552 put_v(bc, 13); /* type */ 565 put_v(bc, 13); /* type */
553 put_str(bc, LIBAVFORMAT_IDENT); 566 put_str(bc, LIBAVFORMAT_IDENT);
554 567
555 put_v(bc, 0); /* eof info */ 568 put_v(bc, 0); /* eof info */
556 569 update_packetheader(nut, bc, 0, 1);
557 put_be32(bc, 0); /* FIXME: checksum */
558 update_packetheader(nut, bc, 0);
559 570
560 put_flush_packet(bc); 571 put_flush_packet(bc);
561 572
562 return 0; 573 return 0;
563 } 574 }
592 if(!stream->last_key_frame) 603 if(!stream->last_key_frame)
593 frame_type=2; 604 frame_type=2;
594 } 605 }
595 606
596 if(frame_type>0){ 607 if(frame_type>0){
597 update_packetheader(nut, bc, 0); 608 update_packetheader(nut, bc, 0, 0);
598 reset(s); 609 reset(s);
599 full_pts=1; 610 full_pts=1;
600 } 611 }
601 //FIXME ensure that the timestamp can be represented by either delta or lsb or full_pts=1 612 //FIXME ensure that the timestamp can be represented by either delta or lsb or full_pts=1
602 613
682 if (frame_type==2) 693 if (frame_type==2)
683 put_be64(bc, KEYFRAME_STARTCODE); 694 put_be64(bc, KEYFRAME_STARTCODE);
684 put_byte(bc, frame_code); 695 put_byte(bc, frame_code);
685 696
686 if(frame_type>0) 697 if(frame_type>0)
687 put_packetheader(nut, bc, FFMAX(size+20, MAX_TYPE1_DISTANCE)); 698 put_packetheader(nut, bc, FFMAX(size+20, MAX_TYPE1_DISTANCE), 0);
688 if(nut->frame_code[frame_code].stream_id_plus1 == 0) 699 if(nut->frame_code[frame_code].stream_id_plus1 == 0)
689 put_v(bc, stream_index); 700 put_v(bc, stream_index);
690 if (flags & FLAG_PTS){ 701 if (flags & FLAG_PTS){
691 if (flags & FLAG_FULL_PTS) 702 if (flags & FLAG_FULL_PTS)
692 put_v(bc, pts); 703 put_v(bc, pts);
695 } 706 }
696 if(flags & FLAG_DATA_SIZE) 707 if(flags & FLAG_DATA_SIZE)
697 put_v(bc, size / size_mul); 708 put_v(bc, size / size_mul);
698 if(size > MAX_TYPE1_DISTANCE){ 709 if(size > MAX_TYPE1_DISTANCE){
699 assert(frame_type > 0); 710 assert(frame_type > 0);
700 update_packetheader(nut, bc, size); 711 update_packetheader(nut, bc, size, 0);
701 } 712 }
702 713
703 put_buffer(bc, buf, size); 714 put_buffer(bc, buf, size);
704 715
705 update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts); 716 update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts);
710 static int nut_write_trailer(AVFormatContext *s) 721 static int nut_write_trailer(AVFormatContext *s)
711 { 722 {
712 NUTContext *nut = s->priv_data; 723 NUTContext *nut = s->priv_data;
713 ByteIOContext *bc = &s->pb; 724 ByteIOContext *bc = &s->pb;
714 725
715 update_packetheader(nut, bc, 0); 726 update_packetheader(nut, bc, 0, 0);
716 727
717 #if 0 728 #if 0
718 int i; 729 int i;
719 730
720 /* WRITE INDEX */ 731 /* WRITE INDEX */
721 732
722 for (i = 0; s->nb_streams; i++) 733 for (i = 0; s->nb_streams; i++)
723 { 734 {
724 put_be64(bc, INDEX_STARTCODE); 735 put_be64(bc, INDEX_STARTCODE);
725 put_packetheader(nut, bc, 64); 736 put_packetheader(nut, bc, 64, 1);
726 put_v(bc, s->streams[i]->id); 737 put_v(bc, s->streams[i]->id);
727 put_v(bc, ...); 738 put_v(bc, ...);
728 put_be32(bc, 0); /* FIXME: checksum */ 739 update_packetheader(nut, bc, 0, 1);
729 update_packetheader(nut, bc, 0);
730 } 740 }
731 #endif 741 #endif
732 742
733 put_flush_packet(bc); 743 put_flush_packet(bc);
734 744
766 776
767 /* main header */ 777 /* main header */
768 tmp = get_be64(bc); 778 tmp = get_be64(bc);
769 if (tmp != MAIN_STARTCODE) 779 if (tmp != MAIN_STARTCODE)
770 av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp); 780 av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp);
771 get_packetheader(nut, bc, 8); 781 get_packetheader(nut, bc, 8, 1);
772 782
773 tmp = get_v(bc); 783 tmp = get_v(bc);
774 if (tmp != 1) 784 if (tmp != 1)
775 av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp); 785 av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp);
776 786
819 if(nut->frame_code['N'].flags != 1){ 829 if(nut->frame_code['N'].flags != 1){
820 av_log(s, AV_LOG_ERROR, "illegal frame_code table\n"); 830 av_log(s, AV_LOG_ERROR, "illegal frame_code table\n");
821 return -1; 831 return -1;
822 } 832 }
823 833
824 get_be32(bc); /* checkusm */ 834 if(check_checksum(bc)){
835 av_log(s, AV_LOG_ERROR, "Main header checksum missmatch\n");
836 return -1;
837 }
825 838
826 s->bit_rate = 0; 839 s->bit_rate = 0;
827 840
828 nut->stream = av_malloc(sizeof(StreamContext)*nb_streams); 841 nut->stream = av_malloc(sizeof(StreamContext)*nb_streams);
829 842
834 AVStream *st; 847 AVStream *st;
835 848
836 tmp = get_be64(bc); 849 tmp = get_be64(bc);
837 if (tmp != STREAM_STARTCODE) 850 if (tmp != STREAM_STARTCODE)
838 av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp); 851 av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp);
839 get_packetheader(nut, bc, 8); 852 get_packetheader(nut, bc, 8, 1);
840 st = av_new_stream(s, get_v(bc)); 853 st = av_new_stream(s, get_v(bc));
841 if (!st) 854 if (!st)
842 return AVERROR_NOMEM; 855 return AVERROR_NOMEM;
843 class = get_v(bc); 856 class = get_v(bc);
844 tmp = get_v(bc); 857 tmp = get_v(bc);
893 if (class == 32) /* AUDIO */ 906 if (class == 32) /* AUDIO */
894 { 907 {
895 st->codec.sample_rate = (get_v(bc) * nom) / denom; 908 st->codec.sample_rate = (get_v(bc) * nom) / denom;
896 st->codec.channels = get_v(bc); 909 st->codec.channels = get_v(bc);
897 } 910 }
898 get_be32(bc); /* checksum */ 911 if(check_checksum(bc)){
912 av_log(s, AV_LOG_ERROR, "Stream header %d checksum missmatch\n", cur_stream);
913 return -1;
914 }
899 nut->stream[cur_stream].rate_num= nom; 915 nut->stream[cur_stream].rate_num= nom;
900 nut->stream[cur_stream].rate_den= denom; 916 nut->stream[cur_stream].rate_den= denom;
901 } 917 }
902 918
903 tmp = get_be64(bc); 919 tmp = get_be64(bc);
904 if (tmp == INFO_STARTCODE){ 920 if (tmp == INFO_STARTCODE){
905 get_packetheader(nut, bc, 8); 921 get_packetheader(nut, bc, 8, 1);
906 922
907 for(;;){ 923 for(;;){
908 int id= get_v(bc); 924 int id= get_v(bc);
909 char *name, *type, custom_name[256], custom_type[256]; 925 char *name, *type, custom_name[256], custom_type[256];
910 926
941 get_str(bc, s->comment, sizeof(s->comment)); 957 get_str(bc, s->comment, sizeof(s->comment));
942 else 958 else
943 get_str(bc, NULL, 0); 959 get_str(bc, NULL, 0);
944 } 960 }
945 } 961 }
946 get_be32(bc); /* checksum */ 962 if(check_checksum(bc)){
963 av_log(s, AV_LOG_ERROR, "Info header checksum missmatch\n");
964 }
947 }else 965 }else
948 url_fseek(bc, -8, SEEK_CUR); 966 url_fseek(bc, -8, SEEK_CUR);
949 967
950 return 0; 968 return 0;
951 } 969 }
984 stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1; 1002 stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1;
985 1003
986 if(flags & FLAG_FRAME_TYPE){ 1004 if(flags & FLAG_FRAME_TYPE){
987 reset(s); 1005 reset(s);
988 if(frame_type==2){ 1006 if(frame_type==2){
989 get_packetheader(nut, bc, 8+1); 1007 get_packetheader(nut, bc, 8+1, 0);
990 }else{ 1008 }else{
991 get_packetheader(nut, bc, 1); 1009 get_packetheader(nut, bc, 1, 0);
992 frame_type= 1; 1010 frame_type= 1;
993 } 1011 }
994 } 1012 }
995 1013
996 if(stream_id==-1) 1014 if(stream_id==-1)