| 446 | } |
| 447 | |
| 448 | static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, |
| 449 | int letter, const char *buf) |
| 450 | { |
| 451 | RTSPState *rt = s->priv_data; |
| 452 | char buf1[64], st_type[64]; |
| 453 | const char *p; |
| 454 | enum AVMediaType codec_type; |
| 455 | int payload_type; |
| 456 | AVStream *st; |
| 457 | RTSPStream *rtsp_st; |
| 458 | RTSPSource *rtsp_src; |
| 459 | struct sockaddr_storage sdp_ip; |
| 460 | int ttl; |
| 461 | |
| 462 | av_log(s, AV_LOG_TRACE, "sdp: %c='%s'\n", letter, buf); |
| 463 | |
| 464 | p = buf; |
| 465 | if (s1->skip_media && letter != 'm') |
| 466 | return; |
| 467 | switch (letter) { |
| 468 | case 'c': |
| 469 | get_word(buf1, sizeof(buf1), &p); |
| 470 | if (strcmp(buf1, "IN") != 0) |
| 471 | return; |
| 472 | get_word(buf1, sizeof(buf1), &p); |
| 473 | if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6")) |
| 474 | return; |
| 475 | get_word_sep(buf1, sizeof(buf1), "/", &p); |
| 476 | if (get_sockaddr(s, buf1, &sdp_ip)) |
| 477 | return; |
| 478 | ttl = 16; |
| 479 | if (*p == '/') { |
| 480 | p++; |
| 481 | get_word_sep(buf1, sizeof(buf1), "/", &p); |
| 482 | ttl = atoi(buf1); |
| 483 | } |
| 484 | if (s->nb_streams == 0) { |
| 485 | s1->default_ip = sdp_ip; |
| 486 | s1->default_ttl = ttl; |
| 487 | } else { |
| 488 | rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1]; |
| 489 | rtsp_st->sdp_ip = sdp_ip; |
| 490 | rtsp_st->sdp_ttl = ttl; |
| 491 | } |
| 492 | break; |
| 493 | case 's': |
| 494 | av_dict_set(&s->metadata, "title", p, 0); |
| 495 | break; |
| 496 | case 'i': |
| 497 | if (s->nb_streams == 0) { |
| 498 | av_dict_set(&s->metadata, "comment", p, 0); |
| 499 | break; |
| 500 | } |
| 501 | break; |
| 502 | case 'm': |
| 503 | /* new stream */ |
| 504 | s1->skip_media = 0; |
| 505 | s1->seen_fmtp = 0; |
no test coverage detected