/* Dynamically change the number of channels managed by the mixer. If decreasing the number of channels, the upper channels are stopped. */ int Mix_AllocateChannels(int numchans) { if ( numchans<0 || numchans==num_channels ) return(num_channels); if ( numchans < num_channels ) { /* Stop the affected channels */ int i; for(i=numchans; i < num_channels; i++) { Mix_UnregisterAllEffects(i); Mix_HaltChannel(i); } } SDL_LockAudio(); mix_channel = (struct _Mix_Channel *) SDL_realloc(mix_channel, numchans * sizeof(struct _Mix_Channel)); if ( numchans > num_channels ) { /* Initialize the new channels */ int i; for(i=num_channels; i < numchans; i++) { mix_channel[i].chunk = NULL; mix_channel[i].playing = 0; mix_channel[i].looping = 0; mix_channel[i].volume = SDL_MIX_MAXVOLUME; mix_channel[i].fade_volume = SDL_MIX_MAXVOLUME; mix_channel[i].fade_volume_reset = SDL_MIX_MAXVOLUME; mix_channel[i].fading = MIX_NO_FADING; mix_channel[i].tag = -1; mix_channel[i].expire = 0; mix_channel[i].effects = NULL; mix_channel[i].paused = 0; } } num_channels = numchans; SDL_UnlockAudio(); return(num_channels); }
void THMovie::unload() { m_fAborting = true; if(m_pAudioQueue) { m_pAudioQueue->release(); } if(m_pVideoQueue) { m_pVideoQueue->release(); } m_pMoviePictureBuffer->abort(); if(m_pStreamThread) { SDL_WaitThread(m_pStreamThread, nullptr); m_pStreamThread = nullptr; } if(m_pVideoThread) { SDL_WaitThread(m_pVideoThread, nullptr); m_pVideoThread = nullptr; } //wait until after other threads are closed to clear the packet queues //so we don't free something being used. if(m_pAudioQueue) { while(m_pAudioQueue->getCount() > 0) { AVPacket* p = m_pAudioQueue->pull(false); av_packet_unref(p); } delete m_pAudioQueue; m_pAudioQueue = nullptr; } if(m_pVideoQueue) { while(m_pVideoQueue->getCount() > 0) { AVPacket* p = m_pVideoQueue->pull(false); av_packet_unref(p); } delete m_pVideoQueue; m_pVideoQueue = nullptr; } m_pMoviePictureBuffer->deallocate(); if(m_pVideoCodecContext) { avcodec_close(m_pVideoCodecContext); m_pVideoCodecContext = nullptr; } if(m_iChannel >= 0) { Mix_UnregisterAllEffects(m_iChannel); Mix_HaltChannel(m_iChannel); Mix_FreeChunk(m_pChunk); m_iChannel = -1; } SDL_LockMutex(m_pDecodingAudioMutex); if(m_iAudioBufferMaxSize > 0) { av_free(m_pbAudioBuffer); m_iAudioBufferMaxSize = 0; } if(m_pAudioCodecContext) { avcodec_close(m_pAudioCodecContext); m_pAudioCodecContext = nullptr; } av_frame_free(&m_audio_frame); #ifdef CORSIX_TH_USE_FFMPEG swr_free(&m_pAudioResampleContext); #elif defined(CORSIX_TH_USE_LIBAV) // avresample_free doesn't skip nullptr on it's own. if (m_pAudioResampleContext != nullptr) { avresample_free(&m_pAudioResampleContext); m_pAudioResampleContext = nullptr; } #endif if(m_pAudioPacket) { m_pAudioPacket->data = m_pbAudioPacketData; m_pAudioPacket->size = m_iAudioPacketSize; av_packet_unref(m_pAudioPacket); av_free(m_pAudioPacket); m_pAudioPacket = nullptr; m_pbAudioPacketData = nullptr; m_iAudioPacketSize = 0; } SDL_UnlockMutex(m_pDecodingAudioMutex); if(m_pFormatContext) { avformat_close_input(&m_pFormatContext); } }
void movie_player::unload() { aborting = true; if(audio_queue) { audio_queue->release(); } if(video_queue) { video_queue->release(); } movie_picture_buffer->abort(); if(stream_thread.joinable()) { stream_thread.join(); } if(video_thread.joinable()) { video_thread.join(); } //wait until after other threads are closed to clear the packet queues //so we don't free something being used. if(audio_queue) { while(audio_queue->get_count() > 0) { AVPacket* p = audio_queue->pull(false); av_packet_unref(p); av_free(p); } delete audio_queue; audio_queue = nullptr; } if(video_queue) { while(video_queue->get_count() > 0) { AVPacket* p = video_queue->pull(false); av_packet_unref(p); av_free(p); } delete video_queue; video_queue = nullptr; } movie_picture_buffer->deallocate(); #if (defined(CORSIX_TH_USE_LIBAV) && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 14, 0)) || \ (defined(CORSIX_TH_USE_FFMPEG) && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)) if(video_codec_context) { avcodec_free_context(&video_codec_context); video_codec_context = nullptr; } #endif if(audio_channel >= 0) { Mix_UnregisterAllEffects(audio_channel); Mix_HaltChannel(audio_channel); Mix_FreeChunk(empty_audio_chunk); audio_channel = -1; } std::lock_guard<std::mutex> audioLock(decoding_audio_mutex); if(audio_buffer_max_size > 0) { av_free(audio_buffer); audio_buffer_max_size = 0; } #if (defined(CORSIX_TH_USE_LIBAV) && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 14, 0)) || \ (defined(CORSIX_TH_USE_FFMPEG) && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)) if(audio_codec_context) { avcodec_free_context(&audio_codec_context); audio_codec_context = nullptr; } #endif av_frame_free(&audio_frame); #ifdef CORSIX_TH_USE_FFMPEG swr_free(&audio_resample_context); #elif defined(CORSIX_TH_USE_LIBAV) // avresample_free doesn't skip nullptr on it's own. if (audio_resample_context != nullptr) { avresample_free(&audio_resample_context); audio_resample_context = nullptr; } #endif if(audio_packet) { audio_packet->data = audio_packet_data; audio_packet->size = audio_packet_size; av_packet_unref(audio_packet); av_free(audio_packet); audio_packet = nullptr; audio_packet_data = nullptr; audio_packet_size = 0; } if(format_context) { avformat_close_input(&format_context); } }