From 6dde3bf96c982ad4420297bf8a446d4894333e3f Mon Sep 17 00:00:00 2001 From: Tuomas Virtanen Date: Fri, 29 Jun 2018 01:00:24 +0300 Subject: Locking cleanups --- src/internal/kitdecoder.c | 184 ++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 96 deletions(-) (limited to 'src/internal/kitdecoder.c') diff --git a/src/internal/kitdecoder.c b/src/internal/kitdecoder.c index b57cbc4..e2d0a25 100644 --- a/src/internal/kitdecoder.c +++ b/src/internal/kitdecoder.c @@ -71,23 +71,25 @@ Kit_Decoder* Kit_CreateDecoder(const Kit_Source *src, int stream_index, for(int i = 0; i < 2; i++) { dec->buffer[i] = Kit_CreateBuffer(bsizes[i], free_hooks[i]); if(dec->buffer[i] == NULL) { - Kit_SetError("Unable to allocate ringbuffer type %d for stream %d", i, stream_index); + Kit_SetError("Unable to allocate buffer for stream %d: %s", stream_index, SDL_GetError()); goto exit_3; } + } - dec->lock[i] = SDL_CreateMutex(); - if(dec->lock[i] == NULL) { - Kit_SetError("Unable to allocate mutex type %d for stream %d", i, stream_index); - goto exit_3; - } + // Create a lock for output buffer synchronization + dec->output_lock = SDL_CreateMutex(); + if(dec->output_lock == NULL) { + Kit_SetError("Unable to allocate mutex for stream %d: %s", stream_index, SDL_GetError()); + goto exit_4; } // That's that return dec; +exit_4: + SDL_DestroyMutex(dec->output_lock); exit_3: - for(int i = 0; i < 2; i++) { - SDL_DestroyMutex(dec->lock[i]); + for(int i = 0; i < KIT_DEC_BUF_COUNT; i++) { Kit_DestroyBuffer(dec->buffer[i]); } avcodec_close(codec_ctx); @@ -99,6 +101,51 @@ exit_0: return NULL; } +void Kit_CloseDecoder(Kit_Decoder *dec) { + if(dec == NULL) return; + if(dec->dec_close) { + dec->dec_close(dec); + } + for(int i = 0; i < KIT_DEC_BUF_COUNT; i++) { + Kit_DestroyBuffer(dec->buffer[i]); + } + SDL_DestroyMutex(dec->output_lock); + avcodec_close(dec->codec_ctx); + avcodec_free_context(&dec->codec_ctx); + free(dec); +} + +int Kit_RunDecoder(Kit_Decoder *dec) { + if(dec == NULL) return 0; + + AVPacket *in_packet; + int is_output_full = 1; + + // First, check if there is room in output buffer + if(SDL_LockMutex(dec->output_lock) == 0) { + is_output_full = Kit_IsBufferFull(dec->buffer[KIT_DEC_BUF_OUT]); + SDL_UnlockMutex(dec->output_lock); + } + if(is_output_full) { + return 0; + } + + // Then, see if we have incoming data + in_packet = Kit_ReadDecoderInput(dec); + if(in_packet == NULL) { + return 0; + } + + // Run decoder with incoming packet + dec->dec_decode(dec, in_packet); + + // Free raw packet before returning + av_packet_free(&in_packet); + return 1; +} + +// ---- Information API ---- + int Kit_GetDecoderCodecInfo(const Kit_Decoder *dec, Kit_Codec *codec) { if(dec == NULL) { memset(codec, 0, sizeof(Kit_Codec)); @@ -125,6 +172,8 @@ int Kit_GetDecoderStreamIndex(const Kit_Decoder *dec) { return dec->stream_index; } +// ---- Clock handling ---- + void Kit_SetDecoderClockSync(Kit_Decoder *dec, double sync) { if(dec == NULL) return; @@ -137,66 +186,52 @@ void Kit_ChangeDecoderClockSync(Kit_Decoder *dec, double sync) { dec->clock_sync += sync; } +// ---- Input buffer handling ---- + int Kit_WriteDecoderInput(Kit_Decoder *dec, AVPacket *packet) { assert(dec != NULL); - int ret = 1; - if(SDL_LockMutex(dec->lock[KIT_DEC_IN]) == 0) { - ret = Kit_WriteBuffer(dec->buffer[KIT_DEC_IN], packet); - SDL_UnlockMutex(dec->lock[KIT_DEC_IN]); - } - return ret; + return Kit_WriteBuffer(dec->buffer[KIT_DEC_BUF_IN], packet); } bool Kit_CanWriteDecoderInput(Kit_Decoder *dec) { assert(dec != NULL); - bool ret = false; - if(SDL_LockMutex(dec->lock[KIT_DEC_IN]) == 0) { - ret = !Kit_IsBufferFull(dec->buffer[KIT_DEC_IN]); - SDL_UnlockMutex(dec->lock[KIT_DEC_IN]); - } - return ret; + return !Kit_IsBufferFull(dec->buffer[KIT_DEC_BUF_IN]); } AVPacket* Kit_ReadDecoderInput(Kit_Decoder *dec) { assert(dec != NULL); - AVPacket *ret = NULL; - if(SDL_LockMutex(dec->lock[KIT_DEC_IN]) == 0) { - ret = Kit_ReadBuffer(dec->buffer[KIT_DEC_IN]); - SDL_UnlockMutex(dec->lock[KIT_DEC_IN]); - } - return ret; + return Kit_ReadBuffer(dec->buffer[KIT_DEC_BUF_IN]); } +void Kit_ClearDecoderInput(Kit_Decoder *dec) { + Kit_ClearBuffer(dec->buffer[KIT_DEC_BUF_IN]); +} + +// ---- Output buffer handling ---- + int Kit_WriteDecoderOutput(Kit_Decoder *dec, void *packet) { assert(dec != NULL); int ret = 1; - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - ret = Kit_WriteBuffer(dec->buffer[KIT_DEC_OUT], packet); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); + if(SDL_LockMutex(dec->output_lock) == 0) { + ret = Kit_WriteBuffer(dec->buffer[KIT_DEC_BUF_OUT], packet); + SDL_UnlockMutex(dec->output_lock); } return ret; } void Kit_ClearDecoderOutput(Kit_Decoder *dec) { - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - Kit_ClearBuffer(dec->buffer[KIT_DEC_OUT]); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); - } -} - -void Kit_ClearDecoderInput(Kit_Decoder *dec) { - if(SDL_LockMutex(dec->lock[KIT_DEC_IN]) == 0) { - Kit_ClearBuffer(dec->buffer[KIT_DEC_IN]); - SDL_UnlockMutex(dec->lock[KIT_DEC_IN]); + if(SDL_LockMutex(dec->output_lock) == 0) { + Kit_ClearBuffer(dec->buffer[KIT_DEC_BUF_OUT]); + SDL_UnlockMutex(dec->output_lock); } } void* Kit_PeekDecoderOutput(Kit_Decoder *dec) { assert(dec != NULL); void *ret = NULL; - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - ret = Kit_PeekBuffer(dec->buffer[KIT_DEC_OUT]); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); + if(SDL_LockMutex(dec->output_lock) == 0) { + ret = Kit_PeekBuffer(dec->buffer[KIT_DEC_BUF_OUT]); + SDL_UnlockMutex(dec->output_lock); } return ret; } @@ -204,26 +239,26 @@ void* Kit_PeekDecoderOutput(Kit_Decoder *dec) { void* Kit_ReadDecoderOutput(Kit_Decoder *dec) { assert(dec != NULL); void *ret = NULL; - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - ret = Kit_ReadBuffer(dec->buffer[KIT_DEC_OUT]); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); + if(SDL_LockMutex(dec->output_lock) == 0) { + ret = Kit_ReadBuffer(dec->buffer[KIT_DEC_BUF_OUT]); + SDL_UnlockMutex(dec->output_lock); } return ret; } void Kit_ForEachDecoderOutput(Kit_Decoder *dec, Kit_ForEachItemCallback cb, void *userdata) { assert(dec != NULL); - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - Kit_ForEachItemInBuffer(dec->buffer[KIT_DEC_OUT], cb, userdata); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); + if(SDL_LockMutex(dec->output_lock) == 0) { + Kit_ForEachItemInBuffer(dec->buffer[KIT_DEC_BUF_OUT], cb, userdata); + SDL_UnlockMutex(dec->output_lock); } } void Kit_AdvanceDecoderOutput(Kit_Decoder *dec) { assert(dec != NULL); - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - Kit_AdvanceBuffer(dec->buffer[KIT_DEC_OUT]); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); + if(SDL_LockMutex(dec->output_lock) == 0) { + Kit_AdvanceBuffer(dec->buffer[KIT_DEC_BUF_OUT]); + SDL_UnlockMutex(dec->output_lock); } } @@ -235,52 +270,9 @@ void Kit_ClearDecoderBuffers(Kit_Decoder *dec) { } int Kit_LockDecoderOutput(Kit_Decoder *dec) { - return SDL_LockMutex(dec->lock[KIT_DEC_OUT]); + return SDL_LockMutex(dec->output_lock); } void Kit_UnlockDecoderOutput(Kit_Decoder *dec) { - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); -} - -int Kit_RunDecoder(Kit_Decoder *dec) { - if(dec == NULL) return 0; - - AVPacket *in_packet; - int is_output_full = 1; - - // First, check if there is room in output buffer - if(SDL_LockMutex(dec->lock[KIT_DEC_OUT]) == 0) { - is_output_full = Kit_IsBufferFull(dec->buffer[KIT_DEC_OUT]); - SDL_UnlockMutex(dec->lock[KIT_DEC_OUT]); - } - if(is_output_full) { - return 0; - } - - // Then, see if we have incoming data - in_packet = Kit_ReadDecoderInput(dec); - if(in_packet == NULL) { - return 0; - } - - // Run decoder with incoming packet - dec->dec_decode(dec, in_packet); - - // Free raw packet before returning - av_packet_free(&in_packet); - return 1; -} - -void Kit_CloseDecoder(Kit_Decoder *dec) { - if(dec == NULL) return; - if(dec->dec_close) { - dec->dec_close(dec); - } - for(int i = 0; i < 2; i++) { - SDL_DestroyMutex(dec->lock[i]); - Kit_DestroyBuffer(dec->buffer[i]); - } - avcodec_close(dec->codec_ctx); - avcodec_free_context(&dec->codec_ctx); - free(dec); + SDL_UnlockMutex(dec->output_lock); } -- cgit v1.2.3