C++ ffplay不能播放多首歌曲
我已经从中获取了ffplay.c文件,并将其重新编辑为cpp文件,以嵌入到我的win32 gui应用程序中。我对它做了以下更改C++ ffplay不能播放多首歌曲,c++,winapi,ffmpeg,sdl,C++,Winapi,Ffmpeg,Sdl,我已经从中获取了ffplay.c文件,并将其重新编辑为cpp文件,以嵌入到我的win32 gui应用程序中。我对它做了以下更改 将int main函数转换为本地函数,如下所示,我可以将HWND传递给嵌入播放器 更改了回调函数,因为静态的函数不能被C++ EG、使用。 我从主gui调用以下函数 ft=std::async(launch::async, &Menu::play_song, this, songs_to_play.at(0)); 菜单::播放歌曲功能是: void Menu:
ft=std::async(launch::async, &Menu::play_song, this, songs_to_play.at(0));
菜单::播放歌曲
功能是:
void Menu::play_song(wstring song_path)
{
ready_to_play_song = false;
OutputDebugString(L"\nbefore song\n");
using std::future;
using std::async;
using std::launch;
string input{ song_path.begin(),song_path.end() };
Ffplay ffplay;
ffplay.play_song(input, h_sdl_window, &song_opened);
OutputDebugString(L"\nafter song\n");
ready_to_play_song = true;
}
问题是我只能演奏一首歌。如果我再次调用菜单::play_song
功能,声音会丢失,视频/艺术封面偶尔也会丢失。似乎有些资源没有被释放或类似的东西
我已将问题定位到此函数
int Ffplay::packet_queue_get(PacketQueue* q, AVPacket* pkt, int block, int* serial)
{
MyAVPacketList* pkt1;
int ret;
int count=0;
SDL_LockMutex(q->mutex);
for (;;)
{
if (q->abort_request)
{
ret = -1;
break;
}
pkt1 = q->first_pkt;
if (pkt1) {
q->first_pkt = pkt1->next;
if (!q->first_pkt)
q->last_pkt = NULL;
q->nb_packets--;
q->size -= pkt1->pkt.size + sizeof(*pkt1);
q->duration -= pkt1->pkt.duration;
*pkt = pkt1->pkt;
if (serial)
*serial = pkt1->serial;
av_free(pkt1);
ret = 1;
break;
}
else if (!block) {
ret = 0;
break;
}
else
{
logger.log(logger.LEVEL_INFO, "packet_queue before");
SDL_CondWait(q->cond, q->mutex);
logger.log(logger.LEVEL_INFO, "packet_queue after");
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}
调用
SDL\u CondWait(q->cond,q->mutex)代码>首先不要返回 ,抱歉这个问题有点模糊,因为我不能上传很多代码,因为这是我为什么把链接放在原来的一个和我的相似的地方,唯一的区别是我把函数从C静态函数变成C++公共函数。p>
问题在于变量SDL\u AudioDeviceID audio\u dev
使用
audio\u dev=SDL\u OpenAudioDevice(NULL,0,&wanted\u spec,&spec,SDL\u audio\u ALLOW\u FREQUENCY\u CHANGE | SDL\u audio\u ALLOW\u CHANNELS\u CHANGE)
未按计划分配变量,并且在使用SDL\u CloseAudioDevice(audio\u dev)关闭音频设备时分配变量代码>音频设备变量为0,因此设备未关闭,导致第二首歌曲丢失声音或视频可能挂起。
这是使用各种线程调用本地回调函数的结果,这些函数被强制转换为静态性质,正如SDLAPI所期望的那样
答案是将设备变量更改为静态设备,static SDL\u AudioDeviceID audio\u dev代码>因此可以从程序中的任何位置访问变量
ft=std::async(launch::async, &Menu::play_song, this, songs_to_play.at(0));
void Menu::play_song(wstring song_path)
{
ready_to_play_song = false;
OutputDebugString(L"\nbefore song\n");
using std::future;
using std::async;
using std::launch;
string input{ song_path.begin(),song_path.end() };
Ffplay ffplay;
ffplay.play_song(input, h_sdl_window, &song_opened);
OutputDebugString(L"\nafter song\n");
ready_to_play_song = true;
}
int Ffplay::packet_queue_get(PacketQueue* q, AVPacket* pkt, int block, int* serial)
{
MyAVPacketList* pkt1;
int ret;
int count=0;
SDL_LockMutex(q->mutex);
for (;;)
{
if (q->abort_request)
{
ret = -1;
break;
}
pkt1 = q->first_pkt;
if (pkt1) {
q->first_pkt = pkt1->next;
if (!q->first_pkt)
q->last_pkt = NULL;
q->nb_packets--;
q->size -= pkt1->pkt.size + sizeof(*pkt1);
q->duration -= pkt1->pkt.duration;
*pkt = pkt1->pkt;
if (serial)
*serial = pkt1->serial;
av_free(pkt1);
ret = 1;
break;
}
else if (!block) {
ret = 0;
break;
}
else
{
logger.log(logger.LEVEL_INFO, "packet_queue before");
SDL_CondWait(q->cond, q->mutex);
logger.log(logger.LEVEL_INFO, "packet_queue after");
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}