diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/decode/ad.h | 7 | ||||
-rw-r--r-- | audio/decode/ad_lavc.c | 87 | ||||
-rw-r--r-- | audio/decode/ad_spdif.c | 95 | ||||
-rw-r--r-- | audio/decode/dec_audio.c | 21 | ||||
-rw-r--r-- | audio/decode/dec_audio.h | 2 | ||||
-rw-r--r-- | audio/filter/af_lavfi.c | 8 | ||||
-rw-r--r-- | audio/filter/af_lavrresample.c | 3 | ||||
-rw-r--r-- | audio/out/ao_oss.c | 18 | ||||
-rw-r--r-- | audio/out/ao_wasapi.c | 12 | ||||
-rw-r--r-- | audio/out/ao_wasapi.h | 2 | ||||
-rw-r--r-- | audio/out/ao_wasapi_changenotify.c | 2 | ||||
-rw-r--r-- | audio/out/ao_wasapi_utils.c | 41 | ||||
-rw-r--r-- | audio/out/push.c | 7 |
13 files changed, 184 insertions, 121 deletions
diff --git a/audio/decode/ad.h b/audio/decode/ad.h index 771ceb7e88..bbb050eb4c 100644 --- a/audio/decode/ad.h +++ b/audio/decode/ad.h @@ -35,8 +35,11 @@ struct ad_functions { int (*init)(struct dec_audio *da, const char *decoder); void (*uninit)(struct dec_audio *da); int (*control)(struct dec_audio *da, int cmd, void *arg); - int (*decode_packet)(struct dec_audio *da, struct demux_packet *pkt, - struct mp_audio **out); + // Return whether or not the packet has been consumed. + bool (*send_packet)(struct dec_audio *da, struct demux_packet *pkt); + // Return whether decoding is still going on (false if EOF was reached). + // Never returns false & *out set, but can return true with !*out. + bool (*receive_frame)(struct dec_audio *da, struct mp_audio **out); }; enum ad_ctrl { diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index c4d3a2ae7b..7f3abfd612 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -45,7 +45,6 @@ struct priv { uint32_t skip_samples, trim_samples; bool preroll_done; double next_pts; - bool needs_reset; AVRational codec_timebase; }; @@ -116,26 +115,18 @@ static int init(struct dec_audio *da, const char *decoder) av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc, AV_OPT_SEARCH_CHILDREN); -#if HAVE_AVFRAME_SKIP_SAMPLES +#if LIBAVCODEC_VERSION_MICRO >= 100 // Let decoder add AV_FRAME_DATA_SKIP_SAMPLES. av_opt_set(lavc_context, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN); #endif mp_set_avopts(da->log, lavc_context, opts->avopts); - lavc_context->codec_tag = c->codec_tag; - lavc_context->sample_rate = c->samplerate; - lavc_context->bit_rate = c->bitrate; - lavc_context->block_align = c->block_align; - lavc_context->bits_per_coded_sample = c->bits_per_coded_sample; - lavc_context->channels = c->channels.num; - if (!mp_chmap_is_unknown(&c->channels)) - lavc_context->channel_layout = mp_chmap_to_lavc(&c->channels); - - // demux_mkv - mp_lavc_set_extradata(lavc_context, c->extradata, c->extradata_size); - - mp_set_lav_codec_headers(lavc_context, c); + if (mp_set_avctx_codec_headers(lavc_context, c) < 0) { + MP_ERR(da, "Could not set decoder parameters.\n"); + uninit(da); + return 0; + } mp_set_avcodec_threads(da->log, lavc_context, opts->threads); @@ -177,14 +168,12 @@ static int control(struct dec_audio *da, int cmd, void *arg) ctx->trim_samples = 0; ctx->preroll_done = false; ctx->next_pts = MP_NOPTS_VALUE; - ctx->needs_reset = false; return CONTROL_TRUE; } return CONTROL_UNKNOWN; } -static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, - struct mp_audio **out) +static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt) { struct priv *priv = da->priv; AVCodecContext *avctx = priv->avctx; @@ -195,41 +184,48 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, if (mpkt && priv->next_pts == MP_NOPTS_VALUE) priv->next_pts = mpkt->pts; - int in_len = mpkt ? mpkt->len : 0; - AVPacket pkt; mp_set_av_packet(&pkt, mpkt, &priv->codec_timebase); - int got_frame = 0; - av_frame_unref(priv->avframe); + int ret = avcodec_send_packet(avctx, mpkt ? &pkt : NULL); - if (priv->needs_reset) - control(da, ADCTRL_RESET, NULL); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return false; - int ret = avcodec_send_packet(avctx, &pkt); - if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { - if (ret >= 0 && mpkt) - mpkt->len = 0; - ret = avcodec_receive_frame(avctx, priv->avframe); - if (ret >= 0) - got_frame = 1; - if (ret == AVERROR_EOF) - priv->needs_reset = true; - if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) - ret = 0; - } - if (ret < 0) { + if (ret < 0) + MP_ERR(da, "Error decoding audio.\n"); + return true; +} + +static bool receive_frame(struct dec_audio *da, struct mp_audio **out) +{ + struct priv *priv = da->priv; + AVCodecContext *avctx = priv->avctx; + + int ret = avcodec_receive_frame(avctx, priv->avframe); + + if (ret == AVERROR_EOF) { + // If flushing was initialized earlier and has ended now, make it start + // over in case we get new packets at some point in the future. + control(da, ADCTRL_RESET, NULL); + return false; + } else if (ret < 0 && ret != AVERROR(EAGAIN)) { MP_ERR(da, "Error decoding audio.\n"); - return -1; } - if (!got_frame) - return 0; + +#if LIBAVCODEC_VERSION_MICRO >= 100 + if (priv->avframe->flags & AV_FRAME_FLAG_DISCARD) + av_frame_unref(priv->avframe); +#endif + + if (!priv->avframe->buf[0]) + return true; double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase); struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe); if (!mpframe) - return -1; + return true; struct mp_chmap lavc_chmap = mpframe->channels; if (lavc_chmap.num != avctx->channels) @@ -247,7 +243,7 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, if (mpframe->pts != MP_NOPTS_VALUE) priv->next_pts = mpframe->pts + mpframe->samples / (double)mpframe->rate; -#if HAVE_AVFRAME_SKIP_SAMPLES +#if LIBAVCODEC_VERSION_MICRO >= 100 AVFrameSideData *sd = av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES); if (sd && sd->size >= 10) { @@ -279,8 +275,8 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, av_frame_unref(priv->avframe); - MP_DBG(da, "Decoded %d -> %d samples\n", in_len, mpframe->samples); - return 0; + MP_DBG(da, "Decoded %d samples\n", mpframe->samples); + return true; } static void add_decoders(struct mp_decoder_list *list) @@ -294,5 +290,6 @@ const struct ad_functions ad_lavc = { .init = init, .uninit = uninit, .control = control, - .decode_packet = decode_packet, + .send_packet = send_packet, + .receive_frame = receive_frame, }; diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 30c7883bf4..e38c9e5077 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -42,6 +42,8 @@ struct spdifContext { bool use_dts_hd; struct mp_audio fmt; struct mp_audio_pool *pool; + bool got_eof; + struct demux_packet *queued_packet; }; static int write_packet(void *p, uint8_t *buf, int buf_size) @@ -71,6 +73,7 @@ static void uninit(struct dec_audio *da) av_freep(&lavf_ctx->pb->buffer); av_freep(&lavf_ctx->pb); avformat_free_context(lavf_ctx); + talloc_free(spdif_ctx->queued_packet); spdif_ctx->lavf_ctx = NULL; } } @@ -90,13 +93,34 @@ static int init(struct dec_audio *da, const char *decoder) return spdif_ctx->codec_id != AV_CODEC_ID_NONE; } -static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt) +static void determine_codec_params(struct dec_audio *da, AVPacket *pkt, + int *out_profile, int *out_rate) { struct spdifContext *spdif_ctx = da->priv; int profile = FF_PROFILE_UNKNOWN; AVCodecContext *ctx = NULL; AVFrame *frame = NULL; + AVCodecParserContext *parser = av_parser_init(spdif_ctx->codec_id); + if (parser) { + // Don't make it wait for the next frame. + parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; + + ctx = avcodec_alloc_context3(NULL); + + uint8_t *d = NULL; + int s = 0; + av_parser_parse2(parser, ctx, &d, &s, pkt->data, pkt->size, 0, 0, 0); + *out_profile = profile = ctx->profile; + *out_rate = ctx->sample_rate; + + av_free(ctx); + av_parser_close(parser); + } + + if (profile != FF_PROFILE_UNKNOWN || spdif_ctx->codec_id != AV_CODEC_ID_DTS) + return; + AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id); if (!codec) goto done; @@ -120,7 +144,8 @@ static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt) if (avcodec_receive_frame(ctx, frame) < 0) goto done; - profile = ctx->profile; + *out_profile = profile = ctx->profile; + *out_rate = ctx->sample_rate; done: av_frame_free(&frame); @@ -130,8 +155,6 @@ done: if (profile == FF_PROFILE_UNKNOWN) MP_WARN(da, "Failed to parse codec profile.\n"); - - return profile; } static int init_filter(struct dec_audio *da, AVPacket *pkt) @@ -139,8 +162,9 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt) struct spdifContext *spdif_ctx = da->priv; int profile = FF_PROFILE_UNKNOWN; - if (spdif_ctx->codec_id == AV_CODEC_ID_DTS) - profile = determine_codec_profile(da, pkt); + int c_rate = 0; + determine_codec_params(da, pkt, &profile, &c_rate); + MP_VERBOSE(da, "In: profile=%d samplerate=%d\n", profile, c_rate); AVFormatContext *lavf_ctx = avformat_alloc_context(); if (!lavf_ctx) @@ -186,7 +210,7 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt) break; case AV_CODEC_ID_AC3: sample_format = AF_FORMAT_S_AC3; - samplerate = 48000; + samplerate = c_rate > 0 ? c_rate : 48000; num_channels = 2; break; case AV_CODEC_ID_DTS: { @@ -243,44 +267,72 @@ fail: return -1; } -static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, - struct mp_audio **out) + +static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt) { struct spdifContext *spdif_ctx = da->priv; - spdif_ctx->out_buffer_len = 0; + if (spdif_ctx->queued_packet || spdif_ctx->got_eof) + return false; - if (!mpkt) - return 0; + spdif_ctx->queued_packet = mpkt ? demux_copy_packet(mpkt) : NULL; + spdif_ctx->got_eof = !mpkt; + return true; +} - double pts = mpkt->pts; +static bool receive_frame(struct dec_audio *da, struct mp_audio **out) +{ + struct spdifContext *spdif_ctx = da->priv; + + if (spdif_ctx->got_eof) { + spdif_ctx->got_eof = false; + return false; + } + + if (!spdif_ctx->queued_packet) + return true; + + double pts = spdif_ctx->queued_packet->pts; AVPacket pkt; - mp_set_av_packet(&pkt, mpkt, NULL); - mpkt->len = 0; // will be fully consumed + mp_set_av_packet(&pkt, spdif_ctx->queued_packet, NULL); pkt.pts = pkt.dts = 0; if (!spdif_ctx->lavf_ctx) { if (init_filter(da, &pkt) < 0) - return -1; + goto done; } + spdif_ctx->out_buffer_len = 0; int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt); avio_flush(spdif_ctx->lavf_ctx->pb); - if (ret < 0) - return -1; + if (ret < 0) { + MP_ERR(da, "spdif mux error: '%s'\n", mp_strerror(AVUNERROR(ret))); + goto done; + } int samples = spdif_ctx->out_buffer_len / spdif_ctx->fmt.sstride; *out = mp_audio_pool_get(spdif_ctx->pool, &spdif_ctx->fmt, samples); if (!*out) - return -1; + goto done; memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len); (*out)->pts = pts; - return 0; +done: + talloc_free(spdif_ctx->queued_packet); + spdif_ctx->queued_packet = NULL; + return true; } static int control(struct dec_audio *da, int cmd, void *arg) { + struct spdifContext *spdif_ctx = da->priv; + switch (cmd) { + case ADCTRL_RESET: + talloc_free(spdif_ctx->queued_packet); + spdif_ctx->queued_packet = NULL; + spdif_ctx->got_eof = false; + return CONTROL_TRUE; + } return CONTROL_UNKNOWN; } @@ -344,5 +396,6 @@ const struct ad_functions ad_spdif = { .init = init, .uninit = uninit, .control = control, - .decode_packet = decode_packet, + .send_packet = send_packet, + .receive_frame = receive_frame, }; diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 9f28302bd5..5a2735ef20 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -27,6 +27,7 @@ #include "common/codecs.h" #include "common/msg.h" +#include "common/recorder.h" #include "misc/bstr.h" #include "stream/stream.h" @@ -201,7 +202,7 @@ static void fix_audio_pts(struct dec_audio *da) void audio_work(struct dec_audio *da) { - if (da->current_frame) + if (da->current_frame || !da->ad_driver) return; if (!da->packet && !da->new_segment && @@ -217,30 +218,28 @@ void audio_work(struct dec_audio *da) da->packet = NULL; } - bool had_input_packet = !!da->packet; - bool had_packet = da->packet || da->new_segment; + if (da->ad_driver->send_packet(da, da->packet)) { + if (da->recorder_sink) + mp_recorder_feed_packet(da->recorder_sink, da->packet); - int ret = da->ad_driver->decode_packet(da, da->packet, &da->current_frame); - if (ret < 0 || (da->packet && da->packet->len == 0)) { talloc_free(da->packet); da->packet = NULL; } + bool progress = da->ad_driver->receive_frame(da, &da->current_frame); + if (da->current_frame && !mp_audio_config_valid(da->current_frame)) { talloc_free(da->current_frame); da->current_frame = NULL; } - da->current_state = DATA_OK; - if (!da->current_frame) { + da->current_state = da->current_frame ? DATA_OK : DATA_AGAIN; + if (!progress) da->current_state = DATA_EOF; - if (had_packet) - da->current_state = DATA_AGAIN; - } fix_audio_pts(da); - bool segment_end = !da->current_frame && !had_input_packet; + bool segment_end = da->current_state == DATA_EOF; if (da->current_frame) { mp_audio_clip_timestamps(da->current_frame, da->start, da->end); diff --git a/audio/decode/dec_audio.h b/audio/decode/dec_audio.h index ebe7c8ae5b..02447d6742 100644 --- a/audio/decode/dec_audio.h +++ b/audio/decode/dec_audio.h @@ -37,6 +37,8 @@ struct dec_audio { bool try_spdif; + struct mp_recorder_sink *recorder_sink; + // For free use by the ad_driver void *priv; diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c index bc4a687487..55fb7cb0dc 100644 --- a/audio/filter/af_lavfi.c +++ b/audio/filter/af_lavfi.c @@ -246,7 +246,7 @@ static int control(struct af_instance *af, int cmd, void *arg) static void get_metadata_from_av_frame(struct af_instance *af, AVFrame *frame) { -#if HAVE_AVFRAME_METADATA +#if LIBAVUTIL_VERSION_MICRO >= 100 struct priv *p = af->priv; if (!p->metadata) p->metadata = talloc_zero(p, struct mp_tags); @@ -266,6 +266,12 @@ static int filter_frame(struct af_instance *af, struct mp_audio *data) if (!p->graph) goto error; + if (!data) { + if (p->eof) + return 0; + p->eof = true; + } + if (data) { frame = mp_audio_to_avframe_and_unref(data); data = NULL; diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c index 828be66247..47c374b227 100644 --- a/audio/filter/af_lavrresample.c +++ b/audio/filter/af_lavrresample.c @@ -36,6 +36,9 @@ #include "common/common.h" #include "config.h" +#define HAVE_LIBSWRESAMPLE HAVE_IS_FFMPEG +#define HAVE_LIBAVRESAMPLE HAVE_IS_LIBAV + #if HAVE_LIBAVRESAMPLE #include <libavresample/avresample.h> #elif HAVE_LIBSWRESAMPLE diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c index c0446eb2aa..7e73644b8f 100644 --- a/audio/out/ao_oss.c +++ b/audio/out/ao_oss.c @@ -279,14 +279,21 @@ static int reopen_device(struct ao *ao, bool allow_format_changes) int format = ao->format; struct mp_chmap channels = ao->channels; + const char *device = PATH_DEV_DSP; + if (ao->device) + device = ao->device; + if (p->dsp && p->dsp[0]) + device = p->dsp; + + MP_VERBOSE(ao, "using '%s' dsp device\n", device); #ifdef __linux__ - p->audio_fd = open(p->dsp, O_WRONLY | O_NONBLOCK); + p->audio_fd = open(device, O_WRONLY | O_NONBLOCK); #else - p->audio_fd = open(p->dsp, O_WRONLY); + p->audio_fd = open(device, O_WRONLY); #endif if (p->audio_fd < 0) { MP_ERR(ao, "Can't open audio device %s: %s\n", - p->dsp, mp_strerror(errno)); + device, mp_strerror(errno)); goto fail; } @@ -443,9 +450,8 @@ static int init(struct ao *ao) p->oss_mixer_channel = SOUND_MIXER_PCM; } - MP_VERBOSE(ao, "using '%s' dsp device\n", p->dsp); MP_VERBOSE(ao, "using '%s' mixer device\n", p->oss_mixer_device); - MP_VERBOSE(ao, "using '%s' mixer device\n", mixer_channels[p->oss_mixer_channel]); + MP_VERBOSE(ao, "using '%s' mixer channel\n", mixer_channels[p->oss_mixer_channel]); ao->format = af_fmt_from_planar(ao->format); @@ -643,8 +649,6 @@ const struct ao_driver audio_out_oss = { .buffersize = -1, .outburst = 512, .oss_mixer_channel = SOUND_MIXER_PCM, - - .dsp = PATH_DEV_DSP, .oss_mixer_device = PATH_DEV_MIXER, }, .options = (const struct m_option[]) { diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index b2e035d3dc..3a4c341387 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -255,9 +255,9 @@ static void uninit(struct ao *ao) "while waiting for audio thread to terminate\n"); } - SAFE_RELEASE(state->hInitDone, CloseHandle(state->hInitDone)); - SAFE_RELEASE(state->hWake, CloseHandle(state->hWake)); - SAFE_RELEASE(state->hAudioThread,CloseHandle(state->hAudioThread)); + SAFE_DESTROY(state->hInitDone, CloseHandle(state->hInitDone)); + SAFE_DESTROY(state->hWake, CloseHandle(state->hWake)); + SAFE_DESTROY(state->hAudioThread,CloseHandle(state->hAudioThread)); wasapi_change_uninit(ao); @@ -305,7 +305,7 @@ static int init(struct ao *ao) } WaitForSingleObject(state->hInitDone, INFINITE); // wait on init complete - SAFE_RELEASE(state->hInitDone,CloseHandle(state->hInitDone)); + SAFE_DESTROY(state->hInitDone,CloseHandle(state->hInitDone)); if (FAILED(state->init_ret)) { if (!ao->probing) MP_FATAL(ao, "Received failure from audio thread\n"); @@ -418,10 +418,10 @@ static int thread_control(struct ao *ao, enum aocontrol cmd, void *arg) do { IAudioSessionControl_SetDisplayName(state->pSessionControl, title, NULL); - SAFE_RELEASE(tmp, CoTaskMemFree(tmp)); + SAFE_DESTROY(tmp, CoTaskMemFree(tmp)); IAudioSessionControl_GetDisplayName(state->pSessionControl, &tmp); } while (lstrcmpW(title, tmp)); - SAFE_RELEASE(tmp, CoTaskMemFree(tmp)); + SAFE_DESTROY(tmp, CoTaskMemFree(tmp)); talloc_free(title); return CONTROL_OK; } diff --git a/audio/out/ao_wasapi.h b/audio/out/ao_wasapi.h index 65f16d11c1..8f6e38867c 100644 --- a/audio/out/ao_wasapi.h +++ b/audio/out/ao_wasapi.h @@ -47,7 +47,7 @@ void wasapi_change_uninit(struct ao* ao); #define EXIT_ON_ERROR(hres) \ do { if (FAILED(hres)) { goto exit_label; } } while(0) -#define SAFE_RELEASE(unk, release) \ +#define SAFE_DESTROY(unk, release) \ do { if ((unk) != NULL) { release; (unk) = NULL; } } while(0) #define mp_format_res_str(hres) \ diff --git a/audio/out/ao_wasapi_changenotify.c b/audio/out/ao_wasapi_changenotify.c index e1b3a9d604..b9806e0adb 100644 --- a/audio/out/ao_wasapi_changenotify.c +++ b/audio/out/ao_wasapi_changenotify.c @@ -242,5 +242,5 @@ void wasapi_change_uninit(struct ao *ao) change->pEnumerator, (IMMNotificationClient *)change); } - SAFE_RELEASE(change->pEnumerator, IMMDeviceEnumerator_Release(change->pEnumerator)); + SAFE_RELEASE(change->pEnumerator); } diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index 4667b57ae8..a449dbec10 100644 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -539,8 +539,7 @@ static void init_session_display(struct wasapi_state *state) { return; exit_label: // if we got here then the session control is useless - release it - SAFE_RELEASE(state->pSessionControl, - IAudioSessionControl_Release(state->pSessionControl)); + SAFE_RELEASE(state->pSessionControl); MP_WARN(state, "Error setting audio session display name: %s\n", mp_HRESULT_to_str(hr)); return; @@ -571,10 +570,8 @@ static void init_volume_control(struct wasapi_state *state) return; exit_label: state->vol_hw_support = 0; - SAFE_RELEASE(state->pEndpointVolume, - IAudioEndpointVolume_Release(state->pEndpointVolume)); - SAFE_RELEASE(state->pAudioVolume, - ISimpleAudioVolume_Release(state->pAudioVolume)); + SAFE_RELEASE(state->pEndpointVolume); + SAFE_RELEASE(state->pAudioVolume); MP_WARN(state, "Error setting up volume control: %s\n", mp_HRESULT_to_str(hr)); } @@ -707,7 +704,7 @@ exit_label: if (FAILED(hr)) mp_warn(l, "Failed getting device name: %s\n", mp_HRESULT_to_str(hr)); PropVariantClear(&devname); - SAFE_RELEASE(pProps, IPropertyStore_Release(pProps)); + SAFE_RELEASE(pProps); return namestr ? namestr : talloc_strdup(talloc_ctx, ""); } @@ -722,7 +719,7 @@ static struct device_desc *get_device_desc(struct mp_log *l, IMMDevice *pDevice) struct device_desc *d = talloc_zero(NULL, struct device_desc); d->deviceID = talloc_memdup(d, deviceID, (wcslen(deviceID) + 1) * sizeof(wchar_t)); - SAFE_RELEASE(deviceID, CoTaskMemFree(deviceID)); + SAFE_DESTROY(deviceID, CoTaskMemFree(deviceID)); char *full_id = mp_to_utf8(NULL, d->deviceID); bstr id = bstr0(full_id); @@ -745,8 +742,8 @@ static void destroy_enumerator(struct enumerator *e) { if (!e) return; - SAFE_RELEASE(e->pDevices, IMMDeviceCollection_Release(e->pDevices)); - SAFE_RELEASE(e->pEnumerator, IMMDeviceEnumerator_Release(e->pEnumerator)); + SAFE_RELEASE(e->pDevices); + SAFE_RELEASE(e->pEnumerator); talloc_free(e); } @@ -782,7 +779,7 @@ static struct device_desc *device_desc_for_num(struct enumerator *e, UINT i) return NULL; } struct device_desc *d = get_device_desc(e->log, pDevice); - SAFE_RELEASE(pDevice, IMMDevice_Release(pDevice)); + SAFE_RELEASE(pDevice); return d; } @@ -797,7 +794,7 @@ static struct device_desc *default_device_desc(struct enumerator *e) return NULL; } struct device_desc *d = get_device_desc(e->log, pDevice); - SAFE_RELEASE(pDevice, IMMDevice_Release(pDevice)); + SAFE_RELEASE(pDevice); return d; } @@ -834,7 +831,7 @@ static HRESULT load_device(struct mp_log *l, exit_label: if (FAILED(hr)) mp_err(l, "Error loading selected device: %s\n", mp_HRESULT_to_str(hr)); - SAFE_RELEASE(pEnumerator, IMMDeviceEnumerator_Release(pEnumerator)); + SAFE_RELEASE(pEnumerator); return hr; } @@ -908,7 +905,7 @@ LPWSTR wasapi_find_deviceID(struct ao *ao) BSTR_P(device), d->id, d->name); } } - SAFE_RELEASE(d, talloc_free(d)); + SAFE_DESTROY(d, talloc_free(d)); } if (!deviceID) @@ -969,13 +966,13 @@ void wasapi_thread_uninit(struct ao *ao) if (state->pAudioClient) IAudioClient_Stop(state->pAudioClient); - SAFE_RELEASE(state->pRenderClient, IAudioRenderClient_Release(state->pRenderClient)); - SAFE_RELEASE(state->pAudioClock, IAudioClock_Release(state->pAudioClock)); - SAFE_RELEASE(state->pAudioVolume, ISimpleAudioVolume_Release(state->pAudioVolume)); - SAFE_RELEASE(state->pEndpointVolume, IAudioEndpointVolume_Release(state->pEndpointVolume)); - SAFE_RELEASE(state->pSessionControl, IAudioSessionControl_Release(state->pSessionControl)); - SAFE_RELEASE(state->pAudioClient, IAudioClient_Release(state->pAudioClient)); - SAFE_RELEASE(state->pDevice, IMMDevice_Release(state->pDevice)); - SAFE_RELEASE(state->hTask, AvRevertMmThreadCharacteristics(state->hTask)); + SAFE_RELEASE(state->pRenderClient); + SAFE_RELEASE(state->pAudioClock); + SAFE_RELEASE(state->pAudioVolume); + SAFE_RELEASE(state->pEndpointVolume); + SAFE_RELEASE(state->pSessionControl); + SAFE_RELEASE(state->pAudioClient); + SAFE_RELEASE(state->pDevice); + SAFE_DESTROY(state->hTask, AvRevertMmThreadCharacteristics(state->hTask)); MP_DBG(ao, "Thread uninit done\n"); } diff --git a/audio/out/push.c b/audio/out/push.c index a4a6808d7f..a722d19ea2 100644 --- a/audio/out/push.c +++ b/audio/out/push.c @@ -251,12 +251,11 @@ static int play(struct ao *ao, void **data, int samples, int flags) if (got_data) { p->still_playing = true; p->expected_end_time = 0; - } - // If we don't have new data, the decoder thread basically promises it - // will send new data as soon as it's available. - if (got_data) + // If we don't have new data, the decoder thread basically promises it + // will send new data as soon as it's available. wakeup_playthread(ao); + } pthread_mutex_unlock(&p->lock); return write_samples; } |