糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > Gstreamer/audioflingersink/APE: 使用palybin播放extrahigh insane等级的ape音乐出现卡顿现象

Gstreamer/audioflingersink/APE: 使用palybin播放extrahigh insane等级的ape音乐出现卡顿现象

时间:2023-04-12 04:26:12

相关推荐

Gstreamer/audioflingersink/APE: 使用palybin播放extrahigh insane等级的ape音乐出现卡顿现象

解决方法: 1. 增大 audioflingersink 中对 audiotrack 中 ringbuffer 大小的配置;

diff --git a/gst/audioflingersink/gstaudioflingersink.cpp b/gst/audioflingersink/gstaudioflingersink.cpp index 840c3f3..7ec653f 100644 --- a/gst/audioflingersink/gstaudioflingersink.cpp +++ b/gst/audioflingersink/gstaudioflingersink.cpp @@ -38,7 +38,7 @@ using namespace android; #undef LOG_TAG #define LOG_TAG "GstAudioFlingerSink" -#define DEFAULT_BUFFER_TIME (100 * GST_MSECOND) +#define DEFAULT_BUFFER_TIME (400 * GST_MSECOND) #define MIN_CORRECTION (50*GST_MSECOND) #define DEFAULT_VOLUME 1.0 #define DEFAULT_MUTE FALSE

2. 修改 playsink 的 pipeline,在 audioflingersink 之前添加 queue ,或者将 audioconvert 之前的 queue 转移到 audioflinger 之前。

diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 839cde1..cdde376 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -2726,7 +2726,7 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw) prev = chain->filter; } } - +#if 0 /* we have to add a queue when we need to decouple for the video sink in * visualisations and for streamsynchronizer */ GST_DEBUG_OBJECT (playsink, "adding audio queue"); @@ -2748,6 +2748,7 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw) } prev = chain->queue; } +#endif /* find ts-offset element */ gst_object_replace ((GstObject **) & chain->ts_offset, (GstObject *) @@ -2847,6 +2848,28 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw) } } + /* we have to add a queue when we need to playback APE music + * at the level higher than "high"*/ + GST_DEBUG_OBJECT (playsink, "adding audio queue"); + chain->queue = gst_element_factory_make ("queue", "asinkqueue"); + if (chain->queue == NULL) {+ post_missing_element_message (playsink, "queue"); + GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN, + (_("Missing element '%s' - check your GStreamer installation."), +"queue"), ("audio playback and visualizations might not work")); + } else {+ g_object_set (chain->queue, "silent", TRUE, NULL); + gst_bin_add (bin, chain->queue); + if (prev) {+ if (!gst_element_link_pads_full (prev, "src", chain->queue, "sink", + GST_PAD_LINK_CHECK_TEMPLATE_CAPS)) + goto link_failed; + } else {+ head = chain->queue; + } + prev = chain->queue; + } + if (prev) { /* we only have to link to the previous element if we have something in * front of the sink */

详细说明: 首先我们先来观察一下流畅播放和有卡顿播放时的log对比 1. 流畅播放情况下的log(添加queue后) 0:00:09.083588870 4410 0x1379180 DEBUG audioflingersink gstaudioflingersink.cpp:542:gst_android_audioringbuffer_write: size to write = 1179648 0:00:15.226308832 4410 0x1379180 LOGaudioflingersink gstaudioflingersink.cpp:675:gst_android_audioringbuffer_commit:<audioflingersink0> wrote 294912 samples 0:00:15.227225871 4410 0x1379180 LOGaudioflingersink gstaudioflingersink.cpp:649:gst_android_audioringbuffer_commit:<audioflingersink0> entering commit 0:00:15.227344318 4410 0x1379180 DEBUG audioflingersink gstaudioflingersink.cpp:522:gst_android_audioringbuffer_write: pos == 589824, data = 0xb4e37058, samples = 294912, next_sample = 589824 0:00:15.227488044 4410 0x1379180 DEBUG audioflingersink gstaudioflingersink.cpp:542:gst_android_audioringbuffer_write: size to write = 1179648 0:00:21.370138633 4410 0x1379180 LOGaudioflingersink gstaudioflingersink.cpp:675:gst_android_audioringbuffer_commit:<audioflingersink0> wrote 294912 samples 0:00:21.371076892 4410 0x1379180 LOGaudioflingersink gstaudioflingersink.cpp:649:gst_android_audioringbuffer_commit:<audioflingersink0> entering commit 0:00:21.371197152 4410 0x1379180 DEBUG audioflingersink gstaudioflingersink.cpp:522:gst_android_audioringbuffer_write: pos == 884736, data = 0xb53f6058, samples = 294912, next_sample = 884736

