@@ -615,6 +615,8 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count,
615615 return out_frames;
616616}
617617
618+ int wasapi_stream_reset_default_device (cubeb_stream * stm);
619+
618620/* This helper grabs all the frames available from a capture client, put them in
619621 * linear_input_buffer. linear_input_buffer should be cleared before the
620622 * callback exits. This helper does not work with exclusive mode streams. */
@@ -637,6 +639,13 @@ bool get_input_buffer(cubeb_stream * stm)
637639 for (hr = stm->capture_client ->GetNextPacketSize (&next);
638640 next > 0 ;
639641 hr = stm->capture_client ->GetNextPacketSize (&next)) {
642+ if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
643+ // Application can recover from this error. More info
644+ // https://msdn.microsoft.com/en-us/library/windows/desktop/dd316605(v=vs.85).aspx
645+ LOG (" Device invalidated error, reset default device" );
646+ wasapi_stream_reset_default_device (stm);
647+ return true ;
648+ }
640649
641650 if (FAILED (hr)) {
642651 LOG (" cannot get next packet size: %lx" , hr);
@@ -713,10 +722,19 @@ bool get_output_buffer(cubeb_stream * stm, void *& buffer, size_t & frame_count)
713722 XASSERT (has_output (stm));
714723
715724 hr = stm->output_client ->GetCurrentPadding (&padding_out);
725+ if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
726+ // Application can recover from this error. More info
727+ // https://msdn.microsoft.com/en-us/library/windows/desktop/dd316605(v=vs.85).aspx
728+ LOG (" Device invalidated error, reset default device" );
729+ wasapi_stream_reset_default_device (stm);
730+ return true ;
731+ }
732+
716733 if (FAILED (hr)) {
717734 LOG (" Failed to get padding: %lx" , hr);
718735 return false ;
719736 }
737+
720738 XASSERT (padding_out <= stm->output_buffer_frame_count );
721739
722740 if (stm->draining ) {
@@ -996,11 +1014,21 @@ wasapi_stream_render_loop(LPVOID stream)
9961014 }
9971015 XASSERT (stm->output_client || stm->input_client );
9981016 if (stm->output_client ) {
999- stm->output_client ->Start ();
1017+ hr = stm->output_client ->Start ();
1018+ if (FAILED (hr)) {
1019+ LOG (" Error starting output after reconfigure, error: %lx" , hr);
1020+ is_playing = false ;
1021+ continue ;
1022+ }
10001023 LOG (" Output started after reconfigure." );
10011024 }
10021025 if (stm->input_client ) {
1003- stm->input_client ->Start ();
1026+ hr = stm->input_client ->Start ();
1027+ if (FAILED (hr)) {
1028+ LOG (" Error starting input after reconfiguring, error: %lx" , hr);
1029+ is_playing = false ;
1030+ continue ;
1031+ }
10041032 LOG (" Input started after reconfigure." );
10051033 }
10061034 break ;
@@ -1957,6 +1985,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
19571985
19581986 *stream = stm.release ();
19591987
1988+ LOG (" Stream init succesfull (%p)" , *stream);
19601989 return CUBEB_OK;
19611990}
19621991
@@ -1986,6 +2015,7 @@ void close_wasapi_stream(cubeb_stream * stm)
19862015void wasapi_stream_destroy (cubeb_stream * stm)
19872016{
19882017 XASSERT (stm);
2018+ LOG (" Stream destroy (%p)" , stm);
19892019
19902020 // Only free stm->emergency_bailout if we could join the thread.
19912021 // If we could not join the thread, stm->emergency_bailout is true
0 commit comments