Mercurial > mplayer.hg
comparison libmpdemux/realrtsp/real.c @ 12266:096072d234c6
Some sanity and bound checking
author | rtognimp |
---|---|
date | Sat, 24 Apr 2004 10:33:19 +0000 |
parents | 95413c6d76a0 |
children | 4adb4a3b52a2 |
comparison
equal
deleted
inserted
replaced
12265:c9e1fe032d10 | 12266:096072d234c6 |
---|---|
33 #include "../config.h" | 33 #include "../config.h" |
34 #include "../bswap.h" | 34 #include "../bswap.h" |
35 #include "real.h" | 35 #include "real.h" |
36 #include "asmrp.h" | 36 #include "asmrp.h" |
37 #include "sdpplin.h" | 37 #include "sdpplin.h" |
38 #include "xbuffer.h" | |
38 | 39 |
39 /* | 40 /* |
40 #define LOG | 41 #define LOG |
41 */ | 42 */ |
42 | 43 |
420 /* | 421 /* |
421 * takes a MLTI-Chunk and a rule number got from match_asm_rule, | 422 * takes a MLTI-Chunk and a rule number got from match_asm_rule, |
422 * returns a pointer to selected data and number of bytes in that. | 423 * returns a pointer to selected data and number of bytes in that. |
423 */ | 424 */ |
424 | 425 |
425 static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char *out) { | 426 static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { |
426 | 427 |
427 int numrules, codec, size; | 428 int numrules, codec, size; |
428 int i; | 429 int i; |
429 | 430 |
430 /* MLTI chunk should begin with MLTI */ | 431 /* MLTI chunk should begin with MLTI */ |
435 ||(mlti_chunk[3] != 'I')) | 436 ||(mlti_chunk[3] != 'I')) |
436 { | 437 { |
437 #ifdef LOG | 438 #ifdef LOG |
438 printf("libreal: MLTI tag not detected, copying data\n"); | 439 printf("libreal: MLTI tag not detected, copying data\n"); |
439 #endif | 440 #endif |
440 memcpy(out, mlti_chunk, mlti_size); | 441 *out = xbuffer_copyin(*out, 0, mlti_chunk, mlti_size); |
441 return mlti_size; | 442 return mlti_size; |
442 } | 443 } |
443 | 444 |
444 mlti_chunk+=4; | 445 mlti_chunk+=4; |
445 | 446 |
476 size=BE_32(mlti_chunk); | 477 size=BE_32(mlti_chunk); |
477 | 478 |
478 #ifdef LOG | 479 #ifdef LOG |
479 hexdump(mlti_chunk+4, size); | 480 hexdump(mlti_chunk+4, size); |
480 #endif | 481 #endif |
481 memcpy(out,mlti_chunk+4, size); | 482 *out = xbuffer_copyin(*out, 0, mlti_chunk+4, size); |
482 return size; | 483 return size; |
483 } | 484 } |
484 | 485 |
485 /* | 486 /* |
486 * looking at stream description. | 487 * looking at stream description. |
487 */ | 488 */ |
488 | 489 |
489 rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth) { | 490 rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { |
490 | 491 |
491 sdpplin_t *desc; | 492 sdpplin_t *desc; |
492 rmff_header_t *header; | 493 rmff_header_t *header; |
493 char buf[2048]; | 494 char *buf; |
494 int len, i; | 495 int len, i; |
495 int max_bit_rate=0; | 496 int max_bit_rate=0; |
496 int avg_bit_rate=0; | 497 int avg_bit_rate=0; |
497 int max_packet_size=0; | 498 int max_packet_size=0; |
498 int avg_packet_size=0; | 499 int avg_packet_size=0; |
503 | 504 |
504 desc=sdpplin_parse(data); | 505 desc=sdpplin_parse(data); |
505 | 506 |
506 if (!desc) return NULL; | 507 if (!desc) return NULL; |
507 | 508 |
509 buf = xbuffer_init(2048); | |
508 header=calloc(1,sizeof(rmff_header_t)); | 510 header=calloc(1,sizeof(rmff_header_t)); |
509 | 511 |
510 header->fileheader=rmff_new_fileheader(4+desc->stream_count); | 512 header->fileheader=rmff_new_fileheader(4+desc->stream_count); |
511 header->cont=rmff_new_cont( | 513 header->cont=rmff_new_cont( |
512 desc->title, | 514 desc->title, |
533 for (j=0; j<n; j++) { | 535 for (j=0; j<n; j++) { |
534 #ifdef LOG | 536 #ifdef LOG |
535 printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); | 537 printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); |
536 #endif | 538 #endif |
537 sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); | 539 sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); |
538 strcat(stream_rules, b); | 540 *stream_rules = xbuffer_strcat(*stream_rules, b); |
539 } | 541 } |
540 | 542 |
541 if (!desc->stream[i]->mlti_data) return NULL; | 543 if (!desc->stream[i]->mlti_data) return NULL; |
542 | 544 |
543 len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], buf); | 545 len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf); |
544 | 546 |
545 header->streams[i]=rmff_new_mdpr( | 547 header->streams[i]=rmff_new_mdpr( |
546 desc->stream[i]->stream_id, | 548 desc->stream[i]->stream_id, |
547 desc->stream[i]->max_bit_rate, | 549 desc->stream[i]->max_bit_rate, |
548 desc->stream[i]->avg_bit_rate, | 550 desc->stream[i]->avg_bit_rate, |
564 avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; | 566 avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; |
565 else | 567 else |
566 avg_packet_size=desc->stream[i]->avg_packet_size; | 568 avg_packet_size=desc->stream[i]->avg_packet_size; |
567 } | 569 } |
568 | 570 |
569 if (stream_rules) | 571 if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') |
570 stream_rules[strlen(stream_rules)-1]=0; /* delete last ',' in stream_rules */ | 572 (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ |
571 | 573 |
572 header->prop=rmff_new_prop( | 574 header->prop=rmff_new_prop( |
573 max_bit_rate, | 575 max_bit_rate, |
574 avg_bit_rate, | 576 avg_bit_rate, |
575 max_packet_size, | 577 max_packet_size, |
581 0, | 583 0, |
582 desc->stream_count, | 584 desc->stream_count, |
583 desc->flags); | 585 desc->flags); |
584 | 586 |
585 rmff_fix_header(header); | 587 rmff_fix_header(header); |
588 buf = xbuffer_free(buf); | |
586 | 589 |
587 return header; | 590 return header; |
588 } | 591 } |
589 | 592 |
590 int real_get_rdt_chunk(rtsp_t *rtsp_session, char *buffer) { | 593 int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer) { |
591 | 594 |
592 int n=1; | 595 int n=1; |
593 uint8_t header[8]; | 596 uint8_t header[8]; |
594 rmff_pheader_t ph; | 597 rmff_pheader_t ph; |
595 int size; | 598 int size; |
651 prev_stream_number = ph.stream_number; | 654 prev_stream_number = ph.stream_number; |
652 ph.flags=2; | 655 ph.flags=2; |
653 } | 656 } |
654 else | 657 else |
655 ph.flags=0; | 658 ph.flags=0; |
656 rmff_dump_pheader(&ph, buffer); | 659 *buffer = xbuffer_ensure_size(*buffer, 12+size); |
660 rmff_dump_pheader(&ph, *buffer); | |
657 size-=12; | 661 size-=12; |
658 n=rtsp_read_data(rtsp_session, buffer+12, size); | 662 n=rtsp_read_data(rtsp_session, (*buffer)+12, size); |
659 | 663 |
660 return n+12; | 664 return n+12; |
661 } | 665 } |
662 | 666 |
663 int convert_timestamp(char *str, int *sec, int *msec) { | 667 int convert_timestamp(char *str, int *sec, int *msec) { |
685 char *session_id=NULL; | 689 char *session_id=NULL; |
686 rmff_header_t *h; | 690 rmff_header_t *h; |
687 char *challenge1; | 691 char *challenge1; |
688 char challenge2[64]; | 692 char challenge2[64]; |
689 char checksum[34]; | 693 char checksum[34]; |
690 char subscribe[256]; | 694 char *subscribe; |
691 char buf[256]; | 695 char *buf = xbuffer_init(256); |
692 char *mrl=rtsp_get_mrl(rtsp_session); | 696 char *mrl=rtsp_get_mrl(rtsp_session); |
693 unsigned int size; | 697 unsigned int size; |
694 int status; | 698 int status; |
695 | 699 |
696 /* get challenge */ | 700 /* get challenge */ |
716 char *alert=rtsp_search_answers(rtsp_session,"Alert"); | 720 char *alert=rtsp_search_answers(rtsp_session,"Alert"); |
717 if (alert) { | 721 if (alert) { |
718 printf("real: got message from server:\n%s\n", alert); | 722 printf("real: got message from server:\n%s\n", alert); |
719 } | 723 } |
720 rtsp_send_ok(rtsp_session); | 724 rtsp_send_ok(rtsp_session); |
725 buf = xbuffer_free(buf); | |
721 return NULL; | 726 return NULL; |
722 } | 727 } |
723 | 728 |
724 /* receive description */ | 729 /* receive description */ |
725 size=0; | 730 size=0; |
741 | 746 |
742 rtsp_read_data(rtsp_session, description, size); | 747 rtsp_read_data(rtsp_session, description, size); |
743 description[size]=0; | 748 description[size]=0; |
744 | 749 |
745 /* parse sdp (sdpplin) and create a header and a subscribe string */ | 750 /* parse sdp (sdpplin) and create a header and a subscribe string */ |
751 subscribe = xbuffer_init(256); | |
746 strcpy(subscribe, "Subscribe: "); | 752 strcpy(subscribe, "Subscribe: "); |
747 h=real_parse_sdp(description, subscribe+11, bandwidth); | 753 h=real_parse_sdp(description, &subscribe, bandwidth); |
748 if (!h) return NULL; | 754 if (!h) { |
755 subscribe = xbuffer_free(subscribe); | |
756 buf = xbuffer_free(buf); | |
757 return NULL; | |
758 } | |
749 rmff_fix_header(h); | 759 rmff_fix_header(h); |
750 | 760 |
751 #ifdef LOG | 761 #ifdef LOG |
752 printf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", | 762 printf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", |
753 h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); | 763 h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); |
754 #endif | 764 #endif |
755 | 765 |
756 /* setup our streams */ | 766 /* setup our streams */ |
757 real_calc_response_and_checksum (challenge2, checksum, challenge1); | 767 real_calc_response_and_checksum (challenge2, checksum, challenge1); |
768 buf = xbuffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32); | |
758 sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); | 769 sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); |
759 rtsp_schedule_field(rtsp_session, buf); | 770 rtsp_schedule_field(rtsp_session, buf); |
771 buf = xbuffer_ensure_size(buf, strlen(session_id) + 32); | |
760 sprintf(buf, "If-Match: %s", session_id); | 772 sprintf(buf, "If-Match: %s", session_id); |
761 rtsp_schedule_field(rtsp_session, buf); | 773 rtsp_schedule_field(rtsp_session, buf); |
762 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); | 774 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); |
775 buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); | |
763 sprintf(buf, "%s/streamid=0", mrl); | 776 sprintf(buf, "%s/streamid=0", mrl); |
764 rtsp_request_setup(rtsp_session,buf); | 777 rtsp_request_setup(rtsp_session,buf); |
765 | 778 |
766 if (h->prop->num_streams > 1) { | 779 if (h->prop->num_streams > 1) { |
767 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); | 780 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); |
781 buf = xbuffer_ensure_size(buf, strlen(session_id) + 32); | |
768 sprintf(buf, "If-Match: %s", session_id); | 782 sprintf(buf, "If-Match: %s", session_id); |
769 rtsp_schedule_field(rtsp_session, buf); | 783 rtsp_schedule_field(rtsp_session, buf); |
770 | 784 |
785 buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); | |
771 sprintf(buf, "%s/streamid=1", mrl); | 786 sprintf(buf, "%s/streamid=1", mrl); |
772 rtsp_request_setup(rtsp_session,buf); | 787 rtsp_request_setup(rtsp_session,buf); |
773 } | 788 } |
774 /* set stream parameter (bandwidth) with our subscribe string */ | 789 /* set stream parameter (bandwidth) with our subscribe string */ |
775 rtsp_schedule_field(rtsp_session, subscribe); | 790 rtsp_schedule_field(rtsp_session, subscribe); |
792 } | 807 } |
793 rtsp_schedule_field(rtsp_session, buf); | 808 rtsp_schedule_field(rtsp_session, buf); |
794 /* and finally send a play request */ | 809 /* and finally send a play request */ |
795 rtsp_request_play(rtsp_session,NULL); | 810 rtsp_request_play(rtsp_session,NULL); |
796 | 811 |
812 subscribe = xbuffer_free(subscribe); | |
813 buf = xbuffer_free(buf); | |
797 return h; | 814 return h; |
798 } | 815 } |