|
@@ -1,7 +1,9 @@
|
|
|
#include "player.h"
|
|
|
#include "packet.h"
|
|
|
#include "frame.h"
|
|
|
+#ifdef _WIN32
|
|
|
#include "Windows.h"
|
|
|
+#endif
|
|
|
|
|
|
static void sdl_audio_callback(void *opaque, uint8_t*stream, int len);
|
|
|
|
|
@@ -105,11 +107,11 @@ static int audio_decode_thread(void *arg)
|
|
|
|
|
|
while (false == is->buser_stop)
|
|
|
{
|
|
|
- got_frame = audio_decode_frame(is->p_acodec_ctx[is->iaudio_dec_index], &is->audio_pkt_queue, p_frame, is->rvc_hostapi);
|
|
|
+ got_frame = audio_decode_frame(is->m_pacodec_ctx[is->m_iaudio_dec_index], &is->audio_pkt_queue, p_frame, is->rvc_hostapi);
|
|
|
if (got_frame < 0){
|
|
|
if(-2 == got_frame){
|
|
|
- if (is->icurrent_index > is->iaudio_dec_index) {
|
|
|
- is->iaudio_dec_index++;
|
|
|
+ if (is->m_icurrent_index > is->m_iaudio_dec_index) {
|
|
|
+ is->m_iaudio_dec_index++;
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
@@ -121,7 +123,6 @@ static int audio_decode_thread(void *arg)
|
|
|
|
|
|
if (got_frame)
|
|
|
{
|
|
|
- //tb = { 1, p_frame->sample_rate };
|
|
|
tb.num = 1;
|
|
|
tb.den = p_frame->sample_rate;
|
|
|
//从frame队列找到一个可写的空间,若未停止则一直等待,已停止时返回NULL
|
|
@@ -141,13 +142,12 @@ static int audio_decode_thread(void *arg)
|
|
|
// 更新音频frame队列大小及写指针
|
|
|
frame_queue_push(&is->audio_frm_queue);
|
|
|
}
|
|
|
- //av_usleep(RVC_DEFAULT_SLEEP_TIME);
|
|
|
}
|
|
|
|
|
|
the_end:
|
|
|
av_frame_free(&p_frame);
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio decode thread exit, thread id is %u, and user stop flag is %s.", SDL_ThreadID(), is->buser_stop ? "true":"false");
|
|
|
- is->baudio_decode_finished = true;
|
|
|
+ is->m_baudio_decode_finished = true;
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -160,14 +160,13 @@ int open_audio_stream(player_stat_t *is)
|
|
|
int ret = -1;
|
|
|
|
|
|
// 1. 为音频流构建解码器AVCodecContext
|
|
|
- for (size_t index = 0; index < is->uFilesCount; index++){
|
|
|
+ for (size_t index = 0; index < is->m_uFilesCount; index++){
|
|
|
// 1.1 获取解码器参数AVCodecParameters
|
|
|
-
|
|
|
- p_codec_par = is->p_audio_stream[index]->codecpar;
|
|
|
+ p_codec_par = is->m_paudio_stream[index]->codecpar;
|
|
|
// 1.2 获取解码器
|
|
|
p_codec = avcodec_find_decoder(p_codec_par->codec_id);
|
|
|
if (NULL == p_codec) {
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "Cann't find codec!");
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "Cann't find codec!");
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -175,36 +174,40 @@ int open_audio_stream(player_stat_t *is)
|
|
|
// 1.3.1 p_codec_ctx初始化:分配结构体,使用p_codec初始化相应成员为默认值
|
|
|
p_codec_ctx = avcodec_alloc_context3(p_codec);
|
|
|
if (p_codec_ctx == NULL) {
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "avcodec_alloc_context3() failed.");
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "avcodec_alloc_context3() failed.");
|
|
|
return ret;
|
|
|
}
|
|
|
// 1.3.2 p_codec_ctx初始化:p_codec_par ==> p_codec_ctx,初始化相应成员
|
|
|
ret = avcodec_parameters_to_context(p_codec_ctx, p_codec_par);
|
|
|
if (ret < 0) {
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "avcodec_parameters_to_context() failed %d.", ret);
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "avcodec_parameters_to_context() failed %d.", ret);
|
|
|
+ avcodec_close(p_codec_ctx);
|
|
|
+ avcodec_free_context(&p_codec_ctx);
|
|
|
return ret;
|
|
|
}
|
|
|
// 1.3.3 p_codec_ctx初始化:使用p_codec初始化p_codec_ctx,初始化完成
|
|
|
ret = avcodec_open2(p_codec_ctx, p_codec, NULL);
|
|
|
if (ret < 0) {
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "avcodec_open2() failed %d.", ret);
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "avcodec_open2() failed %d.", ret);
|
|
|
+ avcodec_close(p_codec_ctx);
|
|
|
+ avcodec_free_context(&p_codec_ctx);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- p_codec_ctx->pkt_timebase = is->p_audio_stream[index]->time_base;
|
|
|
- is->p_acodec_ctx[index] = p_codec_ctx;
|
|
|
+ p_codec_ctx->pkt_timebase = is->m_paudio_stream[index]->time_base;
|
|
|
+ is->m_pacodec_ctx[index] = p_codec_ctx;
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d is->p_acodec_ctx[%d] = 0x%08x", __FUNCTION__, __LINE__, index, p_codec_ctx);
|
|
|
}
|
|
|
|
|
|
// 2. 创建音频解码线程
|
|
|
- is->audio_decode_tid = SDL_CreateThread(audio_decode_thread, "audio decode thread", is);
|
|
|
- if (NULL == is->audio_decode_tid) {
|
|
|
+ is->m_audio_decode_tid = SDL_CreateThread(audio_decode_thread, "audio decode thread", is);
|
|
|
+ if (NULL == is->m_audio_decode_tid) {
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "SDL_Create audio decode thread failed: %s.", SDL_GetError());
|
|
|
return -1;
|
|
|
}
|
|
|
else {
|
|
|
ret = 0;
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "create %s success, and thread id is %u.", SDL_GetThreadName(is->audio_decode_tid), SDL_GetThreadID(is->audio_decode_tid));
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "create %s success, and thread id is %u.", SDL_GetThreadName(is->m_audio_decode_tid), SDL_GetThreadID(is->m_audio_decode_tid));
|
|
|
}
|
|
|
|
|
|
return ret;
|
|
@@ -219,13 +222,12 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
|
|
|
frame_t *af = NULL;
|
|
|
|
|
|
while (frame_queue_nb_remaining(&is->audio_frm_queue) == 0){
|
|
|
- if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_param_tgt.bytes_per_sec / 2) {
|
|
|
+ if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->m_audio_param_tgt.bytes_per_sec / 2) {
|
|
|
return -1;
|
|
|
}
|
|
|
av_usleep(1000);
|
|
|
}
|
|
|
|
|
|
- //is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d.", __FUNCTION__, __LINE__);
|
|
|
// 若队列头部可读,则由af指向可读帧
|
|
|
if (!(af = frame_queue_peek_readable(&is->audio_frm_queue))) {
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d user stop flag is %s, function return", __FUNCTION__, __LINE__, is->buser_stop ? "true" : "false");
|
|
@@ -248,72 +250,72 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
|
|
|
// 在audio_open()函数中又有“is->audio_src = is->audio_param_tgt”
|
|
|
// 此处表示:如果frame中的音频参数 == is->audio_src == is->audio_param_tgt,那音频重采样的过程就免了(因此时is->swr_ctr是NULL)
|
|
|
// 否则使用frame(源)和is->audio_param_tgt(目标)中的音频参数来设置is->swr_ctx,并使用frame中的音频参数来赋值is->audio_src
|
|
|
- if (af->frame->format != is->audio_param_src.fmt ||
|
|
|
- dec_channel_layout != is->audio_param_src.channel_layout ||
|
|
|
- af->frame->sample_rate != is->audio_param_src.freq)
|
|
|
+ if (af->frame->format != is->m_audio_param_src.fmt ||
|
|
|
+ dec_channel_layout != is->m_audio_param_src.channel_layout ||
|
|
|
+ af->frame->sample_rate != is->m_audio_param_src.freq)
|
|
|
{
|
|
|
- swr_free(&is->audio_swr_ctx);
|
|
|
+ swr_free(&is->m_paudio_swr_ctx);
|
|
|
// 使用frame(源)和is->audio_param_tgt(目标)中的音频参数来设置is->audio_swr_ctx
|
|
|
- is->audio_swr_ctx = swr_alloc_set_opts(NULL,
|
|
|
- is->audio_param_tgt.channel_layout, (AVSampleFormat)is->audio_param_tgt.fmt, is->audio_param_tgt.freq,
|
|
|
+ is->m_paudio_swr_ctx = swr_alloc_set_opts(NULL,
|
|
|
+ is->m_audio_param_tgt.channel_layout, (AVSampleFormat)is->m_audio_param_tgt.fmt, is->m_audio_param_tgt.freq,
|
|
|
dec_channel_layout, (AVSampleFormat)af->frame->format, af->frame->sample_rate,
|
|
|
0, NULL);
|
|
|
- if (!is->audio_swr_ctx || swr_init(is->audio_swr_ctx) < 0)
|
|
|
+ if (!is->m_paudio_swr_ctx || swr_init(is->m_paudio_swr_ctx) < 0)
|
|
|
{
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!",
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!",
|
|
|
af->frame->sample_rate, av_get_sample_fmt_name((AVSampleFormat)af->frame->format), af->frame->channels,
|
|
|
- is->audio_param_tgt.freq, av_get_sample_fmt_name((AVSampleFormat)is->audio_param_tgt.fmt), is->audio_param_tgt.channels);
|
|
|
- swr_free(&is->audio_swr_ctx);
|
|
|
+ is->m_audio_param_tgt.freq, av_get_sample_fmt_name((AVSampleFormat)is->m_audio_param_tgt.fmt), is->m_audio_param_tgt.channels);
|
|
|
+ swr_free(&is->m_paudio_swr_ctx);
|
|
|
return -1;
|
|
|
}
|
|
|
// 使用frame中的参数更新is->audio_src,第一次更新后后面基本不用执行此if分支了,因为一个音频流中各frame通用参数一样
|
|
|
- is->audio_param_src.channel_layout = dec_channel_layout;
|
|
|
- is->audio_param_src.channels = af->frame->channels;
|
|
|
- is->audio_param_src.freq = af->frame->sample_rate;
|
|
|
- is->audio_param_src.fmt = (AVSampleFormat)af->frame->format;
|
|
|
+ is->m_audio_param_src.channel_layout = dec_channel_layout;
|
|
|
+ is->m_audio_param_src.channels = af->frame->channels;
|
|
|
+ is->m_audio_param_src.freq = af->frame->sample_rate;
|
|
|
+ is->m_audio_param_src.fmt = (AVSampleFormat)af->frame->format;
|
|
|
}
|
|
|
|
|
|
- if (is->audio_swr_ctx)
|
|
|
+ if (is->m_paudio_swr_ctx)
|
|
|
{
|
|
|
// 重采样输入参数1:输入音频样本数是af->frame->nb_samples
|
|
|
// 重采样输入参数2:输入音频缓冲区
|
|
|
const uint8_t **in = (const uint8_t **)af->frame->extended_data;
|
|
|
// 重采样输出参数1:输出音频缓冲区尺寸
|
|
|
// 重采样输出参数2:输出音频缓冲区
|
|
|
- uint8_t **out = &is->audio_frm_rwr;
|
|
|
+ uint8_t **out = &is->m_paudio_frm_rwr;
|
|
|
// 重采样输出参数:输出音频样本数(多加了256个样本)
|
|
|
- int out_count = (int64_t)wanted_nb_samples * is->audio_param_tgt.freq / af->frame->sample_rate + 256;
|
|
|
+ int out_count = (int64_t)wanted_nb_samples * is->m_audio_param_tgt.freq / af->frame->sample_rate + 256;
|
|
|
// 重采样输出参数:输出音频缓冲区尺寸(以字节为单位)
|
|
|
- int out_size = av_samples_get_buffer_size(NULL, is->audio_param_tgt.channels, out_count, (AVSampleFormat)is->audio_param_tgt.fmt, 0);
|
|
|
+ int out_size = av_samples_get_buffer_size(NULL, is->m_audio_param_tgt.channels, out_count, (AVSampleFormat)is->m_audio_param_tgt.fmt, 0);
|
|
|
int len2 = 0;
|
|
|
if (out_size < 0){
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "av_samples_get_buffer_size() failed.");
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "av_samples_get_buffer_size() failed.");
|
|
|
return -1;
|
|
|
}
|
|
|
- av_fast_malloc(&is->audio_frm_rwr, &is->audio_frm_rwr_size, out_size);
|
|
|
- if (!is->audio_frm_rwr) {
|
|
|
+ av_fast_malloc(&is->m_paudio_frm_rwr, &is->audio_frm_rwr_size, out_size);
|
|
|
+ if (!is->m_paudio_frm_rwr) {
|
|
|
return AVERROR(ENOMEM);
|
|
|
}
|
|
|
// 音频重采样:返回值是重采样后得到的音频数据中单个声道的样本数
|
|
|
- len2 = swr_convert(is->audio_swr_ctx, out, out_count, in, af->frame->nb_samples);
|
|
|
+ len2 = swr_convert(is->m_paudio_swr_ctx, out, out_count, in, af->frame->nb_samples);
|
|
|
if (len2 < 0){
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "swr_convert() failed.");
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "swr_convert() failed.");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (len2 == out_count){
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio buffer is probably too small.");
|
|
|
- if (swr_init(is->audio_swr_ctx) < 0)
|
|
|
- swr_free(&is->audio_swr_ctx);
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "audio buffer is probably too small.");
|
|
|
+ if (swr_init(is->m_paudio_swr_ctx) < 0)
|
|
|
+ swr_free(&is->m_paudio_swr_ctx);
|
|
|
}
|
|
|
- is->p_audio_frm = is->audio_frm_rwr;
|
|
|
+ is->m_paudio_frm = is->m_paudio_frm_rwr;
|
|
|
// 重采样返回的一帧音频数据大小(以字节为单位)
|
|
|
- resampled_data_size = len2 * is->audio_param_tgt.channels * av_get_bytes_per_sample((AVSampleFormat)is->audio_param_tgt.fmt);
|
|
|
+ resampled_data_size = len2 * is->m_audio_param_tgt.channels * av_get_bytes_per_sample((AVSampleFormat)is->m_audio_param_tgt.fmt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 未经重采样,则将指针指向frame中的音频数据
|
|
|
- is->p_audio_frm = af->frame->data[0];
|
|
|
+ is->m_paudio_frm = af->frame->data[0];
|
|
|
resampled_data_size = data_size;
|
|
|
}
|
|
|
|
|
@@ -341,6 +343,7 @@ static int audio_resample(player_stat_t *is, int64_t audio_callback_time)
|
|
|
return resampled_data_size;
|
|
|
}
|
|
|
|
|
|
+#ifdef _WIN32
|
|
|
static char* Utf8ToGB2312(const char* utf8)
|
|
|
{
|
|
|
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
|
|
@@ -363,6 +366,7 @@ static char* Utf8ToGB2312(const char* utf8)
|
|
|
return str;
|
|
|
}
|
|
|
|
|
|
+#endif
|
|
|
|
|
|
static int open_audio_playing(void *arg)
|
|
|
{
|
|
@@ -370,9 +374,9 @@ static int open_audio_playing(void *arg)
|
|
|
SDL_AudioSpec wanted_spec = {0};
|
|
|
SDL_AudioSpec actual_spec = {0};
|
|
|
|
|
|
- wanted_spec.freq = is->p_acodec_ctx[is->iaudio_dec_index]->sample_rate; // 采样率
|
|
|
+ wanted_spec.freq = is->m_pacodec_ctx[is->m_iaudio_dec_index]->sample_rate; // 采样率
|
|
|
wanted_spec.format = AUDIO_S16SYS; // S表带符号,16是采样深度,SYS表采用系统字节序
|
|
|
- wanted_spec.channels = is->p_acodec_ctx[is->iaudio_dec_index]->channels; // 声音通道数
|
|
|
+ wanted_spec.channels = is->m_pacodec_ctx[is->m_iaudio_dec_index]->channels; // 声音通道数
|
|
|
wanted_spec.silence = 0; // 静音值
|
|
|
// wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; // SDL声音缓冲区尺寸,单位是单声道采样点尺寸x通道数
|
|
|
// SDL声音缓冲区尺寸,单位是单声道采样点尺寸x声道数
|
|
@@ -380,42 +384,70 @@ static int open_audio_playing(void *arg)
|
|
|
wanted_spec.callback = sdl_audio_callback; // 回调函数,若为NULL,则应使用SDL_QueueAudio()机制
|
|
|
wanted_spec.userdata = is; // 提供给回调函数的参数
|
|
|
|
|
|
- if (NULL == is->straudiodev) {
|
|
|
+ if (NULL == is->m_straudiodev) {
|
|
|
+ static bool blog = true;
|
|
|
int iaudioapeaker = SDL_GetNumAudioDevices(0);
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "audio output device number is %d.", iaudioapeaker);
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "audio output device count is %d.", iaudioapeaker);
|
|
|
+ }
|
|
|
+
|
|
|
int i = 0;
|
|
|
for (; i < iaudioapeaker; i++) {
|
|
|
+ #ifdef _WIN32
|
|
|
char* strdevice = Utf8ToGB2312(SDL_GetAudioDeviceName(i, 0));
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "device id %d audio device name is %s.", i, strdevice);
|
|
|
- if (is->paudiodev && strstr(strdevice, is->paudiodev)) {
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "device id %d audio device name is %s.", i, strdevice);
|
|
|
+ }
|
|
|
+ if (is->m_paudiodev && strstr(strdevice, is->m_paudiodev)) {
|
|
|
const char* strdevname = SDL_GetAudioDeviceName(i, 0);
|
|
|
- is->straudiodev = av_strdup(strdevname);
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "%s matched audio device name is %s.", is->paudiodev, strdevice);
|
|
|
+ is->m_straudiodev = av_strdup(strdevname);
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "%s matched audio device name is %s.", is->m_paudiodev, strdevice);
|
|
|
+ }
|
|
|
delete []strdevice;
|
|
|
break;
|
|
|
}
|
|
|
- else {
|
|
|
- delete[] strdevice;
|
|
|
+ else {
|
|
|
+ delete[] strdevice;
|
|
|
+#else
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "device id %d audio device name is %s.", i, SDL_GetAudioDeviceName(i, 0));
|
|
|
+ }
|
|
|
+ if (is->m_paudiodev && strstr(SDL_GetAudioDeviceName(i, 0), is->m_paudiodev)) {
|
|
|
+ const char* strdevname = SDL_GetAudioDeviceName(i, 0);
|
|
|
+ is->m_straudiodev = av_strdup(strdevname);
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "%s matched audio device name is %s.", is->m_paudiodev, strdevname);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ #endif
|
|
|
}
|
|
|
}
|
|
|
if (i == iaudioapeaker) {
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "matched audio device name (%s) failed!", is->straudiodev ? is->straudiodev : "null");
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "matched audio device name (%s) failed!", is->m_straudiodev ? is->m_straudiodev : "null");
|
|
|
}
|
|
|
|
|
|
{
|
|
|
int inum = SDL_GetNumAudioDrivers();
|
|
|
int i = 0;
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "Audio Drivers number is %d.", inum);
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "Audio Drivers number is %d.", inum);
|
|
|
+ }
|
|
|
for (; i < inum; i++) {
|
|
|
const char* drivername = SDL_GetAudioDriver(i);
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "[%d] Audio Drivers name is %s.", i, drivername);
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "[%d] Audio Drivers name is %s.", i, drivername);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "current audio driver name is %s.", SDL_GetCurrentAudioDriver());
|
|
|
+ if (blog) {
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_INFO, "current audio driver name is %s.", SDL_GetCurrentAudioDriver());
|
|
|
+ }
|
|
|
+ blog = false;
|
|
|
}
|
|
|
|
|
|
- while (!(audio_dev = SDL_OpenAudioDevice(is->straudiodev, 0, &wanted_spec, &actual_spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))){
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "SDL_OpenAudio (%d channels, %d Hz): %s",wanted_spec.channels, wanted_spec.freq, SDL_GetError());
|
|
|
+ while (!(is->m_audio_dev = SDL_OpenAudioDevice(is->m_straudiodev, 0, &wanted_spec, &actual_spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))){
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_OpenAudio (%d channels, %d Hz): %s",wanted_spec.channels, wanted_spec.freq, SDL_GetError());
|
|
|
if (!wanted_spec.channels) {
|
|
|
if (!wanted_spec.freq) {
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_ERROR,"No more combinations to try, audio open failed!");
|
|
@@ -425,34 +457,34 @@ static int open_audio_playing(void *arg)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "SDL_OpenAudioDevice success and audio_dev is %d.", audio_dev);
|
|
|
- is->audio_param_tgt.fmt = AV_SAMPLE_FMT_S16;
|
|
|
- is->audio_param_tgt.freq = actual_spec.freq;
|
|
|
- is->audio_param_tgt.channel_layout = av_get_default_channel_layout(actual_spec.channels);
|
|
|
- is->audio_param_tgt.channels = actual_spec.channels;
|
|
|
- is->audio_param_tgt.frame_size = av_samples_get_buffer_size(NULL, actual_spec.channels, 1, (AVSampleFormat)is->audio_param_tgt.fmt, 1);
|
|
|
- is->audio_param_tgt.bytes_per_sec = av_samples_get_buffer_size(NULL, actual_spec.channels, actual_spec.freq, (AVSampleFormat)is->audio_param_tgt.fmt, 1);
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_OpenAudioDevice success and audio_dev is %d.", is->m_audio_dev);
|
|
|
+ is->m_audio_param_tgt.fmt = AV_SAMPLE_FMT_S16;
|
|
|
+ is->m_audio_param_tgt.freq = actual_spec.freq;
|
|
|
+ is->m_audio_param_tgt.channel_layout = av_get_default_channel_layout(actual_spec.channels);
|
|
|
+ is->m_audio_param_tgt.channels = actual_spec.channels;
|
|
|
+ is->m_audio_param_tgt.frame_size = av_samples_get_buffer_size(NULL, actual_spec.channels, 1, (AVSampleFormat)is->m_audio_param_tgt.fmt, 1);
|
|
|
+ is->m_audio_param_tgt.bytes_per_sec = av_samples_get_buffer_size(NULL, actual_spec.channels, actual_spec.freq, (AVSampleFormat)is->m_audio_param_tgt.fmt, 1);
|
|
|
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "audio param target (%d channels, %d Hz, channel_layout(%d), frame_size(%d), bytes_per_sec(%d)).", actual_spec.channels, actual_spec.freq, is->audio_param_tgt.channel_layout, is->audio_param_tgt.frame_size, is->audio_param_tgt.bytes_per_sec);
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio param target (%d channels, %d Hz, channel_layout(%d), frame_size(%d), bytes_per_sec(%d)).", actual_spec.channels, actual_spec.freq, is->m_audio_param_tgt.channel_layout, is->m_audio_param_tgt.frame_size, is->m_audio_param_tgt.bytes_per_sec);
|
|
|
|
|
|
- if (is->audio_param_tgt.bytes_per_sec <= 0 || is->audio_param_tgt.frame_size <= 0){
|
|
|
- is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "av_samples_get_buffer_size failed.");
|
|
|
- SDL_CloseAudioDevice(audio_dev);
|
|
|
+ if (is->m_audio_param_tgt.bytes_per_sec <= 0 || is->m_audio_param_tgt.frame_size <= 0){
|
|
|
+ is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "av_samples_get_buffer_size failed.");
|
|
|
+ SDL_CloseAudioDevice(is->m_audio_dev);
|
|
|
return -1;
|
|
|
}
|
|
|
- is->audio_param_src = is->audio_param_tgt;
|
|
|
+ is->m_audio_param_src = is->m_audio_param_tgt;
|
|
|
is->audio_hw_buf_size = actual_spec.size; // SDL音频缓冲区大小
|
|
|
is->audio_frm_size = 0;
|
|
|
is->audio_cp_index = 0;
|
|
|
|
|
|
- SDL_PauseAudioDevice(audio_dev, 0);
|
|
|
+ SDL_PauseAudioDevice(is->m_audio_dev, 0);
|
|
|
|
|
|
- SDL_LockMutex(is->audio_play_wait_mutex);
|
|
|
- SDL_CondWait(is->audio_play_cond, is->audio_play_wait_mutex);
|
|
|
- SDL_UnlockMutex(is->audio_play_wait_mutex);
|
|
|
+ SDL_LockMutex(is->m_audio_play_wait_mutex);
|
|
|
+ SDL_CondWait(is->m_audio_play_cond, is->m_audio_play_wait_mutex);
|
|
|
+ SDL_UnlockMutex(is->m_audio_play_wait_mutex);
|
|
|
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "----------%s:%d before SDL Close Audio Device.", __FUNCTION__, __LINE__);
|
|
|
- SDL_CloseAudioDevice(audio_dev);
|
|
|
+ SDL_CloseAudioDevice(is->m_audio_dev);
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "---------%s:%d after SDL Close Audio Device.", __FUNCTION__, __LINE__);
|
|
|
|
|
|
return 0;
|
|
@@ -471,9 +503,9 @@ static void sdl_audio_callback(void *opaque, uint8_t*stream, int len)
|
|
|
int audio_size = 0, len1 = 0;
|
|
|
|
|
|
if (is->buser_stop){
|
|
|
- SDL_LockMutex(is->audio_play_wait_mutex);
|
|
|
- SDL_CondSignal(is->audio_play_cond);
|
|
|
- SDL_UnlockMutex(is->audio_play_wait_mutex);
|
|
|
+ SDL_LockMutex(is->m_audio_play_wait_mutex);
|
|
|
+ SDL_CondSignal(is->m_audio_play_cond);
|
|
|
+ SDL_UnlockMutex(is->m_audio_play_wait_mutex);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -485,18 +517,18 @@ static void sdl_audio_callback(void *opaque, uint8_t*stream, int len)
|
|
|
audio_size = audio_resample(is, audio_callback_time);
|
|
|
if (audio_size < 0){
|
|
|
if (-1 == audio_size) {
|
|
|
- if (is->baudio_decode_finished) {
|
|
|
+ if (is->m_baudio_decode_finished) {
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio_size is -1 sdl_audio_callback return, and set abort flag to true.");
|
|
|
is->on_audio_play_finished(is->user_data);
|
|
|
- SDL_LockMutex(is->audio_play_wait_mutex);
|
|
|
- SDL_CondSignal(is->audio_play_cond);
|
|
|
- SDL_UnlockMutex(is->audio_play_wait_mutex);
|
|
|
+ SDL_LockMutex(is->m_audio_play_wait_mutex);
|
|
|
+ SDL_CondSignal(is->m_audio_play_cond);
|
|
|
+ SDL_UnlockMutex(is->m_audio_play_wait_mutex);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
/* if error, just output silence */
|
|
|
- is->p_audio_frm = NULL;
|
|
|
- is->audio_frm_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_param_tgt.frame_size * is->audio_param_tgt.frame_size;
|
|
|
+ is->m_paudio_frm = NULL;
|
|
|
+ is->audio_frm_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->m_audio_param_tgt.frame_size * is->m_audio_param_tgt.frame_size;
|
|
|
}
|
|
|
else{
|
|
|
is->audio_frm_size = audio_size;
|
|
@@ -510,7 +542,7 @@ static void sdl_audio_callback(void *opaque, uint8_t*stream, int len)
|
|
|
len1 = len;
|
|
|
}
|
|
|
// 2. 将转换后的音频数据拷贝到音频缓冲区stream中,之后的播放就是音频设备驱动程序的工作了
|
|
|
- if (is->p_audio_frm != NULL){
|
|
|
+ if (is->m_paudio_frm != NULL){
|
|
|
SDL_memset(stream, 0, len1);
|
|
|
int ivolume = is->uVolume;
|
|
|
if (0 == is->on_audio_volume(&ivolume,is->user_data)){
|
|
@@ -518,9 +550,9 @@ static void sdl_audio_callback(void *opaque, uint8_t*stream, int len)
|
|
|
}
|
|
|
//is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio uVolume is %d.", ivolume);
|
|
|
//SDL_MixAudio(stream, (uint8_t*)is->p_audio_frm + is->audio_cp_index, len1, ivolume);
|
|
|
- SDL_MixAudioFormat(stream, (uint8_t*)is->p_audio_frm + is->audio_cp_index, AUDIO_S16SYS, len1, ivolume);
|
|
|
- if (is->prvc_cb && is->prvc_cb->cb_playing_audiodata) {
|
|
|
- is->prvc_cb->cb_playing_audiodata(&(is->audio_param_tgt), (uint8_t*)is->p_audio_frm + is->audio_cp_index, len1, is->prvc_cb->user_data);
|
|
|
+ SDL_MixAudioFormat(stream, (uint8_t*)is->m_paudio_frm + is->audio_cp_index, AUDIO_S16SYS, len1, ivolume);
|
|
|
+ if (is->m_prvc_cb && is->m_prvc_cb->cb_playing_audiodata) {
|
|
|
+ is->m_prvc_cb->cb_playing_audiodata(&(is->m_audio_param_tgt), (uint8_t*)is->m_paudio_frm + is->audio_cp_index, len1, is->m_prvc_cb->user_data);
|
|
|
}
|
|
|
}
|
|
|
else{
|
|
@@ -541,7 +573,7 @@ static void sdl_audio_callback(void *opaque, uint8_t*stream, int len)
|
|
|
// 更新音频时钟,更新时刻:每次往声卡缓冲区拷入数据后
|
|
|
// 前面audio_decode_frame中更新的is->audio_clock是以音频帧为单位,所以此处第二个参数要减去未拷贝数据量占用的时间
|
|
|
set_clock_at(&is->audio_clk,
|
|
|
- is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_param_tgt.bytes_per_sec,
|
|
|
+ is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->m_audio_param_tgt.bytes_per_sec,
|
|
|
is->audio_clock_serial,
|
|
|
audio_callback_time / 1000000.0);
|
|
|
}
|
|
@@ -550,7 +582,7 @@ static void sdl_audio_callback(void *opaque, uint8_t*stream, int len)
|
|
|
int open_audio(player_stat_t *is)
|
|
|
{
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "enter open_audio()");
|
|
|
- if (-1 == is->audio_idx[is->icurrent_index]){
|
|
|
+ if (-1 == is->audio_idx[is->m_icurrent_index]){
|
|
|
is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "not find audio stream");
|
|
|
}
|
|
|
else {
|