| 
					
				 | 
			
			
				@@ -180,7 +180,7 @@ static inline void free_packets(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	da_free(output->interleaved_packets); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline void clear_audio_buffers(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void clear_raw_audio_buffers(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		for (size_t j = 0; j < MAX_AV_PLANES; j++) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -215,14 +215,14 @@ void obs_output_destroy(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						  output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				obs_encoder_remove_output( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					output->audio_encoders[i], output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		clear_audio_buffers(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		clear_raw_audio_buffers(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		os_event_destroy(output->stopping_event); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		pthread_mutex_destroy(&output->pause.mutex); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -572,16 +572,16 @@ static inline bool pause_can_stop(struct pause_data *pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static bool obs_encoded_output_pause(obs_output_t *output, bool pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	obs_encoder_t *venc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	obs_encoder_t *aenc[MAX_AUDIO_MIXES]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	obs_encoder_t *aenc[MAX_OUTPUT_AUDIO_ENCODERS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	uint64_t closest_v_ts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	bool success = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	venc = output->video_encoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		aenc[i] = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	pthread_mutex_lock(&venc->pause.mutex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (aenc[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			pthread_mutex_lock(&aenc[i]->pause.mutex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -595,7 +595,7 @@ static bool obs_encoded_output_pause(obs_output_t *output, bool pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (!pause_can_start(&venc->pause)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			goto fail; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (aenc[i] && !pause_can_start(&aenc[i]->pause)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				goto fail; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -604,7 +604,7 @@ static bool obs_encoded_output_pause(obs_output_t *output, bool pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		os_atomic_set_bool(&venc->paused, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		venc->pause.ts_start = closest_v_ts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (aenc[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				os_atomic_set_bool(&aenc[i]->paused, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				aenc[i]->pause.ts_start = closest_v_ts; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -614,7 +614,7 @@ static bool obs_encoded_output_pause(obs_output_t *output, bool pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (!pause_can_stop(&venc->pause)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			goto fail; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (aenc[i] && !pause_can_stop(&aenc[i]->pause)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				goto fail; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -623,7 +623,7 @@ static bool obs_encoded_output_pause(obs_output_t *output, bool pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		os_atomic_set_bool(&venc->paused, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		end_pause(&venc->pause, closest_v_ts); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (aenc[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				os_atomic_set_bool(&aenc[i]->paused, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				end_pause(&aenc[i]->pause, closest_v_ts); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -636,7 +636,7 @@ static bool obs_encoded_output_pause(obs_output_t *output, bool pause) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	success = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 fail: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = MAX_AUDIO_MIXES; i > 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = MAX_OUTPUT_AUDIO_ENCODERS; i > 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (aenc[i - 1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			pthread_mutex_unlock(&aenc[i - 1]->pause.mutex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -801,8 +801,9 @@ void obs_output_remove_encoder_internal(struct obs_output *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (output->video_encoder == encoder) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		output->video_encoder = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (output->audio_encoders[i] == encoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			obs_encoder_t *audio = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (audio == encoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				output->audio_encoders[i] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -870,7 +871,7 @@ void obs_output_set_audio_encoder(obs_output_t *output, obs_encoder_t *encoder, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if ((output->info.flags & OBS_OUTPUT_MULTI_TRACK) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (idx >= MAX_AUDIO_MIXES) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (idx >= MAX_OUTPUT_AUDIO_ENCODERS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -900,15 +901,8 @@ obs_encoder_t *obs_output_get_audio_encoder(const obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!obs_output_valid(output, "obs_output_get_audio_encoder")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if ((output->info.flags & OBS_OUTPUT_MULTI_TRACK) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (idx >= MAX_AUDIO_MIXES) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (idx > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (idx >= MAX_OUTPUT_AUDIO_ENCODERS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return output->audio_encoders[idx]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1054,42 +1048,18 @@ void obs_output_set_audio_conversion( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	output->audio_conversion_set = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline size_t num_audio_mixes(const struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t mix_count = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if ((output->info.flags & OBS_OUTPUT_MULTI_TRACK) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		mix_count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!output->audio_encoders[i]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			mix_count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return mix_count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline bool audio_valid(const struct obs_output *output, bool encoded) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (encoded) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		size_t mix_count = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (!mix_count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < mix_count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (!output->audio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return output->audio != NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static bool can_begin_data_capture(const struct obs_output *output, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1166,10 +1136,10 @@ get_audio_conversion(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static size_t get_track_index(const struct obs_output *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			      struct encoder_packet *pkt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct obs_encoder *encoder = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (pkt->encoder == encoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (encoder && pkt->encoder == encoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1420,7 +1390,6 @@ static size_t get_interleaved_start_idx(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static int prune_premature_packets(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t audio_mixes = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	struct encoder_packet *video; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int video_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int max_idx; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1438,10 +1407,13 @@ static int prune_premature_packets(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	video = &output->interleaved_packets.array[video_idx]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	duration_usec = video->timebase_num * 1000000LL / video->timebase_den; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < audio_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct encoder_packet *audio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		int audio_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (!output->audio_encoders[i]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		audio_idx = find_first_packet_type_idx(output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						       OBS_ENCODER_AUDIO, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (audio_idx == -1) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1565,18 +1537,20 @@ find_last_packet_type(struct obs_output *output, enum obs_encoder_type type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static bool get_audio_and_video_packets(struct obs_output *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					struct encoder_packet **video, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					struct encoder_packet **audio, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					size_t audio_mixes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					struct encoder_packet **audio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	*video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!*video) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		output->received_video = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < audio_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		audio[i] = find_first_packet_type(output, OBS_ENCODER_AUDIO, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (!audio[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			output->received_audio = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			audio[i] = find_first_packet_type(output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							  OBS_ENCODER_AUDIO, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (!audio[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				output->received_audio = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1587,26 +1561,50 @@ static bool get_audio_and_video_packets(struct obs_output *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static bool get_first_audio_encoder_index(const struct obs_output *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					  size_t *index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			*index = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static bool initialize_interleaved_packets(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	struct encoder_packet *video; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	struct encoder_packet *audio[MAX_AUDIO_MIXES]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	struct encoder_packet *last_audio[MAX_AUDIO_MIXES]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t audio_mixes = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct encoder_packet *audio[MAX_OUTPUT_AUDIO_ENCODERS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct encoder_packet *last_audio[MAX_OUTPUT_AUDIO_ENCODERS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	size_t start_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size_t first_audio_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!get_audio_and_video_packets(output, &video, audio, audio_mixes)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!get_first_audio_encoder_index(output, &first_audio_idx)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < audio_mixes; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		last_audio[i] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			find_last_packet_type(output, OBS_ENCODER_AUDIO, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!get_audio_and_video_packets(output, &video, audio)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			last_audio[i] = find_last_packet_type( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				output, OBS_ENCODER_AUDIO, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/* ensure that there is audio past the first video packet */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < audio_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (last_audio[i]->dts_usec < video->dts_usec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			output->received_audio = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (last_audio[i]->dts_usec < video->dts_usec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				output->received_audio = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1614,19 +1612,20 @@ static bool initialize_interleaved_packets(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	start_idx = get_interleaved_start_idx(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (start_idx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		discard_to_idx(output, start_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (!get_audio_and_video_packets(output, &video, audio, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						 audio_mixes)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (!get_audio_and_video_packets(output, &video, audio)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/* get new offsets */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	output->video_offset = video->pts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < audio_mixes; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		output->audio_offsets[i] = audio[i]->dts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			output->audio_offsets[i] = audio[i]->dts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #if DEBUG_STARTING_PACKETS == 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int64_t v = video->dts_usec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	int64_t a = audio[0]->dts_usec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int64_t a = audio[first_audio_idx]->dts_usec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int64_t diff = v - a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	blog(LOG_DEBUG, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1636,7 +1635,7 @@ static bool initialize_interleaved_packets(struct obs_output *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/* subtract offsets from highest TS offset variables */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	output->highest_audio_ts -= audio[0]->dts_usec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	output->highest_audio_ts -= audio[first_audio_idx]->dts_usec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	output->highest_video_ts -= video->dts_usec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/* apply new offsets to all existing packet DTS/PTS values */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1885,11 +1884,11 @@ static void default_raw_audio_callback(void *param, size_t mix_idx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline void start_audio_encoders(struct obs_output *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					encoded_callback_t encoded_callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t num_mixes = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < num_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		obs_encoder_start(output->audio_encoders[i], encoded_callback, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				  output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (output->audio_encoders[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			obs_encoder_start(output->audio_encoders[i], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					  encoded_callback, output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1919,7 +1918,7 @@ static void reset_packet_data(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	output->highest_video_ts = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	output->video_offset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		output->audio_offsets[i] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	free_packets(output); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2049,14 +2048,14 @@ bool obs_output_can_begin_data_capture(const obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				      has_service); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline bool initialize_audio_encoders(obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					     size_t num_mixes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline bool initialize_audio_encoders(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < num_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (!obs_encoder_initialize(output->audio_encoders[i])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		obs_encoder_t *audio = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (audio && !obs_encoder_initialize(audio)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			obs_output_set_last_error( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				output, obs_encoder_get_last_error( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						output->audio_encoders[i])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				output, obs_encoder_get_last_error(audio)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2064,10 +2063,9 @@ static inline bool initialize_audio_encoders(obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline obs_encoder_t *find_inactive_audio_encoder(obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							 size_t num_mixes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline obs_encoder_t *find_inactive_audio_encoder(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < num_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct obs_encoder *audio = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (audio && !audio->active && !audio->paired_encoder) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2077,11 +2075,10 @@ static inline obs_encoder_t *find_inactive_audio_encoder(obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline void pair_encoders(obs_output_t *output, size_t num_mixes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void pair_encoders(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	struct obs_encoder *video = output->video_encoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	struct obs_encoder *audio = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		find_inactive_audio_encoder(output, num_mixes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct obs_encoder *audio = find_inactive_audio_encoder(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (video && audio) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		pthread_mutex_lock(&audio->init_mutex); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2103,7 +2100,6 @@ static inline void pair_encoders(obs_output_t *output, size_t num_mixes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	bool encoded, has_video, has_audio, has_service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t num_mixes = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!obs_output_valid(output, "obs_output_initialize_encoders")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2122,7 +2118,7 @@ bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			obs_encoder_get_last_error(output->video_encoder)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (has_audio && !initialize_audio_encoders(output, num_mixes)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (has_audio && !initialize_audio_encoders(output)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2150,7 +2146,7 @@ static bool begin_delayed_capture(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void reset_raw_output(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	clear_audio_buffers(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clear_raw_audio_buffers(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (output->audio) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const struct audio_output_info *aoi = 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2187,7 +2183,6 @@ static void reset_raw_output(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	bool encoded, has_video, has_audio, has_service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t num_mixes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!obs_output_valid(output, "obs_output_begin_data_capture")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2210,9 +2205,8 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				    has_service)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	num_mixes = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (has_video && has_audio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		pair_encoders(output, num_mixes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pair_encoders(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	os_atomic_set_bool(&output->data_active, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	hook_data_capture(output, encoded, has_video, has_audio); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2240,11 +2234,10 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline void stop_audio_encoders(obs_output_t *output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				       encoded_callback_t encoded_callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	size_t num_mixes = num_audio_mixes(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (size_t i = 0; i < num_mixes; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		obs_encoder_stop(output->audio_encoders[i], encoded_callback, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				 output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		obs_encoder_t *audio = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (audio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			obs_encoder_stop(audio, encoded_callback, output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2650,7 +2643,7 @@ const char *obs_output_get_last_error(obs_output_t *output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return vencoder->last_error_message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			obs_encoder_t *aencoder = output->audio_encoders[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (aencoder && aencoder->last_error_message) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				return aencoder->last_error_message; 
			 |