static av_cold int init(AVFilterContext *ctx) { AConvertContext *aconvert = ctx->priv; char *arg, *ptr = NULL; int ret = 0; char *args = av_strdup(NULL); av_log(ctx, AV_LOG_WARNING, "This filter is deprecated, use aformat instead\n"); aconvert->out_sample_fmt = AV_SAMPLE_FMT_NONE; aconvert->out_chlayout = 0; if ((arg = av_strtok(args, ":", &ptr)) && strcmp(arg, "auto")) { if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0) goto end; } if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) { if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0) goto end; } end: av_freep(&args); return ret; }
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) { AResampleContext *aresample = ctx->priv; int ret = 0; char *argd = av_strdup(args); aresample->next_pts = AV_NOPTS_VALUE; aresample->swr = swr_alloc(); if (!aresample->swr) return AVERROR(ENOMEM); if (args) { char *ptr=argd, *token; while(token = av_strtok(ptr, ":", &ptr)) { char *value; av_strtok(token, "=", &value); if(value) { if((ret=av_opt_set(aresample->swr, token, value, 0)) < 0) goto end; } else { int out_rate; if ((ret = ff_parse_sample_rate(&out_rate, token, ctx)) < 0) goto end; if((ret = av_opt_set_int(aresample->swr, "osr", out_rate, 0)) < 0) goto end; } } } end: av_free(argd); return ret; }
static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque) { AConvertContext *aconvert = ctx->priv; char *arg, *ptr = NULL; int ret = 0; char *args = av_strdup(args0); aconvert->out_sample_fmt = AV_SAMPLE_FMT_NONE; aconvert->out_chlayout = 0; aconvert->out_packing_fmt = -1; if ((arg = av_strtok(args, ":", &ptr)) && strcmp(arg, "auto")) { if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0) goto end; } if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) { if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0) goto end; } if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) { if ((ret = ff_parse_packing_format((int *)&aconvert->out_packing_fmt, arg, ctx)) < 0) goto end; } end: av_freep(&args); return ret; }
static int bsf_parse_single(const char *str, AVBSFList *bsf_lst) { char *bsf_name, *bsf_options_str, *buf; AVDictionary *bsf_options = NULL; int ret = 0; if (!(buf = av_strdup(str))) return AVERROR(ENOMEM); bsf_name = av_strtok(buf, "=", &bsf_options_str); if (!bsf_name) { ret = AVERROR(EINVAL); goto end; } if (bsf_options_str) { ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0); if (ret < 0) goto end; } ret = av_bsf_list_append2(bsf_lst, bsf_name, &bsf_options); av_dict_free(&bsf_options); end: av_free(buf); return ret; }
int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst) { AVBSFList *lst; char *bsf_str, *buf, *dup, *saveptr; int ret; if (!str) return av_bsf_get_null_filter(bsf_lst); lst = av_bsf_list_alloc(); if (!lst) return AVERROR(ENOMEM); if (!(dup = buf = av_strdup(str))) return AVERROR(ENOMEM); while (1) { bsf_str = av_strtok(buf, ",", &saveptr); if (!bsf_str) break; ret = bsf_parse_single(bsf_str, lst); if (ret < 0) goto end; buf = NULL; } ret = av_bsf_list_finalize(&lst, bsf_lst); end: if (ret < 0) av_bsf_list_free(&lst); av_free(dup); return ret; }
/** * Parse list of bitstream filters and add them to the list of filters * pointed to by bsfs. * * The list must be specified in the form: * BSFS ::= BSF[,BSFS] */ static int parse_bsfs(void *log_ctx, const char *bsfs_spec, AVBitStreamFilterContext **bsfs) { char *bsf_name, *buf, *dup, *saveptr; int ret = 0; if (!(dup = buf = av_strdup(bsfs_spec))) return AVERROR(ENOMEM); while (bsf_name = av_strtok(buf, ",", &saveptr)) { AVBitStreamFilterContext *bsf = av_bitstream_filter_init(bsf_name); if (!bsf) { av_log(log_ctx, AV_LOG_ERROR, "Cannot initialize bitstream filter with name '%s', " "unknown filter or internal error happened\n", bsf_name); ret = AVERROR_UNKNOWN; goto end; } /* append bsf context to the list of bsf contexts */ *bsfs = bsf; bsfs = &bsf->next; buf = NULL; } end: av_free(dup); return ret; }
static void fill_items(char *item_str, int *nb_items, float *items) { char *p, *saveptr = NULL; int i, new_nb_items = 0; p = item_str; for (i = 0; i < *nb_items; i++) { char *tstr = av_strtok(p, "|", &saveptr); p = NULL; new_nb_items += sscanf(tstr, "%f", &items[i]) == 1; } *nb_items = new_nb_items; }
static av_cold int init(AVFilterContext *ctx) { MixContext *s = ctx->priv; char *p, *arg, *saveptr = NULL; float last_weight = 1.f; int i, ret; for (i = 0; i < s->nb_inputs; i++) { AVFilterPad pad = { 0 }; pad.type = AVMEDIA_TYPE_AUDIO; pad.name = av_asprintf("input%d", i); if (!pad.name) return AVERROR(ENOMEM); if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { av_freep(&pad.name); return ret; } } s->fdsp = avpriv_float_dsp_alloc(0); if (!s->fdsp) return AVERROR(ENOMEM); s->weights = av_mallocz_array(s->nb_inputs, sizeof(*s->weights)); if (!s->weights) return AVERROR(ENOMEM); p = s->weights_str; for (i = 0; i < s->nb_inputs; i++) { if (!(arg = av_strtok(p, " ", &saveptr))) break; p = NULL; sscanf(arg, "%f", &last_weight); s->weights[i] = last_weight; s->weight_sum += last_weight; } for (; i < s->nb_inputs; i++) { s->weights[i] = last_weight; s->weight_sum += last_weight; } return 0; }
static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque) { ABufferSourceContext *abuffer = ctx->priv; char *arg = NULL, *ptr, chlayout_str[16]; char *args = av_strdup(args0); int ret; arg = av_strtok(args, ":", &ptr); #define ADD_FORMAT(fmt_name) \ if (!arg) \ goto arg_fail; \ if ((ret = ff_parse_##fmt_name(&abuffer->fmt_name, arg, ctx)) < 0) { \ av_freep(&args); \ return ret; \ } \ if (*args) \ arg = av_strtok(NULL, ":", &ptr) ADD_FORMAT(sample_rate); ADD_FORMAT(sample_format); ADD_FORMAT(channel_layout); ADD_FORMAT(packing_format); abuffer->fifo = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*)); if (!abuffer->fifo) { av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo, filter init failed.\n"); return AVERROR(ENOMEM); } av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1, abuffer->channel_layout); av_log(ctx, AV_LOG_INFO, "format:%s layout:%s rate:%d\n", av_get_sample_fmt_name(abuffer->sample_format), chlayout_str, abuffer->sample_rate); av_freep(&args); return 0; arg_fail: av_log(ctx, AV_LOG_ERROR, "Invalid arguments, must be of the form " "sample_rate:sample_fmt:channel_layout:packing\n"); av_freep(&args); return AVERROR(EINVAL); }
static av_cold int init(AVFilterContext *ctx) { MixContext *s = ctx->priv; char *p, *arg, *saveptr = NULL; int i, ret; s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames)); if (!s->frames) return AVERROR(ENOMEM); s->weights = av_calloc(s->nb_inputs, sizeof(*s->weights)); if (!s->weights) return AVERROR(ENOMEM); for (i = 0; i < s->nb_inputs; i++) { AVFilterPad pad = { 0 }; pad.type = AVMEDIA_TYPE_VIDEO; pad.name = av_asprintf("input%d", i); if (!pad.name) return AVERROR(ENOMEM); if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { av_freep(&pad.name); return ret; } } p = s->weights_str; for (i = 0; i < s->nb_inputs; i++) { if (!(arg = av_strtok(p, " ", &saveptr))) break; p = NULL; sscanf(arg, "%f", &s->weights[i]); s->wfactor += s->weights[i]; } s->wfactor = 1 / s->wfactor; return 0; }
static av_cold int init(AVFilterContext *ctx) { ShuffleFramesContext *s = ctx->priv; char *mapping, *saveptr = NULL, *p; int n, nb_items; nb_items = 1; for (p = s->mapping; *p; p++) { if (*p == '|' || *p == ' ') nb_items++; } s->frames = av_calloc(nb_items, sizeof(*s->frames)); s->map = av_calloc(nb_items, sizeof(*s->map)); s->pts = av_calloc(nb_items, sizeof(*s->pts)); if (!s->map || !s->frames || !s->pts) { return AVERROR(ENOMEM); } mapping = av_strdup(s->mapping); if (!mapping) return AVERROR(ENOMEM); for (n = 0; n < nb_items; n++) { char *map = av_strtok(n == 0 ? mapping : NULL, " |", &saveptr); if (!map || sscanf(map, "%d", &s->map[n]) != 1) { av_free(mapping); return AVERROR(EINVAL); } if (s->map[n] < 0 || s->map[n] >= nb_items) { av_log(ctx, AV_LOG_ERROR, "Index out of range.\n"); av_free(mapping); return AVERROR(EINVAL); } } s->nb_frames = nb_items; av_free(mapping); return 0; }
static av_cold int init(AVFilterContext *ctx) { ConvolutionContext *s = ctx->priv; int i; for (i = 0; i < 4; i++) { int *matrix = (int *)s->matrix[i]; char *p, *arg, *saveptr = NULL; p = s->matrix_str[i]; while (s->matrix_length[i] < 25) { if (!(arg = av_strtok(p, " ", &saveptr))) break; p = NULL; sscanf(arg, "%d", &matrix[s->matrix_length[i]]); s->matrix_length[i]++; } if (s->matrix_length[i] == 9) { if (!memcmp(matrix, same3x3, sizeof(same3x3))) s->copy[i] = 1; else s->filter[i] = filter_3x3; } else if (s->matrix_length[i] == 25) { if (!memcmp(matrix, same5x5, sizeof(same5x5))) s->copy[i] = 1; else s->filter[i] = filter_5x5; } else { return AVERROR(EINVAL); } } return 0; }
static int plot_freqs(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; ShowFreqsContext *s = ctx->priv; const int win_size = s->win_size; char *colors, *color, *saveptr = NULL; AVFrame *out; int ch, n; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) return AVERROR(ENOMEM); for (n = 0; n < outlink->h; n++) memset(out->data[0] + out->linesize[0] * n, 0, outlink->w * 4); /* fill FFT input with the number of samples available */ for (ch = 0; ch < s->nb_channels; ch++) { const float *p = (float *)in->extended_data[ch]; for (n = 0; n < in->nb_samples; n++) { s->fft_data[ch][n].re = p[n] * s->window_func_lut[n]; s->fft_data[ch][n].im = 0; } for (; n < win_size; n++) { s->fft_data[ch][n].re = 0; s->fft_data[ch][n].im = 0; } } /* run FFT on each samples set */ for (ch = 0; ch < s->nb_channels; ch++) { av_fft_permute(s->fft, s->fft_data[ch]); av_fft_calc(s->fft, s->fft_data[ch]); } #define RE(x, ch) s->fft_data[ch][x].re #define IM(x, ch) s->fft_data[ch][x].im #define M(a, b) (sqrt((a) * (a) + (b) * (b))) colors = av_strdup(s->colors); if (!colors) { av_frame_free(&out); return AVERROR(ENOMEM); } for (ch = 0; ch < s->nb_channels; ch++) { uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff }; int prev_y = -1, f; double a; color = av_strtok(ch == 0 ? colors : NULL, " |", &saveptr); if (color) av_parse_color(fg, color, -1, ctx); a = av_clipd(M(RE(0, ch), 0) / s->scale, 0, 1); plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink); for (f = 1; f < s->nb_freq; f++) { a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1); plot_freq(s, ch, a, f, fg, &prev_y, out, outlink); } } av_free(colors); out->pts = in->pts; return ff_filter_frame(outlink, out); }
static int convolution_opencl_make_filter_params(AVFilterContext *avctx) { ConvolutionOpenCLContext *ctx = avctx->priv; float *matrix = NULL; size_t matrix_bytes; cl_mem buffer; cl_int cle; int i, j; int sscanf_err; char *p, *arg, *saveptr = NULL; float input_matrix[4][49]; for (i = 0; i < 4; i++) { ctx->biases[i] = ctx->biases[i] / 255.0; } for (i = 0; i < 4; i++) { p = ctx->matrix_str[i]; while (ctx->matrix_sizes[i] < 49) { arg = av_strtok(p, " ", &saveptr); if (!arg) { break; } p = NULL; sscanf_err = sscanf(arg, "%f", &input_matrix[i][ctx->matrix_sizes[i]]); if (sscanf_err != 1) { av_log(ctx, AV_LOG_ERROR, "Matrix is sequence of 9, 25 or 49 signed numbers\n"); return AVERROR(EINVAL); } ctx->matrix_sizes[i]++; } if (ctx->matrix_sizes[i] == 9) { ctx->dims[i] = 3; } else if (ctx->matrix_sizes[i] == 25) { ctx->dims[i] = 5; } else if (ctx->matrix_sizes[i] == 49) { ctx->dims[i] = 7; } else { av_log(ctx, AV_LOG_ERROR, "Invalid matrix size:%d\n", ctx->matrix_sizes[i]); return AVERROR(EINVAL); } } for (j = 0; j < 4; j++) { matrix_bytes = sizeof(float)*ctx->matrix_sizes[j]; matrix = av_malloc(matrix_bytes); if (!matrix) { av_freep(&matrix); return AVERROR(ENOMEM); } for (i = 0; i < ctx->matrix_sizes[j]; i++) matrix[i] = input_matrix[j][i]; buffer = clCreateBuffer(ctx->ocf.hwctx->context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR | CL_MEM_HOST_NO_ACCESS, matrix_bytes, matrix, &cle); if (!buffer) { av_log(avctx, AV_LOG_ERROR, "Failed to create matrix buffer: " "%d.\n", cle); av_freep(&matrix); return AVERROR(EIO); } ctx->matrix[j] = buffer; av_freep(&matrix); } return 0; }
static av_cold int init(AVFilterContext *ctx) { ConvolutionContext *s = ctx->priv; int i; if (!strcmp(ctx->filter->name, "convolution")) { for (i = 0; i < 4; i++) { int *matrix = (int *)s->matrix[i]; char *p, *arg, *saveptr = NULL; float sum = 0; p = s->matrix_str[i]; while (s->matrix_length[i] < 49) { if (!(arg = av_strtok(p, " ", &saveptr))) break; p = NULL; sscanf(arg, "%d", &matrix[s->matrix_length[i]]); sum += matrix[s->matrix_length[i]]; s->matrix_length[i]++; } if (s->matrix_length[i] == 9) { s->size[i] = 3; if (!memcmp(matrix, same3x3, sizeof(same3x3))) s->copy[i] = 1; else s->filter[i] = filter_3x3; } else if (s->matrix_length[i] == 25) { s->size[i] = 5; if (!memcmp(matrix, same5x5, sizeof(same5x5))) s->copy[i] = 1; else s->filter[i] = filter_5x5; } else if (s->matrix_length[i] == 49) { s->size[i] = 7; if (!memcmp(matrix, same7x7, sizeof(same7x7))) s->copy[i] = 1; else s->filter[i] = filter_7x7; } else { return AVERROR(EINVAL); } if (sum == 0) sum = 1; if (s->rdiv[i] == 0) s->rdiv[i] = 1. / sum; if (s->copy[i] && (s->rdiv[i] != 1. || s->bias[i] != 0.)) s->copy[i] = 0; } } else if (!strcmp(ctx->filter->name, "prewitt")) { for (i = 0; i < 4; i++) { if ((1 << i) & s->planes) s->filter[i] = filter_prewitt; else s->copy[i] = 1; } } else if (!strcmp(ctx->filter->name, "roberts")) { for (i = 0; i < 4; i++) { if ((1 << i) & s->planes) s->filter[i] = filter_roberts; else s->copy[i] = 1; } } else if (!strcmp(ctx->filter->name, "sobel")) { for (i = 0; i < 4; i++) { if ((1 << i) & s->planes) s->filter[i] = filter_sobel; else s->copy[i] = 1; } } return 0; }
static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src) { SAMIContext *sami = avctx->priv_data; int ret = 0; char *tag = NULL; char *dupsrc = av_strdup(src); char *p = dupsrc; av_bprint_clear(&sami->content); for (;;) { char *saveptr = NULL; int prev_chr_is_space = 0; AVBPrint *dst = &sami->content; /* parse & extract paragraph tag */ p = av_stristr(p, "<P"); if (!p) break; if (p[2] != '>' && !av_isspace(p[2])) { // avoid confusion with tags such as <PRE> p++; continue; } if (dst->len) // add a separator with the previous paragraph if there was one av_bprintf(dst, "\\N"); tag = av_strtok(p, ">", &saveptr); if (!tag || !saveptr) break; p = saveptr; /* check if the current paragraph is the "source" (speaker name) */ if (av_stristr(tag, "ID=Source") || av_stristr(tag, "ID=\"Source\"")) { dst = &sami->source; av_bprint_clear(dst); } /* if empty event -> skip subtitle */ while (av_isspace(*p)) p++; if (!strncmp(p, " ", 6)) { ret = -1; goto end; } /* extract the text, stripping most of the tags */ while (*p) { if (*p == '<') { if (!av_strncasecmp(p, "<P", 2) && (p[2] == '>' || av_isspace(p[2]))) break; if (!av_strncasecmp(p, "<BR", 3)) av_bprintf(dst, "\\N"); p++; while (*p && *p != '>') p++; if (!*p) break; if (*p == '>') p++; } if (!av_isspace(*p)) av_bprint_chars(dst, *p, 1); else if (!prev_chr_is_space) av_bprint_chars(dst, ' ', 1); prev_chr_is_space = av_isspace(*p); p++; } } av_bprint_clear(&sami->full); if (sami->source.len) av_bprintf(&sami->full, "{\\i1}%s{\\i0}\\N", sami->source.str); av_bprintf(&sami->full, "%s", sami->content.str); end: av_free(dupsrc); return ret; }
static av_cold int init_subtitles(AVFilterContext *ctx) { int j, ret, sid; int k = 0; AVDictionary *codec_opts = NULL; AVFormatContext *fmt = NULL; AVCodecContext *dec_ctx = NULL; AVCodec *dec = NULL; const AVCodecDescriptor *dec_desc; AVStream *st; AVPacket pkt; AssContext *ass = ctx->priv; /* Init libass */ ret = init(ctx); if (ret < 0) return ret; ass->track = ass_new_track(ass->library); if (!ass->track) { av_log(ctx, AV_LOG_ERROR, "Could not create a libass track\n"); return AVERROR(EINVAL); } /* Open subtitles file */ ret = avformat_open_input(&fmt, ass->filename, NULL, NULL); if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Unable to open %s\n", ass->filename); goto end; } ret = avformat_find_stream_info(fmt, NULL); if (ret < 0) goto end; /* Locate subtitles stream */ if (ass->stream_index < 0) ret = av_find_best_stream(fmt, AVMEDIA_TYPE_SUBTITLE, -1, -1, NULL, 0); else { ret = -1; if (ass->stream_index < fmt->nb_streams) { for (j = 0; j < fmt->nb_streams; j++) { if (fmt->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { if (ass->stream_index == k) { ret = j; break; } k++; } } } } if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Unable to locate subtitle stream in %s\n", ass->filename); goto end; } sid = ret; st = fmt->streams[sid]; /* Load attached fonts */ for (j = 0; j < fmt->nb_streams; j++) { AVStream *st = fmt->streams[j]; if (st->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT && attachment_is_font(st)) { const AVDictionaryEntry *tag = NULL; tag = av_dict_get(st->metadata, "filename", NULL, AV_DICT_MATCH_CASE); if (tag) { av_log(ctx, AV_LOG_DEBUG, "Loading attached font: %s\n", tag->value); ass_add_font(ass->library, tag->value, st->codecpar->extradata, st->codecpar->extradata_size); } else { av_log(ctx, AV_LOG_WARNING, "Font attachment has no filename, ignored.\n"); } } } /* Initialize fonts */ ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1); /* Open decoder */ dec = avcodec_find_decoder(st->codecpar->codec_id); if (!dec) { av_log(ctx, AV_LOG_ERROR, "Failed to find subtitle codec %s\n", avcodec_get_name(st->codecpar->codec_id)); return AVERROR(EINVAL); } dec_desc = avcodec_descriptor_get(st->codecpar->codec_id); if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) { av_log(ctx, AV_LOG_ERROR, "Only text based subtitles are currently supported\n"); return AVERROR_PATCHWELCOME; } if (ass->charenc) av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0); if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57,26,100)) av_dict_set(&codec_opts, "sub_text_format", "ass", 0); dec_ctx = avcodec_alloc_context3(dec); if (!dec_ctx) return AVERROR(ENOMEM); ret = avcodec_parameters_to_context(dec_ctx, st->codecpar); if (ret < 0) goto end; /* * This is required by the decoding process in order to rescale the * timestamps: in the current API the decoded subtitles have their pts * expressed in AV_TIME_BASE, and thus the lavc internals need to know the * stream time base in order to achieve the rescaling. * * That API is old and needs to be reworked to match behaviour with A/V. */ av_codec_set_pkt_timebase(dec_ctx, st->time_base); ret = avcodec_open2(dec_ctx, NULL, &codec_opts); if (ret < 0) goto end; if (ass->force_style) { char **list = NULL; char *temp = NULL; char *ptr = av_strtok(ass->force_style, ",", &temp); int i = 0; while (ptr) { av_dynarray_add(&list, &i, ptr); if (!list) { ret = AVERROR(ENOMEM); goto end; } ptr = av_strtok(NULL, ",", &temp); } av_dynarray_add(&list, &i, NULL); if (!list) { ret = AVERROR(ENOMEM); goto end; } ass_set_style_overrides(ass->library, list); av_free(list); } /* Decode subtitles and push them into the renderer (libass) */ if (dec_ctx->subtitle_header) ass_process_codec_private(ass->track, dec_ctx->subtitle_header, dec_ctx->subtitle_header_size); av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; while (av_read_frame(fmt, &pkt) >= 0) { int i, got_subtitle; AVSubtitle sub = {0}; if (pkt.stream_index == sid) { ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt); if (ret < 0) { av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n", av_err2str(ret)); } else if (got_subtitle) { const int64_t start_time = av_rescale_q(sub.pts, AV_TIME_BASE_Q, av_make_q(1, 1000)); const int64_t duration = sub.end_display_time; for (i = 0; i < sub.num_rects; i++) { char *ass_line = sub.rects[i]->ass; if (!ass_line) break; if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,25,100)) ass_process_data(ass->track, ass_line, strlen(ass_line)); else ass_process_chunk(ass->track, ass_line, strlen(ass_line), start_time, duration); } } } av_packet_unref(&pkt); avsubtitle_free(&sub); } end: av_dict_free(&codec_opts); avcodec_close(dec_ctx); avcodec_free_context(&dec_ctx); avformat_close_input(&fmt); return ret; }
static av_cold int init(AVFilterContext *ctx) { LADSPAContext *s = ctx->priv; LADSPA_Descriptor_Function descriptor_fn; const LADSPA_Descriptor *desc; LADSPA_PortDescriptor pd; AVFilterPad pad = { NULL }; char *p, *arg, *saveptr = NULL; unsigned long nb_ports; int i; if (!s->dl_name) { av_log(ctx, AV_LOG_ERROR, "No plugin name provided\n"); return AVERROR(EINVAL); } if (s->dl_name[0] == '/' || s->dl_name[0] == '.') { // argument is a path s->dl_handle = dlopen(s->dl_name, RTLD_LOCAL|RTLD_NOW); } else { // argument is a shared object name char *paths = av_strdup(getenv("LADSPA_PATH")); const char *separator = ":"; if (paths) { p = paths; while ((arg = av_strtok(p, separator, &saveptr)) && !s->dl_handle) { s->dl_handle = try_load(arg, s->dl_name); p = NULL; } } av_free(paths); if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) { s->dl_handle = try_load(paths, s->dl_name); av_free(paths); } if (!s->dl_handle) s->dl_handle = try_load("/usr/local/lib/ladspa", s->dl_name); if (!s->dl_handle) s->dl_handle = try_load("/usr/lib/ladspa", s->dl_name); } if (!s->dl_handle) { av_log(ctx, AV_LOG_ERROR, "Failed to load '%s'\n", s->dl_name); return AVERROR(EINVAL); } descriptor_fn = dlsym(s->dl_handle, "ladspa_descriptor"); if (!descriptor_fn) { av_log(ctx, AV_LOG_ERROR, "Could not find ladspa_descriptor: %s\n", dlerror()); return AVERROR(EINVAL); } // Find the requested plugin, or list plugins if (!s->plugin) { av_log(ctx, AV_LOG_INFO, "The '%s' library contains the following plugins:\n", s->dl_name); av_log(ctx, AV_LOG_INFO, "I = Input Channels\n"); av_log(ctx, AV_LOG_INFO, "O = Output Channels\n"); av_log(ctx, AV_LOG_INFO, "I:O %-25s %s\n", "Plugin", "Description"); av_log(ctx, AV_LOG_INFO, "\n"); for (i = 0; desc = descriptor_fn(i); i++) { unsigned long inputs = 0, outputs = 0; count_ports(desc, &inputs, &outputs); av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label, av_x_if_null(desc->Name, "?")); av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n", av_x_if_null(desc->Maker, "?")); av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n", av_x_if_null(desc->Copyright, "?")); } return AVERROR_EXIT; } else { for (i = 0;; i++) { desc = descriptor_fn(i); if (!desc) { av_log(ctx, AV_LOG_ERROR, "Could not find plugin: %s\n", s->plugin); return AVERROR(EINVAL); } if (desc->Label && !strcmp(desc->Label, s->plugin)) break; } } s->desc = desc; nb_ports = desc->PortCount; s->ipmap = av_calloc(nb_ports, sizeof(*s->ipmap)); s->opmap = av_calloc(nb_ports, sizeof(*s->opmap)); s->icmap = av_calloc(nb_ports, sizeof(*s->icmap)); s->ocmap = av_calloc(nb_ports, sizeof(*s->ocmap)); s->ictlv = av_calloc(nb_ports, sizeof(*s->ictlv)); s->octlv = av_calloc(nb_ports, sizeof(*s->octlv)); s->ctl_needs_value = av_calloc(nb_ports, sizeof(*s->ctl_needs_value)); if (!s->ipmap || !s->opmap || !s->icmap || !s->ocmap || !s->ictlv || !s->octlv || !s->ctl_needs_value) return AVERROR(ENOMEM); for (i = 0; i < nb_ports; i++) { pd = desc->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { s->ipmap[s->nb_inputs] = i; s->nb_inputs++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { s->opmap[s->nb_outputs] = i; s->nb_outputs++; } } else if (LADSPA_IS_PORT_CONTROL(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { s->icmap[s->nb_inputcontrols] = i; if (LADSPA_IS_HINT_HAS_DEFAULT(desc->PortRangeHints[i].HintDescriptor)) set_default_ctl_value(s, s->nb_inputcontrols, s->icmap, s->ictlv); else s->ctl_needs_value[s->nb_inputcontrols] = 1; s->nb_inputcontrols++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { s->ocmap[s->nb_outputcontrols] = i; s->nb_outputcontrols++; } } } // List Control Ports if "help" is specified if (s->options && !strcmp(s->options, "help")) { if (!s->nb_inputcontrols) { av_log(ctx, AV_LOG_INFO, "The '%s' plugin does not have any input controls.\n", desc->Label); } else { av_log(ctx, AV_LOG_INFO, "The '%s' plugin has the following input controls:\n", desc->Label); for (i = 0; i < s->nb_inputcontrols; i++) print_ctl_info(ctx, AV_LOG_INFO, s, i, s->icmap, s->ictlv, 0); } return AVERROR_EXIT; } // Parse control parameters p = s->options; while (s->options) { LADSPA_Data val; int ret; if (!(arg = av_strtok(p, "|", &saveptr))) break; p = NULL; if (sscanf(arg, "c%d=%f", &i, &val) != 2) { av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n"); return AVERROR(EINVAL); } if ((ret = set_control(ctx, i, val)) < 0) return ret; s->ctl_needs_value[i] = 0; } // Check if any controls are not set for (i = 0; i < s->nb_inputcontrols; i++) { if (s->ctl_needs_value[i]) { av_log(ctx, AV_LOG_ERROR, "Control c%d must be set.\n", i); print_ctl_info(ctx, AV_LOG_ERROR, s, i, s->icmap, s->ictlv, 0); return AVERROR(EINVAL); } } pad.type = AVMEDIA_TYPE_AUDIO; if (s->nb_inputs) { pad.name = av_asprintf("in0:%s%lu", desc->Label, s->nb_inputs); if (!pad.name) return AVERROR(ENOMEM); pad.filter_frame = filter_frame; pad.config_props = config_input; if (ff_insert_inpad(ctx, ctx->nb_inputs, &pad) < 0) { av_freep(&pad.name); return AVERROR(ENOMEM); } } av_log(ctx, AV_LOG_DEBUG, "ports: %lu\n", nb_ports); av_log(ctx, AV_LOG_DEBUG, "inputs: %lu outputs: %lu\n", s->nb_inputs, s->nb_outputs); av_log(ctx, AV_LOG_DEBUG, "input controls: %lu output controls: %lu\n", s->nb_inputcontrols, s->nb_outputcontrols); return 0; }
static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AFFTFiltContext *s = ctx->priv; char *saveptr = NULL; int ret = 0, ch, i; float overlap; char *args; const char *last_expr = "1"; s->fft = av_fft_init(s->fft_bits, 0); s->ifft = av_fft_init(s->fft_bits, 1); if (!s->fft || !s->ifft) return AVERROR(ENOMEM); s->window_size = 1 << s->fft_bits; s->fft_data = av_calloc(inlink->channels, sizeof(*s->fft_data)); if (!s->fft_data) return AVERROR(ENOMEM); for (ch = 0; ch < inlink->channels; ch++) { s->fft_data[ch] = av_calloc(s->window_size, sizeof(**s->fft_data)); if (!s->fft_data[ch]) return AVERROR(ENOMEM); } s->real = av_calloc(inlink->channels, sizeof(*s->real)); if (!s->real) return AVERROR(ENOMEM); s->imag = av_calloc(inlink->channels, sizeof(*s->imag)); if (!s->imag) return AVERROR(ENOMEM); args = av_strdup(s->real_str); if (!args) return AVERROR(ENOMEM); for (ch = 0; ch < inlink->channels; ch++) { char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr); ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) break; if (arg) last_expr = arg; s->nb_exprs++; } av_free(args); args = av_strdup(s->img_str ? s->img_str : s->real_str); if (!args) return AVERROR(ENOMEM); for (ch = 0; ch < inlink->channels; ch++) { char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr); ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) break; if (arg) last_expr = arg; } av_free(args); s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size); if (!s->fifo) return AVERROR(ENOMEM); s->window_func_lut = av_realloc_f(s->window_func_lut, s->window_size, sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); ff_generate_window_func(s->window_func_lut, s->window_size, s->win_func, &overlap); if (s->overlap == 1) s->overlap = overlap; for (s->win_scale = 0, i = 0; i < s->window_size; i++) { s->win_scale += s->window_func_lut[i] * s->window_func_lut[i]; } s->hop_size = s->window_size * (1 - s->overlap); if (s->hop_size <= 0) return AVERROR(EINVAL); s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2); if (!s->buffer) return AVERROR(ENOMEM); return ret; }
static av_cold int init(AVFilterContext *ctx) { SoxContext *sox = ctx->priv; char **argv = NULL; char *args1 = av_strdup(sox->filter); int argc = 0, numargs = 0, ret = 0; sox_encodinginfo_t *encoding; const sox_effect_handler_t *handler; char *saveptr; #define FAIL(err) ret = err; goto end; // initialize SoX if necessary if (soxinit != SOX_SUCCESS && (soxinit = sox_init()) != SOX_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Error when initing libsox: '%s'\n", sox_strerror(soxinit)); FAIL(AVERROR(EINVAL)); } // create arguments array if ((ret = realloc_argv(&argv, &numargs)) < 0) { FAIL(ret); } // parse arguments into a string array argv[argc++] = av_strtok(args1, " ", &saveptr); while (argv[argc++] = av_strtok(NULL, " ", &saveptr)) { if (argc == numargs) { if ((ret = realloc_argv(&argv, &numargs)) < 0) { FAIL(ret); } } } handler = sox_find_effect(argv[0]); if (!handler) { av_log(ctx, AV_LOG_ERROR, "Could not find Sox effect named '%s'\n", argv[0]); FAIL(AVERROR(EINVAL)); } sox->effect = sox_create_effect(handler); if (!sox->effect) { av_log(ctx, AV_LOG_ERROR, "Could not create Sox effect '%s'\n", argv[0]); return AVERROR(EINVAL); } if (sox->effect->handler.getopts(sox->effect, argc-1, argv) != SOX_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Invalid arguments to Sox effect\n"); if (sox->effect->handler.usage) av_log(ctx, AV_LOG_ERROR, "Usage: %s\n", sox->effect->handler.usage); return AVERROR(EINVAL); } if (!(encoding = av_mallocz(sizeof(sox_encodinginfo_t)))) return AVERROR(ENOMEM); encoding->encoding = SOX_DEFAULT_ENCODING; encoding->bits_per_sample = 32; sox->effect->out_encoding = sox->effect->in_encoding = encoding; sox->effect->clips = 0; sox->effect->imin = 0; end: av_free(args1); return ret; }
static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) { int i, ret; AVDictionary *options = NULL; AVDictionaryEntry *entry; char *filename; char *format = NULL, *select = NULL, *on_fail = NULL; AVFormatContext *avf2 = NULL; AVStream *st, *st2; int stream_count; int fullret; char *subselect = NULL, *next_subselect = NULL, *first_subselect = NULL, *tmp_select = NULL; if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0) return ret; #define STEAL_OPTION(option, field) do { \ if ((entry = av_dict_get(options, option, NULL, 0))) { \ field = entry->value; \ entry->value = NULL; /* prevent it from being freed */ \ av_dict_set(&options, option, NULL, 0); \ } \ } while (0) STEAL_OPTION("f", format); STEAL_OPTION("select", select); STEAL_OPTION("onfail", on_fail); ret = parse_slave_failure_policy_option(on_fail, tee_slave); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Invalid onfail option value, valid options are 'abort' and 'ignore'\n"); goto end; } ret = avformat_alloc_output_context2(&avf2, NULL, format, filename); if (ret < 0) goto end; tee_slave->avf = avf2; av_dict_copy(&avf2->metadata, avf->metadata, 0); avf2->opaque = avf->opaque; avf2->io_open = avf->io_open; avf2->io_close = avf->io_close; tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map)); if (!tee_slave->stream_map) { ret = AVERROR(ENOMEM); goto end; } stream_count = 0; for (i = 0; i < avf->nb_streams; i++) { st = avf->streams[i]; if (select) { tmp_select = av_strdup(select); // av_strtok is destructive so we regenerate it in each loop if (!tmp_select) { ret = AVERROR(ENOMEM); goto end; } fullret = 0; first_subselect = tmp_select; next_subselect = NULL; while (subselect = av_strtok(first_subselect, slave_select_sep, &next_subselect)) { first_subselect = NULL; ret = avformat_match_stream_specifier(avf, avf->streams[i], subselect); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Invalid stream specifier '%s' for output '%s'\n", subselect, slave); goto end; } if (ret != 0) { fullret = 1; // match break; } } av_freep(&tmp_select); if (fullret == 0) { /* no match */ tee_slave->stream_map[i] = -1; continue; } } tee_slave->stream_map[i] = stream_count++; if (!(st2 = avformat_new_stream(avf2, NULL))) { ret = AVERROR(ENOMEM); goto end; } st2->id = st->id; st2->r_frame_rate = st->r_frame_rate; st2->time_base = st->time_base; st2->start_time = st->start_time; st2->duration = st->duration; st2->nb_frames = st->nb_frames; st2->disposition = st->disposition; st2->sample_aspect_ratio = st->sample_aspect_ratio; st2->avg_frame_rate = st->avg_frame_rate; av_dict_copy(&st2->metadata, st->metadata, 0); if ((ret = avcodec_parameters_copy(st2->codecpar, st->codecpar)) < 0) goto end; } if (!(avf2->oformat->flags & AVFMT_NOFILE)) { if ((ret = avf2->io_open(avf2, &avf2->pb, filename, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n", slave, av_err2str(ret)); goto end; } } if ((ret = avformat_write_header(avf2, &options)) < 0) { av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n", slave, av_err2str(ret)); goto end; } tee_slave->header_written = 1; tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(*tee_slave->bsfs)); if (!tee_slave->bsfs) { ret = AVERROR(ENOMEM); goto end; } entry = NULL; while (entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX)) { const char *spec = entry->key + strlen("bsfs"); if (*spec) { if (strspn(spec, slave_bsfs_spec_sep) != 1) { av_log(avf, AV_LOG_ERROR, "Specifier separator in '%s' is '%c', but only characters '%s' " "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep); ret = AVERROR(EINVAL); goto end; } spec++; /* consume separator */ } for (i = 0; i < avf2->nb_streams; i++) { ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Invalid stream specifier '%s' in bsfs option '%s' for slave " "output '%s'\n", spec, entry->key, filename); goto end; } if (ret > 0) { av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave " "output '%s'\n", spec, entry->value, i, filename); if (tee_slave->bsfs[i]) { av_log(avf, AV_LOG_WARNING, "Duplicate bsfs specification associated to stream %d of slave " "output '%s', filters will be ignored\n", i, filename); continue; } ret = parse_bsfs(avf, entry->value, &tee_slave->bsfs[i]); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s' associated to " "stream %d of slave output '%s'\n", entry->value, i, filename); goto end; } } } av_dict_set(&options, entry->key, NULL, 0); } if (options) { entry = NULL; while ((entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX))) av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key); ret = AVERROR_OPTION_NOT_FOUND; goto end; } end: av_free(format); av_free(select); av_free(on_fail); av_dict_free(&options); av_freep(&tmp_select); return ret; }
/** * Create a string containing cookie values for use as a HTTP cookie header * field value for a particular path and domain from the cookie values stored in * the HTTP protocol context. The cookie string is stored in *cookies. * * @return a negative value if an error condition occurred, 0 otherwise */ static int get_cookies(HTTPContext *s, char **cookies, const char *path, const char *domain) { // cookie strings will look like Set-Cookie header field values. Multiple // Set-Cookie fields will result in multiple values delimited by a newline int ret = 0; char *next, *cookie, *set_cookies = av_strdup(s->cookies), *cset_cookies = set_cookies; if (!set_cookies) return AVERROR(EINVAL); // destroy any cookies in the dictionary. av_dict_free(&s->cookie_dict); *cookies = NULL; while ((cookie = av_strtok(set_cookies, "\n", &next))) { int domain_offset = 0; char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL; set_cookies = NULL; // store the cookie in a dict in case it is updated in the response if (parse_cookie(s, cookie, &s->cookie_dict)) av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie); while ((param = av_strtok(cookie, "; ", &next_param))) { if (cookie) { // first key-value pair is the actual cookie value cvalue = av_strdup(param); cookie = NULL; } else if (!av_strncasecmp("path=", param, 5)) { av_free(cpath); cpath = av_strdup(¶m[5]); } else if (!av_strncasecmp("domain=", param, 7)) { // if the cookie specifies a sub-domain, skip the leading dot thereby // supporting URLs that point to sub-domains and the master domain int leading_dot = (param[7] == '.'); av_free(cdomain); cdomain = av_strdup(¶m[7+leading_dot]); } else { // ignore unknown attributes } } if (!cdomain) cdomain = av_strdup(domain); // ensure all of the necessary values are valid if (!cdomain || !cpath || !cvalue) { av_log(s, AV_LOG_WARNING, "Invalid cookie found, no value, path or domain specified\n"); goto done_cookie; } // check if the request path matches the cookie path if (av_strncasecmp(path, cpath, strlen(cpath))) goto done_cookie; // the domain should be at least the size of our cookie domain domain_offset = strlen(domain) - strlen(cdomain); if (domain_offset < 0) goto done_cookie; // match the cookie domain if (av_strcasecmp(&domain[domain_offset], cdomain)) goto done_cookie; // cookie parameters match, so copy the value if (!*cookies) { if (!(*cookies = av_strdup(cvalue))) { ret = AVERROR(ENOMEM); goto done_cookie; } } else { char *tmp = *cookies; size_t str_size = strlen(cvalue) + strlen(*cookies) + 3; if (!(*cookies = av_malloc(str_size))) { ret = AVERROR(ENOMEM); goto done_cookie; } snprintf(*cookies, str_size, "%s; %s", tmp, cvalue); av_free(tmp); } done_cookie: av_freep(&cdomain); av_freep(&cpath); av_freep(&cvalue); if (ret < 0) { if (*cookies) av_freep(cookies); av_free(cset_cookies); return ret; } } av_free(cset_cookies); return 0; }
static int scc_read_header(AVFormatContext *s) { SCCContext *scc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); char line[4096], line2[4096]; int count = 0, ret = 0; ptrdiff_t len2, len; uint8_t out[4096]; FFTextReader tr; ff_text_init_avio(s, &tr, s->pb); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, 1000); st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; while (!ff_text_eof(&tr)) { const int64_t pos = ff_text_pos(&tr); char *saveptr = NULL, *lline; int hh1, mm1, ss1, fs1, i; int hh2, mm2, ss2, fs2; int64_t ts_start, ts_end; AVPacket *sub; if (count == 0) { while (!ff_text_eof(&tr)) { len = ff_subtitles_read_line(&tr, line, sizeof(line)); if (len > 13) break; } } if (!strncmp(line, "Scenarist_SCC V1.0", 18)) continue; if (sscanf(line, "%d:%d:%d%*[:;]%d", &hh1, &mm1, &ss1, &fs1) != 4) continue; ts_start = (hh1 * 3600LL + mm1 * 60LL + ss1) * 1000LL + fs1 * 33; while (!ff_text_eof(&tr)) { len2 = ff_subtitles_read_line(&tr, line2, sizeof(line2)); if (len2 > 13) break; } if (sscanf(line2, "%d:%d:%d%*[:;]%d", &hh2, &mm2, &ss2, &fs2) != 4) continue; ts_end = (hh2 * 3600LL + mm2 * 60LL + ss2) * 1000LL + fs2 * 33; count++; lline = (char *)&line; lline += 12; for (i = 0; i < 4095; i += 3) { char *ptr = av_strtok(lline, " ", &saveptr); char c1, c2, c3, c4; if (!ptr) break; if (sscanf(ptr, "%c%c%c%c", &c1, &c2, &c3, &c4) != 4) break; lline = NULL; out[i+0] = 0xfc; out[i+1] = convert(c2) | (convert(c1) << 4); out[i+2] = convert(c4) | (convert(c3) << 4); } out[i] = 0; sub = ff_subtitles_queue_insert(&scc->q, out, i, 0); if (!sub) return AVERROR(ENOMEM); sub->pos = pos; sub->pts = ts_start; sub->duration = FFMAX(1200, ts_end - ts_start); memmove(line, line2, sizeof(line)); FFSWAP(ptrdiff_t, len, len2); } ff_subtitles_queue_finalize(s, &scc->q); return ret; }
static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) { int i, ret; AVDictionary *options = NULL; AVDictionaryEntry *entry; char *filename; char *format = NULL, *select = NULL, *on_fail = NULL; char *use_fifo = NULL, *fifo_options_str = NULL; AVFormatContext *avf2 = NULL; AVStream *st, *st2; int stream_count; int fullret; char *subselect = NULL, *next_subselect = NULL, *first_subselect = NULL, *tmp_select = NULL; if ((ret = ff_tee_parse_slave_options(avf, slave, &options, &filename)) < 0) return ret; #define STEAL_OPTION(option, field) do { \ if ((entry = av_dict_get(options, option, NULL, 0))) { \ field = entry->value; \ entry->value = NULL; /* prevent it from being freed */ \ av_dict_set(&options, option, NULL, 0); \ } \ } while (0) STEAL_OPTION("f", format); STEAL_OPTION("select", select); STEAL_OPTION("onfail", on_fail); STEAL_OPTION("use_fifo", use_fifo); STEAL_OPTION("fifo_options", fifo_options_str); ret = parse_slave_failure_policy_option(on_fail, tee_slave); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Invalid onfail option value, valid options are 'abort' and 'ignore'\n"); goto end; } ret = parse_slave_fifo_options(use_fifo, fifo_options_str, tee_slave); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n", av_err2str(ret)); goto end; } if (tee_slave->use_fifo) { if (options) { char *format_options_str = NULL; ret = av_dict_get_string(options, &format_options_str, '=', ':'); if (ret < 0) goto end; ret = av_dict_set(&tee_slave->fifo_options, "format_options", format_options_str, AV_DICT_DONT_STRDUP_VAL); if (ret < 0) goto end; } if (format) { ret = av_dict_set(&tee_slave->fifo_options, "fifo_format", format, AV_DICT_DONT_STRDUP_VAL); format = NULL; if (ret < 0) goto end; } av_dict_free(&options); options = tee_slave->fifo_options; } ret = avformat_alloc_output_context2(&avf2, NULL, tee_slave->use_fifo ? "fifo" :format, filename); if (ret < 0) goto end; tee_slave->avf = avf2; av_dict_copy(&avf2->metadata, avf->metadata, 0); avf2->opaque = avf->opaque; avf2->io_open = avf->io_open; avf2->io_close = avf->io_close; avf2->interrupt_callback = avf->interrupt_callback; avf2->flags = avf->flags; tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map)); if (!tee_slave->stream_map) { ret = AVERROR(ENOMEM); goto end; } stream_count = 0; for (i = 0; i < avf->nb_streams; i++) { st = avf->streams[i]; if (select) { tmp_select = av_strdup(select); // av_strtok is destructive so we regenerate it in each loop if (!tmp_select) { ret = AVERROR(ENOMEM); goto end; } fullret = 0; first_subselect = tmp_select; next_subselect = NULL; while (subselect = av_strtok(first_subselect, slave_select_sep, &next_subselect)) { first_subselect = NULL; ret = avformat_match_stream_specifier(avf, avf->streams[i], subselect); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Invalid stream specifier '%s' for output '%s'\n", subselect, slave); goto end; } if (ret != 0) { fullret = 1; // match break; } } av_freep(&tmp_select); if (fullret == 0) { /* no match */ tee_slave->stream_map[i] = -1; continue; } } tee_slave->stream_map[i] = stream_count++; if (!(st2 = avformat_new_stream(avf2, NULL))) { ret = AVERROR(ENOMEM); goto end; } ret = ff_stream_encode_params_copy(st2, st); if (ret < 0) goto end; } ret = ff_format_output_open(avf2, filename, NULL); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n", slave, av_err2str(ret)); goto end; } if ((ret = avformat_write_header(avf2, &options)) < 0) { av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n", slave, av_err2str(ret)); goto end; } tee_slave->header_written = 1; tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(*tee_slave->bsfs)); if (!tee_slave->bsfs) { ret = AVERROR(ENOMEM); goto end; } entry = NULL; while (entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX)) { const char *spec = entry->key + strlen("bsfs"); if (*spec) { if (strspn(spec, slave_bsfs_spec_sep) != 1) { av_log(avf, AV_LOG_ERROR, "Specifier separator in '%s' is '%c', but only characters '%s' " "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep); ret = AVERROR(EINVAL); goto end; } spec++; /* consume separator */ } for (i = 0; i < avf2->nb_streams; i++) { ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Invalid stream specifier '%s' in bsfs option '%s' for slave " "output '%s'\n", spec, entry->key, filename); goto end; } if (ret > 0) { av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave " "output '%s'\n", spec, entry->value, i, filename); if (tee_slave->bsfs[i]) { av_log(avf, AV_LOG_WARNING, "Duplicate bsfs specification associated to stream %d of slave " "output '%s', filters will be ignored\n", i, filename); continue; } ret = av_bsf_list_parse_str(entry->value, &tee_slave->bsfs[i]); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s' associated to " "stream %d of slave output '%s'\n", entry->value, i, filename); goto end; } } } av_dict_set(&options, entry->key, NULL, 0); } for (i = 0; i < avf->nb_streams; i++){ int target_stream = tee_slave->stream_map[i]; if (target_stream < 0) continue; if (!tee_slave->bsfs[target_stream]) { /* Add pass-through bitstream filter */ ret = av_bsf_get_null_filter(&tee_slave->bsfs[target_stream]); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Failed to create pass-through bitstream filter: %s\n", av_err2str(ret)); goto end; } } tee_slave->bsfs[target_stream]->time_base_in = avf->streams[i]->time_base; ret = avcodec_parameters_copy(tee_slave->bsfs[target_stream]->par_in, avf->streams[i]->codecpar); if (ret < 0) goto end; ret = av_bsf_init(tee_slave->bsfs[target_stream]); if (ret < 0) { av_log(avf, AV_LOG_ERROR, "Failed to initialize bitstream filter(s): %s\n", av_err2str(ret)); goto end; } } if (options) { entry = NULL; while ((entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX))) av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key); ret = AVERROR_OPTION_NOT_FOUND; goto end; } end: av_free(format); av_free(select); av_free(on_fail); av_dict_free(&options); av_freep(&tmp_select); return ret; }
static av_cold int frei0r_init(AVFilterContext *ctx, const char *dl_name, int type) { Frei0rContext *frei0r = ctx->priv; f0r_init_f f0r_init; f0r_get_plugin_info_f f0r_get_plugin_info; f0r_plugin_info_t *pi; char *path; /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */ if ((path = av_strdup(getenv("FREI0R_PATH")))) { char *p, *ptr = NULL; for (p = path; p = av_strtok(p, ":", &ptr); p = NULL) if (frei0r->dl_handle = load_path(ctx, p, dl_name)) break; av_free(path); } if (!frei0r->dl_handle && (path = getenv("HOME"))) { char prefix[1024]; snprintf(prefix, sizeof(prefix), "%s/.frei0r-1/lib/", path); frei0r->dl_handle = load_path(ctx, prefix, dl_name); } if (!frei0r->dl_handle) frei0r->dl_handle = load_path(ctx, "/usr/local/lib/frei0r-1/", dl_name); if (!frei0r->dl_handle) frei0r->dl_handle = load_path(ctx, "/usr/lib/frei0r-1/", dl_name); if (!frei0r->dl_handle) { av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dl_name); return AVERROR(EINVAL); } if (!(f0r_init = load_sym(ctx, "f0r_init" )) || !(f0r_get_plugin_info = load_sym(ctx, "f0r_get_plugin_info")) || !(frei0r->get_param_info = load_sym(ctx, "f0r_get_param_info" )) || !(frei0r->get_param_value = load_sym(ctx, "f0r_get_param_value")) || !(frei0r->set_param_value = load_sym(ctx, "f0r_set_param_value")) || !(frei0r->update = load_sym(ctx, "f0r_update" )) || !(frei0r->construct = load_sym(ctx, "f0r_construct" )) || !(frei0r->destruct = load_sym(ctx, "f0r_destruct" )) || !(frei0r->deinit = load_sym(ctx, "f0r_deinit" ))) return AVERROR(EINVAL); if (f0r_init() < 0) { av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module"); return AVERROR(EINVAL); } f0r_get_plugin_info(&frei0r->plugin_info); pi = &frei0r->plugin_info; if (pi->plugin_type != type) { av_log(ctx, AV_LOG_ERROR, "Invalid type '%s' for the plugin\n", pi->plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" : pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" : pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" : pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown"); return AVERROR(EINVAL); } av_log(ctx, AV_LOG_VERBOSE, "name:%s author:'%s' explanation:'%s' color_model:%s " "frei0r_version:%d version:%d.%d num_params:%d\n", pi->name, pi->author, pi->explanation, pi->color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" : pi->color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" : pi->color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown", pi->frei0r_version, pi->major_version, pi->minor_version, pi->num_params); return 0; }
static av_cold int frei0r_init(AVFilterContext *ctx, const char *dl_name, int type) { Frei0rContext *s = ctx->priv; f0r_init_f f0r_init; f0r_get_plugin_info_f f0r_get_plugin_info; f0r_plugin_info_t *pi; char *path; int ret = 0; int i; static const char* const frei0r_pathlist[] = { "/usr/local/lib/frei0r-1/", "/usr/lib/frei0r-1/", "/usr/local/lib64/frei0r-1/", "/usr/lib64/frei0r-1/" }; if (!dl_name) { av_log(ctx, AV_LOG_ERROR, "No filter name provided.\n"); return AVERROR(EINVAL); } /* see: http://frei0r.dyne.org/codedoc/html/group__pluglocations.html */ if ((path = av_strdup(getenv("FREI0R_PATH")))) { #ifdef _WIN32 const char *separator = ";"; #else const char *separator = ":"; #endif char *p, *ptr = NULL; for (p = path; p = av_strtok(p, separator, &ptr); p = NULL) { /* add additional trailing slash in case it is missing */ char *p1 = av_asprintf("%s/", p); if (!p1) { ret = AVERROR(ENOMEM); goto check_path_end; } ret = load_path(ctx, &s->dl_handle, p1, dl_name); av_free(p1); if (ret < 0) goto check_path_end; if (s->dl_handle) break; } check_path_end: av_free(path); if (ret < 0) return ret; } if (!s->dl_handle && (path = getenv("HOME"))) { char *prefix = av_asprintf("%s/.frei0r-1/lib/", path); if (!prefix) return AVERROR(ENOMEM); ret = load_path(ctx, &s->dl_handle, prefix, dl_name); av_free(prefix); if (ret < 0) return ret; } for (i = 0; !s->dl_handle && i < FF_ARRAY_ELEMS(frei0r_pathlist); i++) { ret = load_path(ctx, &s->dl_handle, frei0r_pathlist[i], dl_name); if (ret < 0) return ret; } if (!s->dl_handle) { av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'.\n", dl_name); return AVERROR(EINVAL); } if (!(f0r_init = load_sym(ctx, "f0r_init" )) || !(f0r_get_plugin_info = load_sym(ctx, "f0r_get_plugin_info")) || !(s->get_param_info = load_sym(ctx, "f0r_get_param_info" )) || !(s->get_param_value = load_sym(ctx, "f0r_get_param_value")) || !(s->set_param_value = load_sym(ctx, "f0r_set_param_value")) || !(s->update = load_sym(ctx, "f0r_update" )) || !(s->construct = load_sym(ctx, "f0r_construct" )) || !(s->destruct = load_sym(ctx, "f0r_destruct" )) || !(s->deinit = load_sym(ctx, "f0r_deinit" ))) return AVERROR(EINVAL); if (f0r_init() < 0) { av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module.\n"); return AVERROR(EINVAL); } f0r_get_plugin_info(&s->plugin_info); pi = &s->plugin_info; if (pi->plugin_type != type) { av_log(ctx, AV_LOG_ERROR, "Invalid type '%s' for this plugin\n", pi->plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" : pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" : pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" : pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown"); return AVERROR(EINVAL); } av_log(ctx, AV_LOG_VERBOSE, "name:%s author:'%s' explanation:'%s' color_model:%s " "frei0r_version:%d version:%d.%d num_params:%d\n", pi->name, pi->author, pi->explanation, pi->color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" : pi->color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" : pi->color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown", pi->frei0r_version, pi->major_version, pi->minor_version, pi->num_params); return 0; }