diff options
Diffstat (limited to 'audio')
47 files changed, 4443 insertions, 1189 deletions
diff --git a/audio/aframe.c b/audio/aframe.c index fc5d73be2d..03e8ab8ae8 100644 --- a/audio/aframe.c +++ b/audio/aframe.c @@ -18,9 +18,12 @@ #include <libavutil/frame.h> #include <libavutil/mem.h> +#include "config.h" + #include "common/common.h" #include "chmap.h" +#include "chmap_avchannel.h" #include "fmt-conversion.h" #include "format.h" #include "aframe.h" @@ -49,8 +52,7 @@ struct mp_aframe *mp_aframe_create(void) { struct mp_aframe *frame = talloc_zero(NULL, struct mp_aframe); frame->av_frame = av_frame_alloc(); - if (!frame->av_frame) - abort(); + MP_HANDLE_OOM(frame->av_frame); talloc_set_destructor(frame, free_frame); mp_aframe_reset(frame); return frame; @@ -121,6 +123,16 @@ struct mp_aframe *mp_aframe_from_avframe(struct AVFrame *av_frame) if (!av_frame || av_frame->width > 0 || av_frame->height > 0) return NULL; +#if HAVE_AV_CHANNEL_LAYOUT + if (!av_channel_layout_check(&av_frame->ch_layout)) + return NULL; + + struct mp_chmap converted_map = { 0 }; + if (!mp_chmap_from_av_layout(&converted_map, &av_frame->ch_layout)) { + return NULL; + } +#endif + int format = af_from_avformat(av_frame->format); if (!format && av_frame->format != AV_SAMPLE_FMT_NONE) return NULL; @@ -132,11 +144,15 @@ struct mp_aframe *mp_aframe_from_avframe(struct AVFrame *av_frame) abort(); frame->format = format; +#if !HAVE_AV_CHANNEL_LAYOUT mp_chmap_from_lavc(&frame->chmap, frame->av_frame->channel_layout); // FFmpeg being a stupid POS again if (frame->chmap.num != frame->av_frame->channels) mp_chmap_from_channels(&frame->chmap, av_frame->channels); +#else + frame->chmap = converted_map; +#endif if (av_frame->opaque_ref) { struct avframe_opaque *op = (void *)av_frame->opaque_ref->data; @@ -204,9 +220,16 @@ void mp_aframe_config_copy(struct mp_aframe *dst, struct mp_aframe *src) dst->av_frame->sample_rate = src->av_frame->sample_rate; dst->av_frame->format = src->av_frame->format; + +#if !HAVE_AV_CHANNEL_LAYOUT dst->av_frame->channel_layout = src->av_frame->channel_layout; // FFmpeg being a stupid POS again dst->av_frame->channels = src->av_frame->channels; +#else + if (av_channel_layout_copy(&dst->av_frame->ch_layout, + &src->av_frame->ch_layout) < 0) + abort(); +#endif } // Copy "soft" attributes from src to dst, excluding things which affect @@ -315,13 +338,21 @@ bool mp_aframe_set_chmap(struct mp_aframe *frame, struct mp_chmap *in) return false; if (mp_aframe_is_allocated(frame) && in->num != frame->chmap.num) return false; + +#if !HAVE_AV_CHANNEL_LAYOUT uint64_t lavc_layout = mp_chmap_to_lavc_unchecked(in); if (!lavc_layout && in->num) return false; +#endif frame->chmap = *in; + +#if !HAVE_AV_CHANNEL_LAYOUT frame->av_frame->channel_layout = lavc_layout; // FFmpeg being a stupid POS again frame->av_frame->channels = frame->chmap.num; +#else + mp_chmap_to_av_layout(&frame->av_frame->ch_layout, in); +#endif return true; } @@ -434,6 +465,37 @@ void mp_aframe_skip_samples(struct mp_aframe *f, int samples) f->pts += samples / mp_aframe_get_effective_rate(f); } +// sanitize a floating point sample value +#define sanitizef(f) do { \ + if (!isnormal(f)) \ + (f) = 0; \ +} while (0) + +void mp_aframe_sanitize_float(struct mp_aframe *mpa) +{ + int format = af_fmt_from_planar(mp_aframe_get_format(mpa)); + if (format != AF_FORMAT_FLOAT && format != AF_FORMAT_DOUBLE) + return; + int num_planes = mp_aframe_get_planes(mpa); + uint8_t **planes = mp_aframe_get_data_rw(mpa); + if (!planes) + return; + for (int p = 0; p < num_planes; p++) { + void *ptr = planes[p]; + int total = mp_aframe_get_total_plane_samples(mpa); + switch (format) { + case AF_FORMAT_FLOAT: + for (int s = 0; s < total; s++) + sanitizef(((float *)ptr)[s]); + break; + case AF_FORMAT_DOUBLE: + for (int s = 0; s < total; s++) + sanitizef(((double *)ptr)[s]); + break; + } + } +} + // Return the timestamp of the sample just after the end of this frame. double mp_aframe_end_pts(struct mp_aframe *f) { @@ -538,7 +600,7 @@ bool mp_aframe_set_silence(struct mp_aframe *f, int offset, int samples) bool mp_aframe_reverse(struct mp_aframe *f) { int format = mp_aframe_get_format(f); - size_t bps = af_fmt_to_bytes(format); + int bps = af_fmt_to_bytes(format); if (!af_fmt_is_pcm(format) || bps > 16) return false; @@ -635,18 +697,23 @@ int mp_aframe_pool_allocate(struct mp_aframe_pool *pool, struct mp_aframe *frame AVFrame *av_frame = frame->av_frame; if (av_frame->extended_data != av_frame->data) av_freep(&av_frame->extended_data); // sigh - av_frame->extended_data = - av_mallocz_array(planes, sizeof(av_frame->extended_data[0])); - if (!av_frame->extended_data) - abort(); + if (planes > AV_NUM_DATA_POINTERS) { + av_frame->extended_data = + av_calloc(planes, sizeof(av_frame->extended_data[0])); + MP_HANDLE_OOM(av_frame->extended_data); + } else { + av_frame->extended_data = av_frame->data; + } av_frame->buf[0] = av_buffer_pool_get(pool->avpool); if (!av_frame->buf[0]) return -1; av_frame->linesize[0] = samples * sstride; for (int n = 0; n < planes; n++) av_frame->extended_data[n] = av_frame->buf[0]->data + n * plane_size; - for (int n = 0; n < MPMIN(planes, AV_NUM_DATA_POINTERS); n++) - av_frame->data[n] = av_frame->extended_data[n]; + if (planes > AV_NUM_DATA_POINTERS) { + for (int n = 0; n < AV_NUM_DATA_POINTERS; n++) + av_frame->data[n] = av_frame->extended_data[n]; + } av_frame->nb_samples = samples; return 0; diff --git a/audio/aframe.h b/audio/aframe.h index be456a3dd1..d19c7e8bcb 100644 --- a/audio/aframe.h +++ b/audio/aframe.h @@ -60,6 +60,7 @@ char *mp_aframe_format_str_buf(char *buf, size_t buf_size, struct mp_aframe *fmt #define mp_aframe_format_str(fmt) mp_aframe_format_str_buf((char[32]){0}, 32, (fmt)) void mp_aframe_skip_samples(struct mp_aframe *f, int samples); +void mp_aframe_sanitize_float(struct mp_aframe *f); double mp_aframe_end_pts(struct mp_aframe *f); double mp_aframe_duration(struct mp_aframe *f); void mp_aframe_clip_timestamps(struct mp_aframe *f, double start, double end); diff --git a/audio/chmap.c b/audio/chmap.c index edbe83eb68..a56d78dfe2 100644 --- a/audio/chmap.c +++ b/audio/chmap.c @@ -52,6 +52,11 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = { [MP_SPEAKER_ID_SDL] = {"sdl", "surround direct left"}, [MP_SPEAKER_ID_SDR] = {"sdr", "surround direct right"}, [MP_SPEAKER_ID_LFE2] = {"lfe2", "low frequency 2"}, + [MP_SPEAKER_ID_TSL] = {"tsl", "top side left"}, + [MP_SPEAKER_ID_TSR] = {"tsr", "top side right"}, + [MP_SPEAKER_ID_BFC] = {"bfc", "bottom front center"}, + [MP_SPEAKER_ID_BFL] = {"bfl", "bottom front left"}, + [MP_SPEAKER_ID_BFR] = {"bfr", "bottom front right"}, [MP_SPEAKER_ID_NA] = {"na", "not available"}, }; @@ -83,7 +88,7 @@ static const char *const std_layout_names[][2] = { {"6.0(front)", "fl-fr-flc-frc-sl-sr"}, {"hexagonal", "fl-fr-fc-bl-br-bc"}, {"6.1", "fl-fr-fc-lfe-bc-sl-sr"}, - {"6.1(back)", "fl-fr-fc-lfe-bl-br-bc"}, // lavc calls this "6.1" too + {"6.1(back)", "fl-fr-fc-lfe-bl-br-bc"}, {"6.1(top)", "fl-fr-fc-lfe-bl-br-tc"}, // not in lavc {"6.1(front)", "fl-fr-lfe-flc-frc-sl-sr"}, {"7.0", "fl-fr-fc-bl-br-sl-sr"}, @@ -93,8 +98,13 @@ static const char *const std_layout_names[][2] = { {"7.1(alsa)", "fl-fr-bl-br-fc-lfe-sl-sr"}, // not in lavc {"7.1(wide)", "fl-fr-fc-lfe-bl-br-flc-frc"}, {"7.1(wide-side)", "fl-fr-fc-lfe-flc-frc-sl-sr"}, + {"7.1(top)", "fl-fr-fc-lfe-bl-br-tfl-tfr"}, {"7.1(rear)", "fl-fr-fc-lfe-bl-br-sdl-sdr"}, // not in lavc {"octagonal", "fl-fr-fc-bl-br-bc-sl-sr"}, + {"cube", "fl-fr-bl-br-tfl-tfr-tbl-tbr"}, + {"hexadecagonal", "fl-fr-fc-bl-br-bc-sl-sr-tfc-tfl-tfr-tbl-tbc-tbr-wl-wr"}, + {"downmix", "fl-fr"}, + {"22.2", "fl-fr-fc-lfe-bl-br-flc-frc-bc-sl-sr-tc-tfl-tfc-tfr-tbl-tbc-tbr-lfe2-tsl-tsr-bfc-bfl-bfr"}, {"auto", ""}, // not in lavc {0} }; @@ -229,8 +239,8 @@ void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels) } } -// Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>. -// Speakers not representable by ffmpeg/libav are dropped. +// Return the ffmpeg channel layout as in <libavutil/channel_layout.h>. +// Speakers not representable by ffmpeg are dropped. // Warning: this ignores the order of the channels, and will return a channel // mask even if the order is different from libavcodec's. // Also, "unknown" channel maps are translated to non-sense channel @@ -253,7 +263,7 @@ uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src) return mask; } -// Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>. +// Return the ffmpeg channel layout as in <libavutil/channel_layout.h>. // Returns 0 if the channel order doesn't match lavc's or if it's invalid. uint64_t mp_chmap_to_lavc(const struct mp_chmap *src) { @@ -262,7 +272,7 @@ uint64_t mp_chmap_to_lavc(const struct mp_chmap *src) return mp_chmap_to_lavc_unchecked(src); } -// Set channel map from the ffmpeg/libav channel layout as in +// Set channel map from the ffmpeg channel layout as in // <libavutil/channel_layout.h>. // If the number of channels exceed MP_NUM_CHANNELS, set dst to empty. void mp_chmap_from_lavc(struct mp_chmap *dst, uint64_t src) @@ -470,6 +480,23 @@ char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap * return mp_chmap_to_str_buf(buf, buf_size, &map); } +mp_ch_layout_tuple *mp_iterate_builtin_layouts(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + + if (i >= MP_ARRAY_SIZE(std_layout_names) || + !std_layout_names[i][0]) + return NULL; + + *opaque = (void *)(i + 1); + + if (std_layout_names[i][1][0] == '\0') { + return mp_iterate_builtin_layouts(opaque); + } + + return &std_layout_names[i]; +} + void mp_chmap_print_help(struct mp_log *log) { mp_info(log, "Speakers:\n"); diff --git a/audio/chmap.h b/audio/chmap.h index dff69336d6..58a3f71907 100644 --- a/audio/chmap.h +++ b/audio/chmap.h @@ -22,7 +22,7 @@ #include <stdbool.h> #include "misc/bstr.h" -#define MP_NUM_CHANNELS 16 +#define MP_NUM_CHANNELS 64 // Speaker a channel can be assigned to. // This corresponds to WAVEFORMATEXTENSIBLE channel mask bit indexes. @@ -55,6 +55,11 @@ enum mp_speaker_id { MP_SPEAKER_ID_SDL, // SURROUND_DIRECT_LEFT MP_SPEAKER_ID_SDR, // SURROUND_DIRECT_RIGHT MP_SPEAKER_ID_LFE2, // LOW_FREQUENCY_2 + MP_SPEAKER_ID_TSL, // TOP_SIDE_LEFT + MP_SPEAKER_ID_TSR, // TOP_SIDE_RIGHT, + MP_SPEAKER_ID_BFC, // BOTTOM_FRONT_CENTER + MP_SPEAKER_ID_BFL, // BOTTOM_FRONT_LEFT + MP_SPEAKER_ID_BFR, // BOTTOM_FRONT_RIGHT // Speaker IDs >= 64 are not representable in WAVEFORMATEXTENSIBLE or libav*. @@ -75,6 +80,8 @@ struct mp_chmap { uint8_t speaker[MP_NUM_CHANNELS]; }; +typedef const char * const (mp_ch_layout_tuple)[2]; + #define MP_SP(speaker) MP_SPEAKER_ID_ ## speaker #define MP_CHMAP2(a, b) \ @@ -122,13 +129,28 @@ void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from, int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b); char *mp_chmap_to_str_buf(char *buf, size_t buf_size, const struct mp_chmap *src); -#define mp_chmap_to_str(m) mp_chmap_to_str_buf((char[64]){0}, 64, (m)) +#define mp_chmap_to_str_(m, sz) mp_chmap_to_str_buf((char[sz]){0}, sz, (m)) +#define mp_chmap_to_str(m) mp_chmap_to_str_(m, MP_NUM_CHANNELS * 4) char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap *src); -#define mp_chmap_to_str_hr(m) mp_chmap_to_str_hr_buf((char[128]){0}, 128, (m)) +#define mp_chmap_to_str_hr_(m, sz) mp_chmap_to_str_hr_buf((char[sz]){0}, sz, (m)) +#define mp_chmap_to_str_hr(m) mp_chmap_to_str_hr_(m, MP_NUM_CHANNELS * 4) bool mp_chmap_from_str(struct mp_chmap *dst, bstr src); +/** + * Iterate over all built-in channel layouts which have mapped channels. + * + * @param opaque a pointer where the iteration state is stored. Must point + * to nullptr to start the iteration. + * + * @return nullptr when the iteration is finished. + * Otherwise a pointer to an array of two char pointers. + * - [0] being the human-readable layout name. + * - [1] being the string representation of the layout. + */ +mp_ch_layout_tuple *mp_iterate_builtin_layouts(void **opaque); + struct mp_log; void mp_chmap_print_help(struct mp_log *log); diff --git a/audio/chmap_avchannel.c b/audio/chmap_avchannel.c new file mode 100644 index 0000000000..ec961de422 --- /dev/null +++ b/audio/chmap_avchannel.c @@ -0,0 +1,51 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libavutil/channel_layout.h> + +#include "chmap.h" +#include "chmap_avchannel.h" + +bool mp_chmap_from_av_layout(struct mp_chmap *dst, const AVChannelLayout *src) +{ + *dst = (struct mp_chmap) {0}; + + switch (src->order) { + case AV_CHANNEL_ORDER_UNSPEC: + mp_chmap_from_channels(dst, src->nb_channels); + return dst->num == src->nb_channels; + case AV_CHANNEL_ORDER_NATIVE: + mp_chmap_from_lavc(dst, src->u.mask); + return dst->num == src->nb_channels; + default: + // TODO: handle custom layouts + return false; + } +} + +void mp_chmap_to_av_layout(AVChannelLayout *dst, const struct mp_chmap *src) +{ + *dst = (AVChannelLayout){ + .order = AV_CHANNEL_ORDER_UNSPEC, + .nb_channels = src->num, + }; + + // TODO: handle custom layouts + if (!mp_chmap_is_unknown(src)) { + av_channel_layout_from_mask(dst, mp_chmap_to_lavc(src)); + } +} diff --git a/audio/chmap_avchannel.h b/audio/chmap_avchannel.h new file mode 100644 index 0000000000..e136ccc7ce --- /dev/null +++ b/audio/chmap_avchannel.h @@ -0,0 +1,32 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <libavutil/channel_layout.h> + +#include "config.h" + +#include "chmap.h" + +#if HAVE_AV_CHANNEL_LAYOUT + +bool mp_chmap_from_av_layout(struct mp_chmap *dst, const AVChannelLayout *src); + +void mp_chmap_to_av_layout(AVChannelLayout *dst, const struct mp_chmap *src); + +#endif diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index eaaf0729e9..39cd74cd2a 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -17,7 +17,6 @@ #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <stdbool.h> #include <assert.h> @@ -26,8 +25,11 @@ #include <libavutil/common.h> #include <libavutil/intreadwrite.h> +#include "config.h" + #include "mpv_talloc.h" #include "audio/aframe.h" +#include "audio/chmap_avchannel.h" #include "audio/fmt-conversion.h" #include "common/av_common.h" #include "common/codecs.h" @@ -41,8 +43,10 @@ #include "options/options.h" struct priv { + struct mp_codec_params *codec; AVCodecContext *avctx; AVFrame *avframe; + AVPacket *avpkt; struct mp_chmap force_channel_map; uint32_t skip_samples, trim_samples; bool preroll_done; @@ -56,7 +60,7 @@ struct priv { #define OPT_BASE_STRUCT struct ad_lavc_params struct ad_lavc_params { float ac3drc; - int downmix; + bool downmix; int threads; char **avopts; }; @@ -64,7 +68,7 @@ struct ad_lavc_params { const struct m_sub_options ad_lavc_conf = { .opts = (const m_option_t[]) { {"ac3drc", OPT_FLOAT(ac3drc), M_RANGE(0, 6)}, - {"downmix", OPT_FLAG(downmix)}, + {"downmix", OPT_BOOL(downmix)}, {"threads", OPT_INT(threads), M_RANGE(0, 16)}, {"o", OPT_KEYVALUELIST(avopts)}, {0} @@ -72,7 +76,6 @@ const struct m_sub_options ad_lavc_conf = { .size = sizeof(struct ad_lavc_params), .defaults = &(const struct ad_lavc_params){ .ac3drc = 0, - .downmix = 0, .threads = 1, }, }; @@ -85,7 +88,7 @@ static bool init(struct mp_filter *da, struct mp_codec_params *codec, struct ad_lavc_params *opts = mp_get_config_group(ctx, da->global, &ad_lavc_conf); AVCodecContext *lavc_context; - AVCodec *lavc_codec; + const AVCodec *lavc_codec; ctx->codec_timebase = mp_get_codec_timebase(codec); @@ -101,13 +104,29 @@ static bool init(struct mp_filter *da, struct mp_codec_params *codec, lavc_context = avcodec_alloc_context3(lavc_codec); ctx->avctx = lavc_context; ctx->avframe = av_frame_alloc(); + ctx->avpkt = av_packet_alloc(); + MP_HANDLE_OOM(ctx->avctx && ctx->avframe && ctx->avpkt); lavc_context->codec_type = AVMEDIA_TYPE_AUDIO; lavc_context->codec_id = lavc_codec->id; lavc_context->pkt_timebase = ctx->codec_timebase; if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) { + const struct mp_chmap *requested_layout = + &mpopts->audio_output_channels.chmaps[0]; +#if !HAVE_AV_CHANNEL_LAYOUT lavc_context->request_channel_layout = - mp_chmap_to_lavc(&mpopts->audio_output_channels.chmaps[0]); + mp_chmap_to_lavc(requested_layout); +#else + AVChannelLayout av_layout = { 0 }; + mp_chmap_to_av_layout(&av_layout, requested_layout); + + // Always try to set requested output layout - currently only something + // supported by AC3, MLP/TrueHD, DTS and the fdk-aac wrapper. + av_opt_set_chlayout(lavc_context, "downmix", &av_layout, + AV_OPT_SEARCH_CHILDREN); + + av_channel_layout_uninit(&av_layout); +#endif } // Always try to set - option only exists for AC3 at the moment @@ -137,15 +156,16 @@ static bool init(struct mp_filter *da, struct mp_codec_params *codec, return true; } -static void destroy(struct mp_filter *da) +static void ad_lavc_destroy(struct mp_filter *da) { struct priv *ctx = da->priv; avcodec_free_context(&ctx->avctx); av_frame_free(&ctx->avframe); + mp_free_av_packet(&ctx->avpkt); } -static void reset(struct mp_filter *da) +static void ad_lavc_reset(struct mp_filter *da) { struct priv *ctx = da->priv; @@ -168,10 +188,9 @@ static int send_packet(struct mp_filter *da, struct demux_packet *mpkt) if (mpkt && priv->next_pts == MP_NOPTS_VALUE) priv->next_pts = mpkt->pts; - AVPacket pkt; - mp_set_av_packet(&pkt, mpkt, &priv->codec_timebase); + mp_set_av_packet(priv->avpkt, mpkt, &priv->codec_timebase); - int ret = avcodec_send_packet(avctx, mpkt ? &pkt : NULL); + int ret = avcodec_send_packet(avctx, mpkt ? priv->avpkt : NULL); if (ret < 0) MP_ERR(da, "Error decoding audio.\n"); return ret; @@ -200,6 +219,8 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out) if (!priv->avframe->buf[0]) return ret; + mp_codec_info_from_av(avctx, priv->codec); + double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase); struct mp_aframe *mpframe = mp_aframe_from_avframe(priv->avframe); @@ -243,6 +264,9 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out) priv->trim_samples -= trim; } + // Strip possibly bogus float values like Infinity, NaN, denormalized + mp_aframe_sanitize_float(mpframe); + if (mp_aframe_get_size(mpframe) > 0) { *out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe); } else { @@ -254,7 +278,7 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out) return ret; } -static void process(struct mp_filter *ad) +static void ad_lavc_process(struct mp_filter *ad) { struct priv *priv = ad->priv; @@ -264,9 +288,9 @@ static void process(struct mp_filter *ad) static const struct mp_filter_info ad_lavc_filter = { .name = "ad_lavc", .priv_size = sizeof(struct priv), - .process = process, - .reset = reset, - .destroy = destroy, + .process = ad_lavc_process, + .reset = ad_lavc_reset, + .destroy = ad_lavc_destroy, }; static struct mp_decoder *create(struct mp_filter *parent, @@ -283,12 +307,16 @@ static struct mp_decoder *create(struct mp_filter *parent, da->log = mp_log_new(da, parent->log, NULL); struct priv *priv = da->priv; + priv->codec = codec; priv->public.f = da; if (!init(da, codec, decoder)) { talloc_free(da); return NULL; } + + codec->codec_desc = priv->avctx->codec_descriptor->long_name; + return &priv->public; } diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 0b1977769a..3f83ab240e 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -37,10 +37,18 @@ #define OUTBUF_SIZE 65536 +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(60, 26, 100) +#define AV_PROFILE_UNKNOWN FF_PROFILE_UNKNOWN +#define AV_PROFILE_DTS_HD_HRA FF_PROFILE_DTS_HD_HRA +#define AV_PROFILE_DTS_HD_MA FF_PROFILE_DTS_HD_MA +#endif + struct spdifContext { struct mp_log *log; + struct mp_codec_params *codec; enum AVCodecID codec_id; AVFormatContext *lavf_ctx; + AVPacket *avpkt; int out_buffer_len; uint8_t out_buffer[OUTBUF_SIZE]; bool need_close; @@ -52,7 +60,11 @@ struct spdifContext { struct mp_decoder public; }; +#if LIBAVCODEC_VERSION_MAJOR < 61 static int write_packet(void *p, uint8_t *buf, int buf_size) +#else +static int write_packet(void *p, const uint8_t *buf, int buf_size) +#endif { struct spdifContext *ctx = p; @@ -68,7 +80,7 @@ static int write_packet(void *p, uint8_t *buf, int buf_size) } // (called on both filter destruction _and_ if lavf fails to init) -static void destroy(struct mp_filter *da) +static void ad_spdif_destroy(struct mp_filter *da) { struct spdifContext *spdif_ctx = da->priv; AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; @@ -78,17 +90,18 @@ static void destroy(struct mp_filter *da) |