Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/**
 * 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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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);
}
Beispiel #14
0
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;
}
Beispiel #15
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;
}
Beispiel #16
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, "&nbsp;", 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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
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;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
/**
 * 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(&param[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(&param[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;
}
Beispiel #23
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
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;
}