Commits

Francesco Romani committed 7df5459

[fix][threading][deadlock] fix potential deadlock when skipping frame range is outside the source limits.
Example: 100 frames source, skip range like 1-101.

There is something more evil lurking out here.
This basic case goes like there:
1. Video Import detects EOS and ends cleanly
2. Audio Import exits with unknown code (?! still investigating)
3. The encoder loop has 10 Video frames waiting, 1 Audio frames waiting.
4. After the last Audio frame consumed, the encoder tries to do another
loop, not knowing the import thread have finished.
5. It get stuck while retrieving the audio frame.

The actual fix looks pretty straightforward, as per this commit, but
truth is the syncronization machinery we've in place is messy and untidy,
and there is plenty of room for deadlock and nasty stuff like that.
The code in 1.2.x is only slightly better, but at least it has (MUCH)
more room for changes and improvements.

I chose to NOT take a more radical road (and change important bits)
because this is a bugfix release, and (most important) dev resources
are scarcer than ever, but a MUCH more deeper review is needed here.

The whole EOS/stop detection deserves better analysis and a radical
rationalization to really get read of those issues and come out
with a clean, nice, robust solution.

  • Participants
  • Parent commits e992f8e
  • Branches transcode-1_1

Comments (0)

Files changed (4)

File src/decoder.c

 
 int tc_import_video_status(void)
 {
-    return (tc_import_thread_is_active(&video_decdata) || vframe_have_more());
+    return vframe_have_more() || tc_import_thread_is_active(&video_decdata);
 }
 
 int tc_import_audio_status(void)
 {
-    return (tc_import_thread_is_active(&video_decdata) || aframe_have_more());
+    return aframe_have_more() || tc_import_thread_is_active(&audio_decdata);
 }
 
 

File src/encoder.c

 
 static int need_stop(TCEncoderData *encdata)
 {
-    return (!tc_running() || encdata->error_flag);
+    return !tc_running() || !tc_import_status() || encdata->error_flag;
 }
 
 /* ------------------------------------------------------------

File tools/tcstub.c

 pthread_mutex_t vbuffer_xx_fill_lock = PTHREAD_MUTEX_INITIALIZER;
 uint32_t vbuffer_xx_fill_ctr = 0;
 
+int tc_import_status()
+{
+    return 1;
+}
 
 #ifdef TC_FRAMEBUFFER_STUBS
 void vframe_copy(vframe_list_t *dst, const vframe_list_t *src, int copy_data)

File tools/tcstub.h

 int tc_import_video_running(void);
 int tc_import_audio_running(void);
 
+int tc_import_status();
+
 #endif /* TC_STUB_H */
 
 /* vim: sw=4