Esempio n. 1
0
static int init(struct sd *sd)
{
    struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
    enum AVCodecID cid = mp_codec_to_av_codec_id(sd->codec);
    AVCodecContext *ctx = NULL;
    AVCodec *sub_codec = avcodec_find_decoder(cid);
    if (!sub_codec)
        goto error;
    ctx = avcodec_alloc_context3(sub_codec);
    if (!ctx)
        goto error;
    mp_lavc_set_extradata(ctx, sd->extradata, sd->extradata_len);
    if (avcodec_open2(ctx, sub_codec, NULL) < 0)
        goto error;
    priv->avctx = ctx;
    sd->priv = priv;
    priv->displayed_id = -1;
    return 0;

error:
    MP_FATAL(sd, "Could not open libavcodec subtitle decoder\n");
    av_free(ctx);
    talloc_free(priv);
    return -1;
}
Esempio n. 2
0
File: sd_lavc.c Progetto: 0x0all/mpv
static void set_mp4_vobsub_idx(AVCodecContext *avctx, char *src, int w, int h)
{
    char pal_s[128];
    int pal_s_pos = 0;
    for (int i = 0; i < 16; i++) {
        unsigned int e = AV_RB32(src + i * 4);

        // lavc doesn't accept YUV palette - "does god hate me?"
        struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
        csp.int_bits_in = 8;
        csp.int_bits_out = 8;
        float cmatrix[3][4];
        mp_get_yuv2rgb_coeffs(&csp, cmatrix);
        int c[3] = {(e >> 16) & 0xff, (e >> 8) & 0xff, e & 0xff};
        mp_map_int_color(cmatrix, 8, c);
        e = (c[2] << 16) | (c[1] << 8) | c[0];

        snprintf(pal_s + pal_s_pos, sizeof(pal_s) - pal_s_pos, "%06x%s", e,
                 i != 15 ? ", " : "");
        pal_s_pos = strlen(pal_s);
        if (pal_s_pos >= sizeof(pal_s))
            break;
    }

    char buf[256] = "";
    snprintf(buf, sizeof(buf), "size: %dx%d\npalette: %s\n", w, h, pal_s);
    mp_lavc_set_extradata(avctx, buf, strlen(buf));
}
Esempio n. 3
0
static int init(struct sd *sd)
{
    enum AVCodecID cid = mp_codec_to_av_codec_id(sd->codec->codec);

    // Supported codecs must be known to decode to paletted bitmaps
    switch (cid) {
    case AV_CODEC_ID_DVB_SUBTITLE:
    case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
    case AV_CODEC_ID_XSUB:
    case AV_CODEC_ID_DVD_SUBTITLE:
        break;
    default:
        return -1;
    }

    struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
    AVCodecContext *ctx = NULL;
    AVCodec *sub_codec = avcodec_find_decoder(cid);
    if (!sub_codec)
        goto error;
    ctx = avcodec_alloc_context3(sub_codec);
    if (!ctx)
        goto error;
    mp_lavc_set_extradata(ctx, sd->codec->extradata, sd->codec->extradata_size);
#if LIBAVCODEC_VERSION_MICRO >= 100
    if (cid == AV_CODEC_ID_HDMV_PGS_SUBTITLE) {
        // We don't always want to set this, because the ridiculously shitty
        // libavcodec API will mess with certain fields (end_display_time)
        // when setting it. On the other hand, PGS in particular needs PTS
        // mangling. While the PGS decoder doesn't modify the timestamps (just
        // reorder it), the ridiculously shitty libavcodec wants a timebase
        // anyway and for no good reason. It always sets end_display_time to
        // UINT32_MAX (which is a broken and undocumented way to say "unknown"),
        // which coincidentally won't be overridden by the ridiculously shitty
        // pkt_timebase code. also, Libav doesn't have the pkt_timebase field,
        // because Libav tends to avoid _adding_ ridiculously shitty APIs.
        priv->pkt_timebase = (AVRational){1, AV_TIME_BASE};
        ctx->pkt_timebase = priv->pkt_timebase;
    } else {
        // But old ffmpeg releases have a buggy pkt_timebase check, because the
        // shit above wasn't bad enough!
        ctx->pkt_timebase = (AVRational){0, 0};
    }
#endif
    if (avcodec_open2(ctx, sub_codec, NULL) < 0)
        goto error;
    priv->avctx = ctx;
    sd->priv = priv;
    priv->displayed_id = -1;
    priv->current_pts = MP_NOPTS_VALUE;
    priv->packer = talloc_zero(priv, struct bitmap_packer);
    return 0;

 error:
    MP_FATAL(sd, "Could not open libavcodec subtitle decoder\n");
    av_free(ctx);
    talloc_free(priv);
    return -1;
}
Esempio n. 4
0
// Copy the codec-related fields from st into avctx. This does not set the
// codec itself, only codec related header data provided by libavformat.
// The goal is to initialize a new decoder with the header data provided by
// libavformat, and unlike avcodec_copy_context(), allow the user to create
// a clean AVCodecContext for a manually selected AVCodec.
// This is strictly for decoding only.
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st)
{
    mp_lavc_set_extradata(avctx, st->extradata, st->extradata_size);
    avctx->codec_tag                = st->codec_tag;
    avctx->bit_rate                 = st->bit_rate;
    avctx->width                    = st->width;
    avctx->height                   = st->height;
    avctx->pix_fmt                  = st->pix_fmt;
    avctx->chroma_sample_location   = st->chroma_sample_location;
    avctx->sample_rate              = st->sample_rate;
    avctx->channels                 = st->channels;
    avctx->block_align              = st->block_align;
    avctx->channel_layout           = st->channel_layout;
    avctx->bits_per_coded_sample    = st->bits_per_coded_sample;
    avctx->has_b_frames             = st->has_b_frames;
}
Esempio n. 5
0
struct lavc_conv *lavc_conv_create(struct mp_log *log, const char *codec_name,
                                   char *extradata, int extradata_len)
{
    struct lavc_conv *priv = talloc_zero(NULL, struct lavc_conv);
    priv->log = log;
    priv->cur_list = talloc_array(priv, char*, 0);
    priv->codec = talloc_strdup(priv, codec_name);
    AVCodecContext *avctx = NULL;
    AVDictionary *opts = NULL;
    const char *fmt = get_lavc_format(priv->codec);
    AVCodec *codec = avcodec_find_decoder(mp_codec_to_av_codec_id(fmt));
    if (!codec)
        goto error;
    avctx = avcodec_alloc_context3(codec);
    if (!avctx)
        goto error;
    if (mp_lavc_set_extradata(avctx, extradata, extradata_len) < 0)
        goto error;
    if (strcmp(codec_name, "eia_608") == 0)
        av_dict_set(&opts, "real_time", "1", 0);
    if (avcodec_open2(avctx, codec, &opts) < 0)
        goto error;
    av_dict_free(&opts);
    // Documented as "set by libavcodec", but there is no other way
    avctx->time_base = (AVRational) {1, 1000};
#if LIBAVCODEC_VERSION_MICRO >= 100
    avctx->pkt_timebase = avctx->time_base;
#endif
    priv->avctx = avctx;
    priv->extradata = talloc_strndup(priv, avctx->subtitle_header,
                                     avctx->subtitle_header_size);
    disable_styles(bstr0(priv->extradata));
    return priv;

 error:
    MP_FATAL(priv, "Could not open libavcodec subtitle converter\n");
    av_dict_free(&opts);
    av_free(avctx);
    talloc_free(priv);
    return NULL;
}