static int init(struct sd *sd) { struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv); AVCodecContext *avctx = NULL; AVCodec *codec = avcodec_find_decoder(mp_codec_to_av_codec_id(sd->codec)); if (!codec) goto error; avctx = avcodec_alloc_context3(codec); if (!avctx) goto error; avctx->extradata_size = sd->extradata_len; avctx->extradata = sd->extradata; if (avcodec_open2(avctx, codec, NULL) < 0) goto error; // Documented as "set by libavcodec", but there is no other way avctx->time_base = (AVRational) {1, 1000}; priv->avctx = avctx; sd->priv = priv; sd->output_codec = "ass"; sd->output_extradata = avctx->subtitle_header; sd->output_extradata_len = avctx->subtitle_header_size; if (sd->output_extradata) { sd->output_extradata = talloc_memdup(sd, sd->output_extradata, sd->output_extradata_len); disable_styles((bstr){sd->output_extradata, sd->output_extradata_len}); } return 0; error: mp_msg(MSGT_SUBREADER, MSGL_ERR, "Could not open libavcodec subtitle converter\n"); av_free(avctx); talloc_free(priv); return -1; }
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; }
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; 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; avctx->extradata_size = extradata_len; avctx->extradata = talloc_memdup(priv, extradata, extradata_len); if (avcodec_open2(avctx, codec, NULL) < 0) goto error; // Documented as "set by libavcodec", but there is no other way avctx->time_base = (AVRational) {1, 1000}; 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_free(avctx); talloc_free(priv); return NULL; }
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; }
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, const char *decoder) { hwdec_request_api(info, "vda"); if (!find_codec(mp_codec_to_av_codec_id(decoder), FF_PROFILE_UNKNOWN)) return HWDEC_ERR_NO_CODEC; return 0; }
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, const char *decoder) { hwdec_request_api(info, "dxva2"); // we can do without too for (int i = 0; dxva2_modes[i].guid; i++) { const dxva2_mode *mode = &dxva2_modes[i]; if (mp_codec_to_av_codec_id(decoder) == mode->codec) return 0; } return HWDEC_ERR_NO_CODEC; }
static bool supports_format(const char *format) { enum AVCodecID cid = mp_codec_to_av_codec_id(format); // 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: return true; default: return false; } }
static int init(struct dec_audio *da, const char *decoder) { struct spdifContext *spdif_ctx = talloc_zero(NULL, struct spdifContext); da->priv = spdif_ctx; spdif_ctx->log = da->log; spdif_ctx->use_dts_hd = da->opts->dtshd; spdif_ctx->pool = mp_audio_pool_create(spdif_ctx); if (strcmp(decoder, "dts-hd") == 0) { decoder = "dts"; spdif_ctx->use_dts_hd = true; } spdif_ctx->codec_id = mp_codec_to_av_codec_id(decoder); return spdif_ctx->codec_id != AV_CODEC_ID_NONE; }
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, const char *decoder) { hwdec_request_api(info, "videotoolbox"); if (!info || !info->hwctx) return HWDEC_ERR_NO_CTX; switch (mp_codec_to_av_codec_id(decoder)) { case AV_CODEC_ID_H264: case AV_CODEC_ID_H263: case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: case AV_CODEC_ID_MPEG4: break; default: return HWDEC_ERR_NO_CODEC; } return 0; }
static bool supports_format(const char *format) { format = get_lavc_format(format); enum AVCodecID cid = mp_codec_to_av_codec_id(format); const AVCodecDescriptor *desc = avcodec_descriptor_get(cid); if (!desc) return false; // These are known to support AVSubtitleRect->ass. const char *whitelist[] = {"text", "ass", "ssa", "srt", "subrip", "microdvd", "mpl2", "jacosub", "pjs", "sami", "realtext", "subviewer", "subviewer1", "vplayer", "webvtt", 0}; for (int n = 0; whitelist[n]; n++) { if (strcmp(format, whitelist[n]) == 0) return true; } return false; }
AVCodecParameters *mp_codec_params_to_av(struct mp_codec_params *c) { AVCodecParameters *avp = avcodec_parameters_alloc(); if (!avp) return NULL; // If we have lavf demuxer params, they overwrite by definition any others. if (c->lav_codecpar) { if (avcodec_parameters_copy(avp, c->lav_codecpar) < 0) goto error; return avp; } avp->codec_type = mp_to_av_stream_type(c->type); avp->codec_id = mp_codec_to_av_codec_id(c->codec); avp->codec_tag = c->codec_tag; if (c->extradata_size) { avp->extradata = av_mallocz(c->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!avp->extradata) goto error; avp->extradata_size = c->extradata_size; memcpy(avp->extradata, c->extradata, avp->extradata_size); } avp->bits_per_coded_sample = c->bits_per_coded_sample; // Video only avp->width = c->disp_w; avp->height = c->disp_h; // Audio only avp->sample_rate = c->samplerate; avp->bit_rate = c->bitrate; avp->block_align = c->block_align; avp->channels = c->channels.num; if (!mp_chmap_is_unknown(&c->channels)) avp->channel_layout = mp_chmap_to_lavc(&c->channels); return avp; error: avcodec_parameters_free(&avp); return NULL; }
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; }
static bool supports_format(const char *format) { enum AVCodecID cid = mp_codec_to_av_codec_id(format); const AVCodecDescriptor *desc = avcodec_descriptor_get(cid); if (!desc) return false; #if HAVE_AV_CODEC_PROP_TEXT_SUB // These are documented to support AVSubtitleRect->ass. return desc->props & AV_CODEC_PROP_TEXT_SUB; #else const char *whitelist[] = {"text", "ass", "ssa", "mov_text", "srt", "subrip", "microdvd", "mpl2", "jacosub", "pjs", "sami", "realtext", "subviewer", "subviewer1", "vplayer", "webvtt", 0}; for (int n = 0; whitelist[n]; n++) { if (strcmp(format, whitelist[n]) == 0) return true; } return false; #endif }
static int init(sh_audio_t *sh, const char *decoder) { int x, in_size, srate, bps, *dtshd_rate; unsigned char *start; double pts; AVFormatContext *lavf_ctx = NULL; AVStream *stream = NULL; const AVOption *opt = NULL; struct spdifContext *spdif_ctx = NULL; spdif_ctx = av_mallocz(sizeof(*spdif_ctx)); if (!spdif_ctx) goto fail; spdif_ctx->lavf_ctx = avformat_alloc_context(); if (!spdif_ctx->lavf_ctx) goto fail; sh->context = spdif_ctx; lavf_ctx = spdif_ctx->lavf_ctx; lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL); if (!lavf_ctx->oformat) goto fail; lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size); if (!lavf_ctx->priv_data) goto fail; lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx, read_packet, write_packet, seek); if (!lavf_ctx->pb) goto fail; stream = avformat_new_stream(lavf_ctx, 0); if (!stream) goto fail; lavf_ctx->duration = AV_NOPTS_VALUE; lavf_ctx->start_time = AV_NOPTS_VALUE; lavf_ctx->streams[0]->codec->codec_id = mp_codec_to_av_codec_id(decoder); lavf_ctx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) { mp_msg(MSGT_DECAUDIO,MSGL_INFO, "This codec is not supported by spdifenc.\n"); goto fail; } // get sample_rate & bitrate from parser x = ds_get_packet_pts(sh->ds, &start, &pts); in_size = x; if (x <= 0) { pts = MP_NOPTS_VALUE; x = 0; } ds_parse(sh->ds, &start, &x, pts, 0); srate = 48000; //fake value bps = 768000/8; //fake value if (x && sh->avctx) { // we have parser and large enough buffer if (sh->avctx->sample_rate < 44100) { mp_msg(MSGT_DECAUDIO,MSGL_INFO, "This stream sample_rate[%d Hz] may be broken. " "Force reset 48000Hz.\n", sh->avctx->sample_rate); srate = 48000; //fake value } else srate = sh->avctx->sample_rate; bps = sh->avctx->bit_rate/8; } sh->ds->buffer_pos -= in_size; switch (lavf_ctx->streams[0]->codec->codec_id) { case AV_CODEC_ID_AAC: spdif_ctx->iec61937_packet_size = 16384; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_AC3: spdif_ctx->iec61937_packet_size = 6144; sh->sample_format = AF_FORMAT_AC3_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_DTS: if(sh->opts->dtshd) { opt = av_opt_find(&lavf_ctx->oformat->priv_class, "dtshd_rate", NULL, 0, 0); if (!opt) goto fail; dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) + opt->offset); *dtshd_rate = 192000*4; spdif_ctx->iec61937_packet_size = 32768; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; // DTS core require 48000 sh->channels = 2*4; sh->i_bps = bps; } else { spdif_ctx->iec61937_packet_size = 32768; sh->sample_format = AF_FORMAT_AC3_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; } break; case AV_CODEC_ID_EAC3: spdif_ctx->iec61937_packet_size = 24576; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_MP3: spdif_ctx->iec61937_packet_size = 4608; sh->sample_format = AF_FORMAT_MPEG2; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_TRUEHD: spdif_ctx->iec61937_packet_size = 61440; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; sh->channels = 8; sh->i_bps = bps; break; default: break; } return 1; fail: uninit(sh); return 0; }
static int init(struct dec_audio *da, const char *decoder) { struct spdifContext *spdif_ctx = talloc_zero(NULL, struct spdifContext); da->priv = spdif_ctx; spdif_ctx->log = da->log; AVFormatContext *lavf_ctx = avformat_alloc_context(); if (!lavf_ctx) goto fail; lavf_ctx->oformat = av_guess_format("spdif", NULL, NULL); if (!lavf_ctx->oformat) goto fail; spdif_ctx->lavf_ctx = lavf_ctx; void *buffer = av_mallocz(OUTBUF_SIZE); if (!buffer) abort(); lavf_ctx->pb = avio_alloc_context(buffer, OUTBUF_SIZE, 1, spdif_ctx, NULL, write_packet, NULL); if (!lavf_ctx->pb) { av_free(buffer); goto fail; } // Request minimal buffering (not available on Libav) #if LIBAVFORMAT_VERSION_MICRO >= 100 lavf_ctx->pb->direct = 1; #endif AVStream *stream = avformat_new_stream(lavf_ctx, 0); if (!stream) goto fail; stream->codec->codec_id = mp_codec_to_av_codec_id(decoder); AVDictionary *format_opts = NULL; int num_channels = 0; int sample_format = 0; int samplerate = 0; switch (stream->codec->codec_id) { case AV_CODEC_ID_AAC: spdif_ctx->iec61937_packet_size = 16384; sample_format = AF_FORMAT_IEC61937_LE; samplerate = 48000; num_channels = 2; break; case AV_CODEC_ID_AC3: spdif_ctx->iec61937_packet_size = 6144; sample_format = AF_FORMAT_AC3_LE; samplerate = 48000; num_channels = 2; break; case AV_CODEC_ID_DTS: if (da->opts->dtshd) { av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000 spdif_ctx->iec61937_packet_size = 32768; sample_format = AF_FORMAT_IEC61937_LE; samplerate = 192000; num_channels = 2*4; } else { spdif_ctx->iec61937_packet_size = 32768; sample_format = AF_FORMAT_AC3_LE; samplerate = 48000; num_channels = 2; } break; case AV_CODEC_ID_EAC3: spdif_ctx->iec61937_packet_size = 24576; sample_format = AF_FORMAT_IEC61937_LE; samplerate = 192000; num_channels = 2; break; case AV_CODEC_ID_MP3: spdif_ctx->iec61937_packet_size = 4608; sample_format = AF_FORMAT_MPEG2; samplerate = 48000; num_channels = 2; break; case AV_CODEC_ID_TRUEHD: spdif_ctx->iec61937_packet_size = 61440; sample_format = AF_FORMAT_IEC61937_LE; samplerate = 192000; num_channels = 8; break; default: abort(); } mp_audio_set_num_channels(&da->decoded, num_channels); mp_audio_set_format(&da->decoded, sample_format); da->decoded.rate = samplerate; if (avformat_write_header(lavf_ctx, &format_opts) < 0) { MP_FATAL(da, "libavformat spdif initialization failed.\n"); av_dict_free(&format_opts); goto fail; } av_dict_free(&format_opts); spdif_ctx->need_close = true; return 1; fail: uninit(da); return 0; }