| 3173 | } |
| 3174 | |
| 3175 | static int parse_forced_key_frames(void *log, KeyframeForceCtx *kf, |
| 3176 | const Muxer *mux, const char *spec) |
| 3177 | { |
| 3178 | const char *p; |
| 3179 | int n = 1, i, ret, size, index = 0; |
| 3180 | int64_t t, *pts; |
| 3181 | |
| 3182 | for (p = spec; *p; p++) |
| 3183 | if (*p == ',') |
| 3184 | n++; |
| 3185 | size = n; |
| 3186 | pts = av_malloc_array(size, sizeof(*pts)); |
| 3187 | if (!pts) |
| 3188 | return AVERROR(ENOMEM); |
| 3189 | |
| 3190 | p = spec; |
| 3191 | for (i = 0; i < n; i++) { |
| 3192 | char *next = strchr(p, ','); |
| 3193 | |
| 3194 | if (next) |
| 3195 | *next++ = 0; |
| 3196 | |
| 3197 | if (strstr(p, "chapters") == p) { |
| 3198 | AVChapter * const *ch = mux->fc->chapters; |
| 3199 | unsigned int nb_ch = mux->fc->nb_chapters; |
| 3200 | int j; |
| 3201 | |
| 3202 | if (nb_ch > INT_MAX - size) { |
| 3203 | ret = AVERROR(ERANGE); |
| 3204 | goto fail; |
| 3205 | } |
| 3206 | size += nb_ch - 1; |
| 3207 | pts = av_realloc_f(pts, size, sizeof(*pts)); |
| 3208 | if (!pts) |
| 3209 | return AVERROR(ENOMEM); |
| 3210 | |
| 3211 | if (p[8]) { |
| 3212 | ret = av_parse_time(&t, p + 8, 1); |
| 3213 | if (ret < 0) { |
| 3214 | av_log(log, AV_LOG_ERROR, |
| 3215 | "Invalid chapter time offset: %s\n", p + 8); |
| 3216 | goto fail; |
| 3217 | } |
| 3218 | } else |
| 3219 | t = 0; |
| 3220 | |
| 3221 | for (j = 0; j < nb_ch; j++) { |
| 3222 | const AVChapter *c = ch[j]; |
| 3223 | av_assert1(index < size); |
| 3224 | pts[index++] = av_rescale_q(c->start, c->time_base, |
| 3225 | AV_TIME_BASE_Q) + t; |
| 3226 | } |
| 3227 | |
| 3228 | } else { |
| 3229 | av_assert1(index < size); |
| 3230 | ret = av_parse_time(&t, p, 1); |
| 3231 | if (ret < 0) { |
| 3232 | av_log(log, AV_LOG_ERROR, "Invalid keyframe time: %s\n", p); |
no test coverage detected