2. 有卡顿情况下的log 0:00:03.948740474 29704 0x105dc00 DEBUG audioflingersink gstaudioflingersink.cpp:542:gst_android_audioringbuffer_write: size to write = 1179648 0:00:09.994151475 29704 0x105dc00 LOGaudioflingersink gstaudioflingersink.cpp:675:gst_android_audioringbuffer_commit:<audioflingersink0> wrote 294912 samples 0:00:10.668653145 29704 0x105dc00 LOGaudioflingersink gstaudioflingersink.cpp:649:gst_android_audioringbuffer_commit:<audioflingersink0> entering commit 0:00:10.669338938 29704 0x105dc00 DEBUG audioflingersink gstaudioflingersink.cpp:522:gst_android_audioringbuffer_write: pos == 589824, data = 0xb5387058, samples = 294912, next_sample = 589824 0:00:10.669590031 29704 0x105dc00 DEBUG audioflingersink gstaudioflingersink.cpp:542:gst_android_audioringbuffer_write: size to write = 1179648 0:00:16.714031100 29704 0x105dc00 LOGaudioflingersink gstaudioflingersink.cpp:675:gst_android_audioringbuffer_commit:<audioflingersink0> wrote 294912 samples 0:00:17.390009935 29704 0x105dc00 LOGaudioflingersink gstaudioflingersink.cpp:649:gst_android_audioringbuffer_commit:<audioflingersink0> entering commit 0:00:17.390678775 29704 0x105dc00 DEBUG audioflingersink gstaudioflingersink.cpp:522:gst_android_audioringbuffer_write: pos == 884736, data = 0xb5387058, samples = 294912, next_sample = 884736

通过对比我们可以发现,在wrote ××× samples 和 entering commit 这两行log的时间上, 流畅情况下是没有大的时间差的,而在有卡顿的情况下我们可以发现存在0.67秒的时间差,这个在实时听感上也是一致的。也就是说造成播放中停顿的问题原因应该出在这个地方。 查看gstaudioflingersink.cpp中对应的代码可以确定,wrote ××× samples这一行代表了上一个buffer写到音频设备里完毕的时间,entering commit这一行代表了下一个buffer开始往设备里写的时间,其间存在着0.67秒的时间差。 现在我们来看看audioringbuffer中对于commit这个虚函数功能的定义,commit():write samples into the ringbuffer。 而在audioflingersink中定义的commit函数却直接调用了android MediaPlayerInterface::AudioSink 类中write()函数直接将buffer数据写到了音频设备中。因此在这里audiolingersink只是借用了audioringbuffer的接口,但是并没有真正用到ringbuffer。由于android的audio框架中已经有了ringbuffer机制,所以audioflingersink 插件的编写者应该是考虑到这一点,不想在这里再多此一举,而且可以减少由于buffering带来的延迟。 由此我们可以确定问题的原因是由于在往音频设备中写下一个buffer数据时,commit()函数没有能够及时的拿到上游传递过来的buffer数据而造成的卡顿延迟。 另外我们还要关注一下每次写的buffer的大小,log中wrote 294912 samples在采样率为48khz的时候相当于6.144秒的音频数据,如此之大的buffer数据应该是造成android audio框架中ringbuffer工作异常的元凶。在ringbuffer中数据消耗到一定水平时需要再次向其写入数据,而其中剩余的数据只够播放几十毫秒的时间,在audioflingersink之前存在audioconvert转换,转换6.144s的数据却需要几百毫秒,因此当ringbuffer中数据播放完而又得不到及时补充就会产生听感上的卡顿。 因此解决这个问题的方法有两种:第一,在audioflingersink之前添加一个queue,使得其随时都有准备好了的buffer数据可供使用;第二,增大ringbuffer的大小,给audioconvert留有足够的处理时间,从而不会造成播放过程的间断。

如果觉得《Gstreamer/audioflingersink/APE: 使用palybin播放extrahigh insane等级的ape音乐出现卡顿现象》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。