tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bsf.c (13763B)


      1 /*
      2 * This file is part of FFmpeg.
      3 *
      4 * FFmpeg is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU Lesser General Public
      6 * License as published by the Free Software Foundation; either
      7 * version 2.1 of the License, or (at your option) any later version.
      8 *
      9 * FFmpeg is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with FFmpeg; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17 */
     18 
     19 #include <string.h>
     20 
     21 #include "config_components.h"
     22 
     23 #include "libavutil/avassert.h"
     24 #include "libavutil/log.h"
     25 #include "libavutil/mem.h"
     26 #include "libavutil/opt.h"
     27 #include "libavutil/avstring.h"
     28 #include "libavutil/bprint.h"
     29 
     30 #include "bsf.h"
     31 #include "bsf_internal.h"
     32 #include "codec_desc.h"
     33 #include "codec_par.h"
     34 #include "packet_internal.h"
     35 
     36 static av_always_inline const FFBitStreamFilter *ff_bsf(const AVBitStreamFilter *bsf)
     37 {
     38    return (const FFBitStreamFilter*)bsf;
     39 }
     40 
     41 typedef struct FFBSFContext {
     42    AVBSFContext pub;
     43    AVPacket *buffer_pkt;
     44    int eof;
     45 } FFBSFContext;
     46 
     47 static av_always_inline FFBSFContext *ffbsfcontext(AVBSFContext *ctx)
     48 {
     49    return (FFBSFContext *)ctx;
     50 }
     51 
     52 void av_bsf_free(AVBSFContext **pctx)
     53 {
     54    AVBSFContext *ctx;
     55    FFBSFContext *bsfi;
     56 
     57    if (!pctx || !*pctx)
     58        return;
     59    ctx  = *pctx;
     60    bsfi = ffbsfcontext(ctx);
     61 
     62    if (ctx->priv_data) {
     63        if (ff_bsf(ctx->filter)->close)
     64            ff_bsf(ctx->filter)->close(ctx);
     65        if (ctx->filter->priv_class)
     66            av_opt_free(ctx->priv_data);
     67        av_freep(&ctx->priv_data);
     68    }
     69    av_packet_free(&bsfi->buffer_pkt);
     70 
     71    avcodec_parameters_free(&ctx->par_in);
     72    avcodec_parameters_free(&ctx->par_out);
     73 
     74    av_freep(pctx);
     75 }
     76 
     77 static void *bsf_child_next(void *obj, void *prev)
     78 {
     79    AVBSFContext *ctx = obj;
     80    if (!prev && ctx->filter->priv_class)
     81        return ctx->priv_data;
     82    return NULL;
     83 }
     84 
     85 static const char *bsf_to_name(void *bsf)
     86 {
     87    return ((AVBSFContext *)bsf)->filter->name;
     88 }
     89 
     90 static const AVClass bsf_class = {
     91    .class_name       = "AVBSFContext",
     92    .item_name        = bsf_to_name,
     93    .version          = LIBAVUTIL_VERSION_INT,
     94    .child_next       = bsf_child_next,
     95    .child_class_iterate = ff_bsf_child_class_iterate,
     96    .category         = AV_CLASS_CATEGORY_BITSTREAM_FILTER,
     97 };
     98 
     99 const AVClass *av_bsf_get_class(void)
    100 {
    101    return &bsf_class;
    102 }
    103 
    104 int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
    105 {
    106    AVBSFContext *ctx;
    107    FFBSFContext *bsfi;
    108    int ret;
    109 
    110    bsfi = av_mallocz(sizeof(*bsfi));
    111    if (!bsfi)
    112        return AVERROR(ENOMEM);
    113    ctx  = &bsfi->pub;
    114 
    115    ctx->av_class = &bsf_class;
    116    ctx->filter   = filter;
    117 
    118    ctx->par_in  = avcodec_parameters_alloc();
    119    ctx->par_out = avcodec_parameters_alloc();
    120    if (!ctx->par_in || !ctx->par_out) {
    121        ret = AVERROR(ENOMEM);
    122        goto fail;
    123    }
    124    /* allocate priv data and init private options */
    125    if (ff_bsf(filter)->priv_data_size) {
    126        ctx->priv_data = av_mallocz(ff_bsf(filter)->priv_data_size);
    127        if (!ctx->priv_data) {
    128            ret = AVERROR(ENOMEM);
    129            goto fail;
    130        }
    131        if (filter->priv_class) {
    132            *(const AVClass **)ctx->priv_data = filter->priv_class;
    133            av_opt_set_defaults(ctx->priv_data);
    134        }
    135    }
    136    bsfi->buffer_pkt = av_packet_alloc();
    137    if (!bsfi->buffer_pkt) {
    138        ret = AVERROR(ENOMEM);
    139        goto fail;
    140    }
    141 
    142    *pctx = ctx;
    143    return 0;
    144 fail:
    145    av_bsf_free(&ctx);
    146    return ret;
    147 }
    148 
    149 int av_bsf_init(AVBSFContext *ctx)
    150 {
    151    int ret, i;
    152 
    153    /* check that the codec is supported */
    154    if (ctx->filter->codec_ids) {
    155        for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++)
    156            if (ctx->par_in->codec_id == ctx->filter->codec_ids[i])
    157                break;
    158        if (ctx->filter->codec_ids[i] == AV_CODEC_ID_NONE) {
    159            const AVCodecDescriptor *desc = avcodec_descriptor_get(ctx->par_in->codec_id);
    160            av_log(ctx, AV_LOG_ERROR, "Codec '%s' (%d) is not supported by the "
    161                   "bitstream filter '%s'. Supported codecs are: ",
    162                   desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name);
    163            for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) {
    164                enum AVCodecID codec_id = ctx->filter->codec_ids[i];
    165                av_log(ctx, AV_LOG_ERROR, "%s (%d) ",
    166                       avcodec_get_name(codec_id), codec_id);
    167            }
    168            av_log(ctx, AV_LOG_ERROR, "\n");
    169            return AVERROR(EINVAL);
    170        }
    171    }
    172 
    173    /* initialize output parameters to be the same as input
    174     * init below might overwrite that */
    175    ret = avcodec_parameters_copy(ctx->par_out, ctx->par_in);
    176    if (ret < 0)
    177        return ret;
    178 
    179    ctx->time_base_out = ctx->time_base_in;
    180 
    181    if (ff_bsf(ctx->filter)->init) {
    182        ret = ff_bsf(ctx->filter)->init(ctx);
    183        if (ret < 0)
    184            return ret;
    185    }
    186 
    187    return 0;
    188 }
    189 
    190 void av_bsf_flush(AVBSFContext *ctx)
    191 {
    192    FFBSFContext *const bsfi = ffbsfcontext(ctx);
    193 
    194    bsfi->eof = 0;
    195 
    196    av_packet_unref(bsfi->buffer_pkt);
    197 
    198    if (ff_bsf(ctx->filter)->flush)
    199        ff_bsf(ctx->filter)->flush(ctx);
    200 }
    201 
    202 int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
    203 {
    204    FFBSFContext *const bsfi = ffbsfcontext(ctx);
    205    int ret;
    206 
    207    if (!pkt || AVPACKET_IS_EMPTY(pkt)) {
    208        if (pkt)
    209            av_packet_unref(pkt);
    210        bsfi->eof = 1;
    211        return 0;
    212    }
    213 
    214    if (bsfi->eof) {
    215        av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n");
    216        return AVERROR(EINVAL);
    217    }
    218 
    219    if (!AVPACKET_IS_EMPTY(bsfi->buffer_pkt))
    220        return AVERROR(EAGAIN);
    221 
    222    ret = av_packet_make_refcounted(pkt);
    223    if (ret < 0)
    224        return ret;
    225    av_packet_move_ref(bsfi->buffer_pkt, pkt);
    226 
    227    return 0;
    228 }
    229 
    230 int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
    231 {
    232    return ff_bsf(ctx->filter)->filter(ctx, pkt);
    233 }
    234 
    235 int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
    236 {
    237    FFBSFContext *const bsfi = ffbsfcontext(ctx);
    238    AVPacket *tmp_pkt;
    239 
    240    if (bsfi->eof)
    241        return AVERROR_EOF;
    242 
    243    if (AVPACKET_IS_EMPTY(bsfi->buffer_pkt))
    244        return AVERROR(EAGAIN);
    245 
    246    tmp_pkt = av_packet_alloc();
    247    if (!tmp_pkt)
    248        return AVERROR(ENOMEM);
    249 
    250    *pkt = bsfi->buffer_pkt;
    251    bsfi->buffer_pkt = tmp_pkt;
    252 
    253    return 0;
    254 }
    255 
    256 int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
    257 {
    258    FFBSFContext *const bsfi = ffbsfcontext(ctx);
    259 
    260    if (bsfi->eof)
    261        return AVERROR_EOF;
    262 
    263    if (AVPACKET_IS_EMPTY(bsfi->buffer_pkt))
    264        return AVERROR(EAGAIN);
    265 
    266    av_packet_move_ref(pkt, bsfi->buffer_pkt);
    267 
    268    return 0;
    269 }
    270 
    271 typedef struct BSFListContext {
    272    const AVClass *class;
    273 
    274    AVBSFContext **bsfs;
    275    int nb_bsfs;
    276 
    277    unsigned idx;           // index of currently processed BSF
    278 
    279    char * item_name;
    280 } BSFListContext;
    281 
    282 
    283 static int bsf_list_init(AVBSFContext *bsf)
    284 {
    285    BSFListContext *lst = bsf->priv_data;
    286    int ret, i;
    287    const AVCodecParameters *cod_par = bsf->par_in;
    288    AVRational tb = bsf->time_base_in;
    289 
    290    for (i = 0; i < lst->nb_bsfs; ++i) {
    291        ret = avcodec_parameters_copy(lst->bsfs[i]->par_in, cod_par);
    292        if (ret < 0)
    293            goto fail;
    294 
    295        lst->bsfs[i]->time_base_in = tb;
    296 
    297        ret = av_bsf_init(lst->bsfs[i]);
    298        if (ret < 0)
    299            goto fail;
    300 
    301        cod_par = lst->bsfs[i]->par_out;
    302        tb = lst->bsfs[i]->time_base_out;
    303    }
    304 
    305    bsf->time_base_out = tb;
    306    ret = avcodec_parameters_copy(bsf->par_out, cod_par);
    307 
    308 fail:
    309    return ret;
    310 }
    311 
    312 static int bsf_list_filter(AVBSFContext *bsf, AVPacket *out)
    313 {
    314    BSFListContext *lst = bsf->priv_data;
    315    int ret, eof = 0;
    316 
    317    if (!lst->nb_bsfs)
    318        return ff_bsf_get_packet_ref(bsf, out);
    319 
    320    while (1) {
    321        /* get a packet from the previous filter up the chain */
    322        if (lst->idx)
    323            ret = av_bsf_receive_packet(lst->bsfs[lst->idx-1], out);
    324        else
    325            ret = ff_bsf_get_packet_ref(bsf, out);
    326        if (ret == AVERROR(EAGAIN)) {
    327            if (!lst->idx)
    328                return ret;
    329            lst->idx--;
    330            continue;
    331        } else if (ret == AVERROR_EOF) {
    332            eof = 1;
    333        } else if (ret < 0)
    334            return ret;
    335 
    336        /* send it to the next filter down the chain */
    337        if (lst->idx < lst->nb_bsfs) {
    338            ret = av_bsf_send_packet(lst->bsfs[lst->idx], eof ? NULL : out);
    339            av_assert1(ret != AVERROR(EAGAIN));
    340            if (ret < 0) {
    341                av_packet_unref(out);
    342                return ret;
    343            }
    344            lst->idx++;
    345            eof = 0;
    346        } else if (eof) {
    347            return ret;
    348        } else {
    349            return 0;
    350        }
    351    }
    352 }
    353 
    354 static void bsf_list_flush(AVBSFContext *bsf)
    355 {
    356    BSFListContext *lst = bsf->priv_data;
    357 
    358    for (int i = 0; i < lst->nb_bsfs; i++)
    359        av_bsf_flush(lst->bsfs[i]);
    360    lst->idx = 0;
    361 }
    362 
    363 static void bsf_list_close(AVBSFContext *bsf)
    364 {
    365    BSFListContext *lst = bsf->priv_data;
    366    int i;
    367 
    368    for (i = 0; i < lst->nb_bsfs; ++i)
    369        av_bsf_free(&lst->bsfs[i]);
    370    av_freep(&lst->bsfs);
    371    av_freep(&lst->item_name);
    372 }
    373 
    374 static const char *bsf_list_item_name(void *ctx)
    375 {
    376    static const char *null_filter_name = "null";
    377    AVBSFContext *bsf_ctx = ctx;
    378    BSFListContext *lst = bsf_ctx->priv_data;
    379 
    380    if (!lst->nb_bsfs)
    381        return null_filter_name;
    382 
    383    if (!lst->item_name) {
    384        int i;
    385        AVBPrint bp;
    386        av_bprint_init(&bp, 16, 128);
    387 
    388        av_bprintf(&bp, "bsf_list(");
    389        for (i = 0; i < lst->nb_bsfs; i++)
    390            av_bprintf(&bp, i ? ",%s" : "%s", lst->bsfs[i]->filter->name);
    391        av_bprintf(&bp, ")");
    392 
    393        av_bprint_finalize(&bp, &lst->item_name);
    394    }
    395 
    396    return lst->item_name;
    397 }
    398 
    399 static const AVClass bsf_list_class = {
    400        .class_name = "bsf_list",
    401        .item_name  = bsf_list_item_name,
    402        .version    = LIBAVUTIL_VERSION_INT,
    403 };
    404 
    405 static const FFBitStreamFilter list_bsf = {
    406        .p.name         = "bsf_list",
    407        .p.priv_class   = &bsf_list_class,
    408        .priv_data_size = sizeof(BSFListContext),
    409        .init           = bsf_list_init,
    410        .filter         = bsf_list_filter,
    411        .flush          = bsf_list_flush,
    412        .close          = bsf_list_close,
    413 };
    414 
    415 struct AVBSFList {
    416    AVBSFContext **bsfs;
    417    int nb_bsfs;
    418 };
    419 
    420 AVBSFList *av_bsf_list_alloc(void)
    421 {
    422    return av_mallocz(sizeof(AVBSFList));
    423 }
    424 
    425 void av_bsf_list_free(AVBSFList **lst)
    426 {
    427    int i;
    428 
    429    if (!*lst)
    430        return;
    431 
    432    for (i = 0; i < (*lst)->nb_bsfs; ++i)
    433        av_bsf_free(&(*lst)->bsfs[i]);
    434    av_free((*lst)->bsfs);
    435    av_freep(lst);
    436 }
    437 
    438 int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf)
    439 {
    440    return av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf);
    441 }
    442 
    443 static int bsf_list_append_internal(AVBSFList *lst, const char *bsf_name, const char *options, AVDictionary ** options_dict)
    444 {
    445    int ret;
    446    const AVBitStreamFilter *filter;
    447    AVBSFContext *bsf;
    448 
    449    filter = av_bsf_get_by_name(bsf_name);
    450    if (!filter)
    451        return AVERROR_BSF_NOT_FOUND;
    452 
    453    ret = av_bsf_alloc(filter, &bsf);
    454    if (ret < 0)
    455        return ret;
    456 
    457    if (options && filter->priv_class) {
    458        const AVOption *opt = av_opt_next(bsf->priv_data, NULL);
    459        const char * shorthand[2] = {NULL};
    460 
    461        if (opt)
    462            shorthand[0] = opt->name;
    463 
    464        ret = av_opt_set_from_string(bsf->priv_data, options, shorthand, "=", ":");
    465        if (ret < 0)
    466            goto end;
    467    }
    468 
    469    if (options_dict) {
    470        ret = av_opt_set_dict2(bsf, options_dict, AV_OPT_SEARCH_CHILDREN);
    471        if (ret < 0)
    472            goto end;
    473    }
    474 
    475    ret = av_bsf_list_append(lst, bsf);
    476 
    477 end:
    478    if (ret < 0)
    479        av_bsf_free(&bsf);
    480 
    481    return ret;
    482 }
    483 
    484 int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options)
    485 {
    486    return bsf_list_append_internal(lst, bsf_name, NULL, options);
    487 }
    488 
    489 int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf)
    490 {
    491    int ret = 0;
    492    BSFListContext *ctx;
    493 
    494    if ((*lst)->nb_bsfs == 1) {
    495        *bsf = (*lst)->bsfs[0];
    496        av_freep(&(*lst)->bsfs);
    497        (*lst)->nb_bsfs = 0;
    498        goto end;
    499    }
    500 
    501    ret = av_bsf_alloc(&list_bsf.p, bsf);
    502    if (ret < 0)
    503        return ret;
    504 
    505    ctx = (*bsf)->priv_data;
    506 
    507    ctx->bsfs = (*lst)->bsfs;
    508    ctx->nb_bsfs = (*lst)->nb_bsfs;
    509 
    510 end:
    511    av_freep(lst);
    512    return ret;
    513 }
    514 
    515 static int bsf_parse_single(char *str, AVBSFList *bsf_lst)
    516 {
    517    char *bsf_name, *bsf_options_str;
    518 
    519    bsf_name = av_strtok(str, "=", &bsf_options_str);
    520    if (!bsf_name)
    521        return AVERROR(EINVAL);
    522 
    523    return bsf_list_append_internal(bsf_lst, bsf_name, bsf_options_str, NULL);
    524 }
    525 
    526 int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst)
    527 {
    528    AVBSFList *lst;
    529    int ret;
    530 
    531    if (!str)
    532        return av_bsf_get_null_filter(bsf_lst);
    533 
    534    lst = av_bsf_list_alloc();
    535    if (!lst)
    536        return AVERROR(ENOMEM);
    537 
    538    do {
    539        char *bsf_str = av_get_token(&str, ",");
    540        ret = bsf_parse_single(bsf_str, lst);
    541        av_free(bsf_str);
    542        if (ret < 0)
    543            goto end;
    544    } while (*str && *++str);
    545 
    546    ret = av_bsf_list_finalize(&lst, bsf_lst);
    547 end:
    548    if (ret < 0)
    549        av_bsf_list_free(&lst);
    550    return ret;
    551 }
    552 
    553 int av_bsf_get_null_filter(AVBSFContext **bsf)
    554 {
    555 #if CONFIG_NULL_BSF
    556    extern const FFBitStreamFilter ff_null_bsf;
    557    return av_bsf_alloc(&ff_null_bsf.p, bsf);
    558 #else
    559    return av_bsf_alloc(&list_bsf.p, bsf);
    560 #endif
    561 }