| 408 | } |
| 409 | |
| 410 | static int parse_adaptation_sets(AVFormatContext *s) |
| 411 | { |
| 412 | WebMDashMuxContext *w = s->priv_data; |
| 413 | char *p = w->adaptation_sets; |
| 414 | char *q; |
| 415 | enum { new_set, parsed_id, parsing_streams } state; |
| 416 | if (!w->adaptation_sets) { |
| 417 | av_log(s, AV_LOG_ERROR, "The 'adaptation_sets' option must be set.\n"); |
| 418 | return AVERROR(EINVAL); |
| 419 | } |
| 420 | // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on |
| 421 | state = new_set; |
| 422 | while (1) { |
| 423 | if (*p == '\0') { |
| 424 | if (state == new_set) |
| 425 | break; |
| 426 | else |
| 427 | return AVERROR(EINVAL); |
| 428 | } else if (state == new_set && *p == ' ') { |
| 429 | p++; |
| 430 | continue; |
| 431 | } else if (state == new_set && !strncmp(p, "id=", 3)) { |
| 432 | void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1)); |
| 433 | const char *comma; |
| 434 | if (mem == NULL) |
| 435 | return AVERROR(ENOMEM); |
| 436 | w->as = mem; |
| 437 | ++w->nb_as; |
| 438 | w->as[w->nb_as - 1].nb_streams = 0; |
| 439 | w->as[w->nb_as - 1].streams = NULL; |
| 440 | p += 3; // consume "id=" |
| 441 | q = w->as[w->nb_as - 1].id; |
| 442 | comma = strchr(p, ','); |
| 443 | if (!comma || comma - p >= sizeof(w->as[w->nb_as - 1].id)) { |
| 444 | av_log(s, AV_LOG_ERROR, "'id' in 'adaptation_sets' is malformed.\n"); |
| 445 | return AVERROR(EINVAL); |
| 446 | } |
| 447 | while (*p != ',') *q++ = *p++; |
| 448 | *q = 0; |
| 449 | p++; |
| 450 | state = parsed_id; |
| 451 | } else if (state == parsed_id && !strncmp(p, "streams=", 8)) { |
| 452 | p += 8; // consume "streams=" |
| 453 | state = parsing_streams; |
| 454 | } else if (state == parsing_streams) { |
| 455 | struct AdaptationSet *as = &w->as[w->nb_as - 1]; |
| 456 | int64_t num; |
| 457 | int ret = av_reallocp_array(&as->streams, ++as->nb_streams, |
| 458 | sizeof(*as->streams)); |
| 459 | if (ret < 0) |
| 460 | return ret; |
| 461 | num = strtoll(p, &q, 10); |
| 462 | if (!av_isdigit(*p) || (*q != ' ' && *q != '\0' && *q != ',') || |
| 463 | num < 0 || num >= s->nb_streams) { |
| 464 | av_log(s, AV_LOG_ERROR, "Invalid value for 'streams' in adapation_sets.\n"); |
| 465 | return AVERROR(EINVAL); |
| 466 | } |
| 467 | as->streams[as->nb_streams - 1] = num; |
no test coverage detected