Changeset 268ff7ea8eff7f6901f46c9b2e4f76b6f02c2cba
- Timestamp:
- 09/25/05 20:25:57 (3 years ago)
- git-parent:
- Files:
-
- modules/access/rtsp/real.c (modified) (6 diffs)
- modules/access/rtsp/real_rmff.c (modified) (2 diffs)
- modules/access/rtsp/real_sdpplin.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
modules/access/rtsp/real.c
r880f95f r268ff7e 93 93 b = ((c & d) | (~c & a)) + LE_32((param+0x3c)) + b + 0x49B40821; 94 94 b = ((b << 0x16) | (b >> 0x0a)) + c; 95 95 96 96 a = ((b & d) | (~d & c)) + LE_32((param+0x04)) + a - 0x09E1DA9E; 97 97 a = ((a << 0x05) | (a >> 0x1b)) + b; … … 248 248 } 249 249 250 static void calc_response (char *result, char *field) 251 { 250 static void calc_response (char *result, char *field) { 252 251 char buf1[128]; 253 252 char buf2[128]; … … 274 273 } 275 274 276 277 static void calc_response_string (char *result, char *challenge) 278 { 275 static void calc_response_string (char *result, char *challenge) { 279 276 char field[128]; 280 277 char zres[20]; … … 305 302 } 306 303 307 void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) 308 { 304 void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) { 305 309 306 int ch_len, table_len, resp_len; 310 307 int i; … … 367 364 * returns a pointer to selected data and number of bytes in that. 368 365 */ 369 static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) 370 { 366 static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { 367 371 368 int numrules, codec, size; 372 369 int i; … … 424 421 */ 425 422 426 rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) 427 { 428 sdpplin_t *desc = NULL; 429 rmff_header_t *header = NULL; 430 char *buf = NULL; 431 int len, i; 432 int max_bit_rate=0; 433 int avg_bit_rate=0; 434 int max_packet_size=0; 435 int avg_packet_size=0; 436 int duration=0; 437 438 if( !data ) return NULL; 439 440 desc=sdpplin_parse(data); 441 if( !desc ) return NULL; 442 443 buf= (char *)malloc(sizeof(char)*2048); 444 if( !buf ) goto error; 445 446 header = (rmff_header_t*)malloc(sizeof(rmff_header_t)); 447 if( !header ) goto error; 448 449 memset(header, 0, sizeof(rmff_header_t)); 450 header->fileheader=rmff_new_fileheader(4+desc->stream_count); 451 header->cont=rmff_new_cont( 452 desc->title, 453 desc->author, 454 desc->copyright, 455 desc->abstract); 456 457 header->data=rmff_new_dataheader(0,0); 458 if( !header->data ) goto error; 459 460 header->streams = (rmff_mdpr_t**) malloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); 461 if( !header->streams ) goto error; 462 463 memset(header->streams, 0, sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); 464 lprintf("number of streams: %u\n", desc->stream_count); 465 for (i=0; i<desc->stream_count; i++) 466 { 467 int j=0; 468 int n; 469 char b[64]; 470 int rulematches[16]; 471 472 lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth); 473 474 n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches); 475 for (j=0; j<n; j++) 476 { 477 lprintf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); 478 sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); 479 strcat(*stream_rules, b); 480 } 481 482 if (!desc->stream[i]->mlti_data) 483 { 484 len = 0; 485 if( buf ) free( buf ); 486 buf = NULL; 487 } 488 else 489 len=select_mlti_data(desc->stream[i]->mlti_data, 490 desc->stream[i]->mlti_data_size, rulematches[0], &buf); 491 492 header->streams[i]=rmff_new_mdpr( 493 desc->stream[i]->stream_id, 494 desc->stream[i]->max_bit_rate, 495 desc->stream[i]->avg_bit_rate, 496 desc->stream[i]->max_packet_size, 497 desc->stream[i]->avg_packet_size, 498 desc->stream[i]->start_time, 499 desc->stream[i]->preroll, 500 desc->stream[i]->duration, 501 desc->stream[i]->stream_name, 502 desc->stream[i]->mime_type, 503 len, 504 buf); 505 if( !header->streams[i] ) goto error; 506 507 duration=MAX(duration,desc->stream[i]->duration); 508 max_bit_rate+=desc->stream[i]->max_bit_rate; 509 avg_bit_rate+=desc->stream[i]->avg_bit_rate; 510 max_packet_size=MAX(max_packet_size, desc->stream[i]->max_packet_size); 511 if (avg_packet_size) 512 avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; 513 else 514 avg_packet_size=desc->stream[i]->avg_packet_size; 423 rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { 424 425 sdpplin_t *desc = NULL; 426 rmff_header_t *header = NULL; 427 char *buf = NULL; 428 int len, i; 429 int max_bit_rate=0; 430 int avg_bit_rate=0; 431 int max_packet_size=0; 432 int avg_packet_size=0; 433 int duration=0; 434 435 if( !data ) return NULL; 436 437 desc=sdpplin_parse(data); 438 if( !desc ) return NULL; 439 440 buf= (char *)malloc(sizeof(char)*2048); 441 if( !buf ) goto error; 442 443 header = (rmff_header_t*)malloc(sizeof(rmff_header_t)); 444 if( !header ) goto error; 445 446 memset(header, 0, sizeof(rmff_header_t)); 447 header->fileheader=rmff_new_fileheader(4+desc->stream_count); 448 header->cont=rmff_new_cont( 449 desc->title, 450 desc->author, 451 desc->copyright, 452 desc->abstract); 453 454 header->data=rmff_new_dataheader(0,0); 455 if( !header->data ) goto error; 456 457 header->streams = (rmff_mdpr_t**) malloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); 458 if( !header->streams ) goto error; 459 460 memset(header->streams, 0, sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); 461 lprintf("number of streams: %u\n", desc->stream_count); 462 463 for (i=0; i<desc->stream_count; i++) { 464 465 int j=0; 466 int n; 467 char b[64]; 468 int rulematches[16]; 469 470 lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth); 471 472 n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches); 473 for (j=0; j<n; j++) { 474 lprintf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); 475 sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); 476 strcat(*stream_rules, b); 515 477 } 516 478 517 if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') 518 (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ 519 520 header->prop=rmff_new_prop( 521 max_bit_rate, 522 avg_bit_rate, 523 max_packet_size, 524 avg_packet_size, 525 0, 526 duration, 527 0, 528 0, 529 0, 530 desc->stream_count, 531 desc->flags); 532 if( !header->prop ) goto error; 533 534 rmff_fix_header(header); 535 536 if( desc ) 537 { 538 sdpplin_free( desc ); 539 free( desc ); 479 if (!desc->stream[i]->mlti_data) { 480 len = 0; 481 if( buf ) free( buf ); 482 buf = NULL; 483 } else 484 len=select_mlti_data(desc->stream[i]->mlti_data, 485 desc->stream[i]->mlti_data_size, rulematches[0], &buf); 486 487 header->streams[i]=rmff_new_mdpr( 488 desc->stream[i]->stream_id, 489 desc->stream[i]->max_bit_rate, 490 desc->stream[i]->avg_bit_rate, 491 desc->stream[i]->max_packet_size, 492 desc->stream[i]->avg_packet_size, 493 desc->stream[i]->start_time, 494 desc->stream[i]->preroll, 495 desc->stream[i]->duration, 496 desc->stream[i]->stream_name, 497 desc->stream[i]->mime_type, 498 len, 499 buf); 500 if( !header->streams[i] ) goto error; 501 502 duration=MAX(duration,desc->stream[i]->duration); 503 max_bit_rate+=desc->stream[i]->max_bit_rate; 504 avg_bit_rate+=desc->stream[i]->avg_bit_rate; 505 max_packet_size=MAX(max_packet_size, desc->stream[i]->max_packet_size); 506 if (avg_packet_size) 507 avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; 508 else 509 avg_packet_size=desc->stream[i]->avg_packet_size; 510 } 511 512 if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') 513 (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ 514 515 header->prop=rmff_new_prop( 516 max_bit_rate, 517 avg_bit_rate, 518 max_packet_size, 519 avg_packet_size, 520 0, 521 duration, 522 0, 523 0, 524 0, 525 desc->stream_count, 526 desc->flags); 527 if( !header->prop ) goto error; 528 529 rmff_fix_header(header); 530 531 if( desc ) { 532 sdpplin_free( desc ); 533 free( desc ); 534 } 535 if( buf ) free(buf); 536 return header; 537 538 error: 539 if( desc ) { 540 sdpplin_free( desc ); 541 free( desc ); 542 } 543 if( header ) { 544 rmff_free_header( header ); 545 free( header ); 546 } 547 if( buf ) free( buf ); 548 return NULL; 549 } 550 551 int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) { 552 553 int n=1; 554 uint8_t header[8]; 555 int size; 556 int flags1; 557 int unknown1; 558 uint32_t ts; 559 560 n=rtsp_read_data(rtsp_session, header, 8); 561 if (n<8) return 0; 562 if (header[0] != 0x24) { 563 lprintf("rdt chunk not recognized: got 0x%02x\n", header[0]); 564 return 0; 565 } 566 size=(header[1]<<16)+(header[2]<<8)+(header[3]); 567 flags1=header[4]; 568 if ((flags1!=0x40)&&(flags1!=0x42)) { 569 lprintf("got flags1: 0x%02x\n",flags1); 570 if (header[6]==0x06) { 571 lprintf("got end of stream packet\n"); 572 return 0; 540 573 } 541 if( buf ) free(buf); 542 return header; 543 544 error: 545 if( desc ) 546 { 547 sdpplin_free( desc ); 548 free( desc ); 549 } 550 if( header ) 551 { 552 rmff_free_header( header ); 553 free( header ); 554 } 555 if( buf ) free( buf ); 556 return NULL; 557 } 558 559 int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) 560 { 561 int n=1; 562 uint8_t header[8]; 563 int size; 564 int flags1; 565 int unknown1; 566 uint32_t ts; 567 568 n=rtsp_read_data(rtsp_session, header, 8); 569 if (n<8) 570 return 0; 571 if (header[0] != 0x24) 572 { 573 lprintf("rdt chunk not recognized: got 0x%02x\n", header[0]); 574 return 0; 575 } 576 size=(header[1]<<16)+(header[2]<<8)+(header[3]); 574 header[0]=header[5]; 575 header[1]=header[6]; 576 header[2]=header[7]; 577 n=rtsp_read_data(rtsp_session, header+3, 5); 578 if (n<5) return 0; 579 lprintf("ignoring bytes:\n"); 580 n=rtsp_read_data(rtsp_session, header+4, 4); 581 if (n<4) return 0; 577 582 flags1=header[4]; 578 if ((flags1!=0x40)&&(flags1!=0x42)) 579 { 580 lprintf("got flags1: 0x%02x\n",flags1); 581 if (header[6]==0x06) 582 { 583 lprintf("got end of stream packet\n"); 584 return 0; 585 } 586 header[0]=header[5]; 587 header[1]=header[6]; 588 header[2]=header[7]; 589 n=rtsp_read_data(rtsp_session, header+3, 5); 590 if (n<5) 591 return 0; 592 lprintf("ignoring bytes:\n"); 593 n=rtsp_read_data(rtsp_session, header+4, 4); 594 if (n<4) 595 return 0; 596 flags1=header[4]; 597 size-=9; 598 } 599 unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); 600 n=rtsp_read_data(rtsp_session, header, 6); 601 if (n<6) 602 return 0; 603 ts=BE_32(header); 583 size-=9; 584 } 585 unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); 586 n=rtsp_read_data(rtsp_session, header, 6); 587 if (n<6) return 0; 588 ts=BE_32(header); 604 589 605 590 #if 0 606 lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n",607 ts, size, flags1, unknown1, header[4], header[5]);591 lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n", 592 ts, size, flags1, unknown1, header[4], header[5]); 608 593 #endif 609 594 610 size+=2;611 ph->object_version=0;612 ph->length=size;613 ph->stream_number=(flags1>>1)&1;614 ph->timestamp=ts;615 ph->reserved=0;616 ph->flags=0; /* TODO: determine keyframe flag and insert here? */617 return size;595 size+=2; 596 ph->object_version=0; 597 ph->length=size; 598 ph->stream_number=(flags1>>1)&1; 599 ph->timestamp=ts; 600 ph->reserved=0; 601 ph->flags=0; /* TODO: determine keyframe flag and insert here? */ 602 return size; 618 603 } 619 604 620 605 int real_get_rdt_chunk(rtsp_client_t *rtsp_session, rmff_pheader_t *ph, 621 unsigned char **buffer) 622 { 623 int n;624 rmff_dump_pheader(ph, *buffer);625 n=rtsp_read_data(rtsp_session, *buffer + 12, ph->length - 12);626 return (n <= 0) ? 0 : n+12;606 unsigned char **buffer) { 607 608 int n; 609 rmff_dump_pheader(ph, *buffer); 610 n=rtsp_read_data(rtsp_session, *buffer + 12, ph->length - 12); 611 return (n <= 0) ? 0 : n+12; 627 612 } 628 613 629 614 //! maximum size of the rtsp description, must be < INT_MAX 630 615 #define MAX_DESC_BUF (20 * 1024 * 1024) 631 rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandwidth) 632 { 633 char *description=NULL; 634 char *session_id=NULL; 635 rmff_header_t *h; 636 char *challenge1 = NULL; 637 char challenge2[64]; 638 char checksum[34]; 639 char *subscribe=NULL; 640 char *buf=(char*)malloc(sizeof(char)*256); 641 char *mrl=rtsp_get_mrl(rtsp_session); 642 unsigned int size; 643 int status; 644 645 /* get challenge */ 646 challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1")); 647 lprintf("Challenge1: %s\n", challenge1); 648 649 /* request stream description */ 650 rtsp_schedule_field(rtsp_session, "Accept: application/sdp"); 651 sprintf(buf, "Bandwidth: %u", bandwidth); 652 rtsp_schedule_field(rtsp_session, buf); 653 rtsp_schedule_field(rtsp_session, "GUID: 00000000-0000-0000-0000-000000000000"); 654 rtsp_schedule_field(rtsp_session, "RegionData: 0"); 655 rtsp_schedule_field(rtsp_session, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); 656 rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1"); 657 rtsp_schedule_field(rtsp_session, "Language: en-US"); 658 rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup"); 659 660 status=rtsp_request_describe(rtsp_session,NULL); 661 if ( status<200 || status>299 ) 662 { 663 char *alert=rtsp_search_answers(rtsp_session,"Alert"); 664 if (alert) { 665 lprintf("real: got message from server:\n%s\n", alert); 666 } 667 printf( "bou\n"); 668 rtsp_send_ok(rtsp_session); 669 if( challenge1 ) free(challenge1); 670 if( alert ) free(alert); 671 if( buf ) free(buf); 672 return NULL; 616 rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandwidth) { 617 618 char *description=NULL; 619 char *session_id=NULL; 620 rmff_header_t *h; 621 char *challenge1 = NULL; 622 char challenge2[64]; 623 char checksum[34]; 624 char *subscribe=NULL; 625 char *buf=(char*)malloc(sizeof(char)*256); 626 char *mrl=rtsp_get_mrl(rtsp_session); 627 unsigned int size; 628 int status; 629 630 /* get challenge */ 631 challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1")); 632 lprintf("Challenge1: %s\n", challenge1); 633 634 /* request stream description */ 635 rtsp_schedule_field(rtsp_session, "Accept: application/sdp"); 636 sprintf(buf, "Bandwidth: %u", bandwidth); 637 rtsp_schedule_field(rtsp_session, buf); 638 rtsp_schedule_field(rtsp_session, "GUID: 00000000-0000-0000-0000-000000000000"); 639 rtsp_schedule_field(rtsp_session, "RegionData: 0"); 640 rtsp_schedule_field(rtsp_session, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); 641 rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1"); 642 rtsp_schedule_field(rtsp_session, "Language: en-US"); 643 rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup"); 644 645 status=rtsp_request_describe(rtsp_session,NULL); 646 if ( status<200 || status>299 ) { 647 char *alert=rtsp_search_answers(rtsp_session,"Alert"); 648 if (alert) { 649 lprintf("real: got message from server:\n%s\n", alert); 673 650 } 674 675 /* receive description */ 676 size=0; 677 if (!rtsp_search_answers(rtsp_session,"Content-length")) 678 lprintf("real: got no Content-length!\n"); 679 else 680 size=atoi(rtsp_search_answers(rtsp_session,"Content-length")); 681 682 if (size > MAX_DESC_BUF) { 683 printf("real: Content-length for description too big (> %uMB)!\n", 684 MAX_DESC_BUF/(1024*1024) ); 685 goto error; 686 } 687 688 if (!rtsp_search_answers(rtsp_session,"ETag")) 689 lprintf("real: got no ETag!\n"); 690 else 691 session_id=strdup(rtsp_search_answers(rtsp_session,"ETag")); 692 693 lprintf("Stream description size: %i\n", size); 694 695 description = (char*)malloc(sizeof(char)*(size+1)); 696 if( !description ) 697 goto error; 698 if( rtsp_read_data(rtsp_session, description, size) <= 0) 699 goto error; 700 description[size]=0; 701 fprintf(stderr,description); 702 703 /* parse sdp (sdpplin) and create a header and a subscribe string */ 704 subscribe = (char *) malloc(sizeof(char)*256); 705 if( !subscribe ) 706 goto error; 707 708 strcpy(subscribe, "Subscribe: "); 709 h=real_parse_sdp(description, &subscribe, bandwidth); 710 if (!h) 711 goto error; 712 713 rmff_fix_header(h); 714 715 #if 0 716 fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", 717 h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); 718 #endif 719 720 /* setup our streams */ 721 real_calc_response_and_checksum (challenge2, checksum, challenge1); 722 buf = realloc(buf, strlen(challenge2) + strlen(checksum) + 32); 723 sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); 724 rtsp_schedule_field(rtsp_session, buf); 651 printf( "bou\n"); 652 rtsp_send_ok(rtsp_session); 653 if( challenge1 ) free(challenge1); 654 if( alert ) free(alert); 655 if( buf ) free(buf); 656 return NULL; 657 } 658 659 /* receive description */ 660 size=0; 661 if (!rtsp_search_answers(rtsp_session,"Content-length")) 662 lprintf("real: got no Content-length!\n"); 663 else 664 size=atoi(rtsp_search_answers(rtsp_session,"Content-length")); 665 666 if (size > MAX_DESC_BUF) { 667 printf("real: Content-length for description too big (> %uMB)!\n", 668 MAX_DESC_BUF/(1024*1024) ); 669 goto error; 670 } 671 672 if (!rtsp_search_answers(rtsp_session,"ETag")) 673 lprintf("real: got no ETag!\n"); 674 else 675 session_id=strdup(rtsp_search_answers(rtsp_session,"ETag")); 676 677 lprintf("Stream description size: %i\n", size); 678 679 description = (char*)malloc(sizeof(char)*(size+1)); 680 if( !description ) 681 goto error; 682 if( rtsp_read_data(rtsp_session, description, size) <= 0) 683 goto error; 684 description[size]=0; 685 fprintf(stderr,description); 686 687 /* parse sdp (sdpplin) and create a header and a subscribe string */ 688 subscribe = (char *) malloc(sizeof(char)*256); 689 if( !subscribe ) 690 goto error; 691 692 strcpy(subscribe, "Subscribe: "); 693 h=real_parse_sdp(description, &subscribe, bandwidth); 694 if (!h) 695 goto error; 696 697 rmff_fix_header(h); 698 699 #if 0 700 fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", 701 h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); 702 #endif 703 704 /* setup our streams */ 705 real_calc_response_and_checksum (challenge2, checksum, challenge1); 706 buf = realloc(buf, strlen(challenge2) + strlen(checksum) + 32); 707 sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); 708 rtsp_schedule_field(rtsp_session, buf); 709 buf = realloc(buf, strlen(session_id) + 32); 710 sprintf(buf, "If-Match: %s", session_id); 711 rtsp_schedule_field(rtsp_session, buf); 712 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); 713 buf = realloc(buf, strlen(mrl) + 32); 714 sprintf(buf, "%s/streamid=0", mrl); 715 rtsp_request_setup(rtsp_session,buf); 716 717 if (h->prop->num_streams > 1) { 718 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); 725 719 buf = realloc(buf, strlen(session_id) + 32); 726 720 sprintf(buf, "If-Match: %s", session_id); 727 721 rtsp_schedule_field(rtsp_session, buf); 728 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play");729 722 buf = realloc(buf, strlen(mrl) + 32); 730 sprintf(buf, "%s/streamid= 0", mrl);723 sprintf(buf, "%s/streamid=1", mrl); 731 724 rtsp_request_setup(rtsp_session,buf); 732 733 if (h->prop->num_streams > 1) { 734 rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); 735 buf = realloc(buf, strlen(session_id) + 32); 736 sprintf(buf, "If-Match: %s", session_id); 737 rtsp_schedule_field(rtsp_session, buf); 738 buf = realloc(buf, strlen(mrl) + 32); 739 sprintf(buf, "%s/streamid=1", mrl); 740 rtsp_request_setup(rtsp_session,buf); 741 } 742 /* set stream parameter (bandwidth) with our subscribe string */ 743 rtsp_schedule_field(rtsp_session, subscribe); 744 rtsp_request_setparameter(rtsp_session,NULL); 745 746 /* and finally send a play request */ 747 rtsp_schedule_field(rtsp_session, "Range: npt=0-"); 748 rtsp_request_play(rtsp_session,NULL); 749 750 if( challenge1 ) free( challenge1 ); 751 if( session_id ) free( session_id ); 752 if( description ) free(description); 753 if( subscribe ) free(subscribe); 754 if( buf ) free(buf); 755 return h; 725 } 726 /* set stream parameter (bandwidth) with our subscribe string */ 727 rtsp_schedule_field(rtsp_session, subscribe); 728 rtsp_request_setparameter(rtsp_session,NULL); 729 730 /* and finally send a play request */ 731 rtsp_schedule_field(rtsp_session, "Range: npt=0-"); 732 rtsp_request_play(rtsp_session,NULL); 733 734 if( challenge1 ) free( challenge1 ); 735 if( session_id ) free( session_id ); 736 if( description ) free(description); 737 if( subscribe ) free(subscribe); 738 if( buf ) free(buf); 739 return h; 756 740 757 741 error: 758 if( h ) rmff_free_header( h );759 if( challenge1 ) free( challenge1 );760 if( session_id ) free( session_id );761 if( description ) free(description);762 if( subscribe ) free(subscribe);763 if( buf ) free(buf);764 return NULL;765 } 742 if( h ) rmff_free_header( h ); 743 if( challenge1 ) free( challenge1 ); 744 if( session_id ) free( session_id ); 745 if( description ) free(description); 746 if( subscribe ) free(subscribe); 747 if( buf ) free(buf); 748 return NULL; 749 } modules/access/rtsp/real_rmff.c
r0c2787f r268ff7e 184 184 } 185 185 186 static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) 187 { 188 if (!data) return;189 190 data->object_id=BE_32(&data->object_id);191 data->size=BE_32(&data->size);192 data->object_version=BE_16(&data->object_version);193 data->num_packets=BE_32(&data->num_packets);194 data->next_data_header=BE_32(&data->next_data_header);195 196 memcpy(buffer, data, 8);197 memcpy(&buffer[8], &data->object_version, 2);198 memcpy(&buffer[10], &data->num_packets, 8);199 200 data->num_packets=BE_32(&data->num_packets);201 data->next_data_header=BE_32(&data->next_data_header);202 data->size=BE_32(&data->size);203 data->object_version=BE_16(&data->object_version);204 data->object_id=BE_32(&data->object_id);186 static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) { 187 188 if (!data) return; 189 190 data->object_id=BE_32(&data->object_id); 191 data->size=BE_32(&data->size); 192 data->object_version=BE_16(&data->object_version); 193 data->num_packets=BE_32(&data->num_packets); 194 data->next_data_header=BE_32(&data->next_data_header); 195 196 memcpy(buffer, data, 8); 197 memcpy(&buffer[8], &data->object_version, 2); 198 memcpy(&buffer[10], &data->num_packets, 8); 199 200 data->num_packets=BE_32(&data->num_packets); 201 data->next_data_header=BE_32(&data->next_data_header); 202 data->size=BE_32(&data->size); 203 data->object_version=BE_16(&data->object_version); 204 data->object_id=BE_32(&data->object_id); 205 205 } 206 206 … … 248 248 } 249 249 250 rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers) 251 { 252 rmff_fileheader_t *fileheader = malloc(sizeof(rmff_fileheader_t));253 if( !fileheader ) return NULL;254 255 memset(fileheader, 0, sizeof(rmff_fileheader_t));256 fileheader->object_id=RMF_TAG;257 fileheader->size=18;258 fileheader->object_version=0;259 fileheader->file_version=0;260 fileheader->num_headers=num_headers;261 262 return fileheader;250 rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers) { 251 252 rmff_fileheader_t *fileheader = malloc(sizeof(rmff_fileheader_t)); 253 if( !fileheader ) return NULL; 254 255 memset(fileheader, 0, sizeof(rmff_fileheader_t)); 256 fileheader->object_id=RMF_TAG; 257 fileheader->size=18; 258 fileheader->object_version=0; 259 fileheader->file_version=0; 260 fileheader->num_headers=num_headers; 261 262 return fileheader; 263 263 } 264 264 265 265 rmff_prop_t *rmff_new_prop ( 266 uint32_t max_bit_rate,267 uint32_t avg_bit_rate,268 uint32_t max_packet_size,269 uint32_t avg_packet_size,270 uint32_t num_packets,271 uint32_t duration,272 uint32_t preroll,273 uint32_t index_offset,274 uint32_t data_offset,275 uint16_t num_streams,276 uint16_t flags )277 { 278 rmff_prop_t *prop = malloc(sizeof(rmff_prop_t));279 if( !prop ) return NULL;280 281 memset(prop, 0, sizeof(rmff_prop_t));282 prop->object_id=PROP_TAG;283 prop->size=50;284 prop->object_version=0;285 prop->max_bit_rate=max_bit_rate;286 prop->avg_bit_rate=avg_bit_rate;287 prop->max_packet_size=max_packet_size;288 prop->avg_packet_size=avg_packet_size;289 prop->num_packets=num_packets;290 prop->duration=duration;291 prop->preroll=preroll;292 prop->index_offset=index_offset;293 prop->data_offset=data_offset;294 prop->num_streams=num_streams;295 prop->flags=flags;296 297 return prop;266 uint32_t max_bit_rate, 267 uint32_t avg_bit_rate, 268 uint32_t max_packet_size, 269 uint32_t avg_packet_size, 270 uint32_t num_packets, 271 uint32_t duration, 272 uint32_t preroll, 273 uint32_t index_offset, 274 uint32_t data_offset, 275 uint16_t num_streams, 276 uint16_t flags ) { 277 278 rmff_prop_t *prop = malloc(sizeof(rmff_prop_t)); 279 if( !prop ) return NULL; 280 281 memset(prop, 0, sizeof(rmff_prop_t)); 282 prop->object_id=PROP_TAG; 283 prop->size=50; 284 prop->object_version=0; 285 prop->max_bit_rate=max_bit_rate; 286 prop->avg_bit_rate=avg_bit_rate; 287 prop->max_packet_size=max_packet_size; 288 prop->avg_packet_size=avg_packet_size; 289 prop->num_packets=num_packets; 290 prop->duration=duration; 291 prop->preroll=preroll; 292 prop->index_offset=index_offset; 293 prop->data_offset=data_offset; 294 prop->num_streams=num_streams; 295 prop->flags=flags; 296 297 return prop; 298 298 } 299 299 300 300 rmff_mdpr_t *rmff_new_mdpr( 301 uint16_t stream_number, 302 uint32_t max_bit_rate, 303 uint32_t avg_bit_rate, 304 uint32_t max_packet_size, 305 uint32_t avg_packet_size, 306 uint32_t start_time, 307 uint32_t preroll, 308 uint32_t duration, 309 const char *stream_name, 310 const char *mime_type, 311 uint32_t type_specific_len, 312 const char *type_specific_data ) 313 { 314 rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t)); 315 if( !mdpr ) return NULL; 316 317 memset(mdpr, 0, sizeof(rmff_mdpr_t)); 318 mdpr->object_id=MDPR_TAG; 319 mdpr->object_version=0; 320 mdpr->stream_number=stream_number; 321 mdpr->max_bit_rate=max_bit_rate; 322 mdpr->avg_bit_rate=avg_bit_rate; 323 mdpr->max_packet_size=max_packet_size; 324 mdpr->avg_packet_size=avg_packet_size; 325 mdpr->start_time=start_time; 326 mdpr->preroll=preroll; 327 mdpr->duration=duration; 328 mdpr->stream_name_size=0; 329 if (stream_name) 330 { 331 mdpr->stream_name=strdup(stream_name); 332 mdpr->stream_name_size=strlen(stream_name); 333 } 334 mdpr->mime_type_size=0; 335 if (mime_type) 336 { 337 mdpr->mime_type=strdup(mime_type); 338 mdpr->mime_type_size=strlen(mime_type); 339 } 340 mdpr->type_specific_len=type_specific_len; 341 342 mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len); 343 if( !mdpr->type_specific_data ) 344 { 345 if( mdpr->stream_name ) free( mdpr->stream_name ); 346 free( mdpr ); 347 return NULL; 348 } 349 memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); 350 mdpr->mlti_data=NULL; 351 mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; 352 return mdpr; 353 } 354 355 rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment) 356 { 357 rmff_cont_t *cont = malloc(sizeof(rmff_cont_t)); 358 if( !cont ) return NULL; 359 360 memset(cont, 0, sizeof(rmff_cont_t)); 361 cont->object_id=CONT_TAG; 362 cont->object_version=0; 363 cont->title=NULL; 364 cont->author=NULL; 365 cont->copyright=NULL; 366 cont->comment=NULL; 367 cont->title_len=0; 368 cont->author_len=0; 369 cont->copyright_len=0; 370 cont->comment_len=0; 371 372 if (title) 373 { 374 cont->title_len=strlen(title); 375 cont->title=strdup(title); 376 } 377 if (author) 378 { 379 cont->author_len=strlen(author); 380 cont->author=strdup(author); 381 } 382 if (copyright) 383 { 384 cont->copyright_len=strlen(copyright); 385 cont->copyright=strdup(copyright); 386 } 387 if (comment) 388 { 389 cont->comment_len=strlen(comment); 390 cont->comment=strdup(comment); 391 } 392 cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18; 393 return cont; 394 } 395 396 rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header) 397 { 398 rmff_data_t *data = malloc(sizeof(rmff_data_t)); 399 if( !data ) return NULL; 400 401 memset(data, 0, sizeof(rmff_data_t)); 402 data->object_id=DATA_TAG; 403 data->size=18; 404 data->object_version=0; 405 data->num_packets=num_packets; 406 data->next_data_header=next_data_header; 407 408 return data; 409 } 410 411 void rmff_print_header(rmff_header_t *h) 412 { 301 uint16_t stream_number, 302 uint32_t max_bit_rate, 303 uint32_t avg_bit_rate, 304 uint32_t max_packet_size, 305 uint32_t avg_packet_size, 306 uint32_t start_time, 307 uint32_t preroll, 308 uint32_t duration, 309 const char *stream_name, 310 const char *mime_type, 311 uint32_t type_specific_len, 312 const char *type_specific_data ) { 313 314 rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t)); 315 if( !mdpr ) return NULL; 316 317 memset(mdpr, 0, sizeof(rmff_mdpr_t)); 318 mdpr->object_id=MDPR_TAG; 319 mdpr->object_version=0; 320 mdpr->stream_number=stream_number; 321 mdpr->max_bit_rate=max_bit_rate; 322 mdpr->avg_bit_rate=avg_bit_rate; 323 mdpr->max_packet_size=max_packet_size; 324 mdpr->avg_packet_size=avg_packet_size; 325 mdpr->start_time=start_time; 326 mdpr->preroll=preroll; 327 mdpr->duration=duration; 328 mdpr->stream_name_size=0; 329 if (stream_name) { 330 mdpr->stream_name=strdup(stream_name); 331 mdpr->stream_name_size=strlen(stream_name); 332 } 333 mdpr->mime_type_size=0; 334 if (mime_type) { 335 mdpr->mime_type=strdup(mime_type); 336 mdpr->mime_type_size=strlen(mime_type); 337 } 338 mdpr->type_specific_len=type_specific_len; 339 340 mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len); 341 if( !mdpr->type_specific_data ) { 342 if( mdpr->stream_name ) free( mdpr->stream_name ); 343 free( mdpr ); 344 return NULL; 345 } 346 memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); 347 mdpr->mlti_data=NULL; 348 mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; 349 return mdpr; 350 } 351 352 rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment) { 353 354 rmff_cont_t *cont = malloc(sizeof(rmff_cont_t)); 355 if( !cont ) return NULL; 356 357 memset(cont, 0, sizeof(rmff_cont_t)); 358 cont->object_id=CONT_TAG; 359 cont->object_version=0; 360 cont->title=NULL; 361 cont->author=NULL; 362 cont->copyright=NULL; 363 cont->comment=NULL; 364 cont->title_len=0; 365 cont->author_len=0; 366 cont->copyright_len=0; 367 cont->comment_len=0; 368 369 if (title) { 370 cont->title_len=strlen(title); 371 cont->title=strdup(title); 372 } 373 if (author) 374 { 375 cont->author_len=strlen(author); 376 cont->author=strdup(author); 377 } 378 if (copyright) { 379 cont->copyright_len=strlen(copyright); 380 cont->copyright=strdup(copyright); 381 } 382 if (comment) { 383 cont->comment_len=strlen(comment); 384 cont->comment=strdup(comment); 385 } 386 cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18; 387 return cont; 388 } 389 390 rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header) { 391 rmff_data_t *data = malloc(sizeof(rmff_data_t)); 392 if( !data ) return NULL; 393 394 memset(data, 0, sizeof(rmff_data_t)); 395 data->object_id=DATA_TAG; 396 data->size=18; 397 data->object_version=0; 398 data->num_packets=num_packets; 399 data->next_data_header=next_data_header; 400 401 return data; 402 } 403 404 void rmff_print_header(rmff_header_t *h) { 413 405 rmff_mdpr_t **stream; 414 406 415 if(!h) 416 { 417 printf("rmff_print_header: NULL given\n"); 418 return; 419 } 420 if(h->fileheader) 421 { 422 printf("\nFILE:\n"); 423 printf("file version : %d\n", h->fileheader->file_version); 424 printf("number of headers : %d\n", h->fileheader->num_headers); 425 } 426 if(h->cont) 427 { 428 printf("\nCONTENT:\n"); 429 printf("title : %s\n", h->cont->title); 430 printf("author : %s\n", h->cont->author); 431 printf("copyright : %s\n", h->cont->copyright); 432 printf("comment : %s\n", h->cont->comment); 433 } 434 if(h->prop) 435 { 436 printf("\nSTREAM PROPERTIES:\n"); 437 printf("bit rate (max/avg) : %i/%i\n", h->prop->max_bit_rate, h->prop->avg_bit_rate); 438 printf("packet size (max/avg) : %i/%i bytes\n", h->prop->max_packet_size, h->prop->avg_packet_size); 439 printf("packets : %i\n", h->prop->num_packets); 440 printf("duration : %i ms\n", h->prop->duration); 441 printf("pre-buffer : %i ms\n", h->prop->preroll); 442 printf("index offset : %i bytes\n", h->prop->index_offset); 443 printf("data offset : %i bytes\n", h->prop->data_offset); 444 printf("media streams : %i\n", h->prop->num_streams); 445 printf("flags : "); 446 if (h->prop->flags & PN_SAVE_ENABLED) printf("save_enabled "); 447 if (h->prop->flags & PN_PERFECT_PLAY_ENABLED) printf("perfect_play_enabled "); 448 if (h->prop->flags & PN_LIVE_BROADCAST) printf("live_broadcast "); 449 printf("\n"); 450 } 451 stream=h->streams; 452 if(stream) 453 { 454 while (*stream) 455 { 456 printf("\nSTREAM %i:\n", (*stream)->stream_number); 457 printf("stream name [mime type] : %s [%s]\n", (*stream)->stream_name, (*stream)->mime_type); 458 printf("bit rate (max/avg) : %i/%i\n", (*stream)->max_bit_rate, (*stream)->avg_bit_rate); 459 printf("packet size (max/avg) : %i/%i bytes\n", (*stream)->max_packet_size, (*stream)->avg_packet_size); 460 printf("start time : %i\n", (*stream)->start_time); 461 printf("pre-buffer : %i ms\n", (*stream)->preroll); 462 printf("duration : %i ms\n", (*stream)->duration); 463 printf("type specific data:\n"); 464 stream++; 465 } 466 } 467 if(h->data) 468 { 469 printf("\nDATA:\n"); 470 printf("size : %i\n", h->data->size); 471 printf("packets : %i\n", h->data->num_packets); 472 printf("next DATA : 0x%08x\n", h->data->next_data_header); 473 } 474 } 475 476 void rmff_fix_header(rmff_header_t *h) 477 { 478 unsigned int num_headers=0; 479 unsigned int header_size=0; 480 rmff_mdpr_t **streams; 481 int num_streams=0; 482 483 if (!h) 484 { 485 lprintf("rmff_fix_header: fatal: no header given.\n"); 486 return; 487 } 488 if (!h->streams) 489 { 490 lprintf("rmff_fix_header: warning: no MDPR chunks\n"); 491 } 492 else 493 { 494 streams=h->streams; 495 while (*streams) 496 { 497 num_streams++; 498 num_headers++; 499 header_size+=(*streams)->size; 500 streams++; 501 } 502 } 503 if (h->prop)
