C++ ffplay不能播放多首歌曲

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:

我已经从中获取了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::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;
    }