void movie_player::copy_audio_to_stream(uint8_t *pbStream, int iStreamSize) { std::lock_guard<std::mutex> audioLock(decoding_audio_mutex); bool fFirst = true; while(iStreamSize > 0 && !aborting) { if(audio_buffer_index >= audio_buffer_size) { int iAudioSize = decode_audio_frame(fFirst); fFirst = false; if(iAudioSize <= 0) { std::memset(audio_buffer, 0, audio_buffer_size); } else { audio_buffer_size = iAudioSize; } audio_buffer_index = 0; } int iCopyLength = audio_buffer_size - audio_buffer_index; if(iCopyLength > iStreamSize) { iCopyLength = iStreamSize; } std::memcpy(pbStream, (uint8_t *)audio_buffer + audio_buffer_index, iCopyLength); iStreamSize -= iCopyLength; pbStream += iCopyLength; audio_buffer_index += iCopyLength; } }
ProjectClip::~ProjectClip() { // controller is deleted in bincontroller abortAudioThumbs(); bin()->slotAbortAudioThumb(m_id); QMutexLocker audioLock(&m_audioMutex); m_thumbMutex.lock(); m_requestedThumbs.clear(); m_thumbMutex.unlock(); m_thumbThread.waitForFinished(); delete m_thumbsProducer; audioFrameCache.clear(); }
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); } }