[xiph-commits] r2999 - liboggplay/trunk/plugin
tahn at svn.annodex.net
tahn at svn.annodex.net
Tue Jun 19 01:53:43 PDT 2007
Author: tahn
Date: 2007-06-19 01:53:43 -0700 (Tue, 19 Jun 2007)
New Revision: 2999
Modified:
liboggplay/trunk/plugin/plugin_gui_mac.c
Log:
Reworked audio processing in the display loop to handle "patchy" audio tracks.
Modified: liboggplay/trunk/plugin/plugin_gui_mac.c
===================================================================
--- liboggplay/trunk/plugin/plugin_gui_mac.c 2007-06-19 07:45:16 UTC (rev 2998)
+++ liboggplay/trunk/plugin/plugin_gui_mac.c 2007-06-19 08:53:43 UTC (rev 2999)
@@ -378,11 +378,11 @@
}
/*
- * Swap the media source on the fly. Shut down and restart the audio to
- * (a) flush the audio buffer, and (b) handle changes in the audio data
- * format. If we're currently paused, temporarily unpause until the first
- * frame of data is retrieved and displayed so the user will get some
- * feedback that the movie has actually been changed.
+ * Swap the media source on the fly. Shut down the audio to (a) flush the
+ * audio buffer and (b) handle changes in the audio data format. If we're
+ * currently paused, temporarily unpause until the first frame of video
+ * data is retrieved and displayed so the user will get some feedback
+ * that the movie has actually been changed.
*/
if (info->new_oggplay_handle != NULL) {
SEM_WAIT(info->oggplay_replace_sem);
@@ -425,8 +425,8 @@
}
/*
- * Spin until we have some data (but wait for a bit first so we don't
- * chew too many cycles).
+ * Spin until we have some video or audio data (but wait for a bit first
+ * so we don't chew too many cycles).
*/
bool have_video = (td.frame_data.video_data != NULL);
bool have_audio = (td.frame_data.samples != NULL && td.frame_data.size > 0);
@@ -474,46 +474,40 @@
}
/*
- * Start up the audio output unit as soon as we have some data to play
- * with. If the media source stops supplying audio, we shouldn't keep
- * the audio unit open.
+ * Process the audio data. We only start the audio output unit once
+ * we have some audio data, because only then do we know the sample
+ * rate and number of channels. Once started, we keep the audio unit going
+ * even if there's no audio data for a given frame, because some input
+ * files have "patchy" audio tracks -- they provide large chunks of audio
+ * every few video frames, with nothing in between.
*/
- if (have_audio && td.audio_handle == NULL) {
- init_audio(info, &td);
- } else if (!have_audio && td.audio_handle != NULL) {
- shutdown_audio(info, &td);
- playback_target = 0;
- }
-
- /*
- * If we have some audio data, send it to the output device and calculate
- * our current playing time using the number of audio bytes consumed.
- */
- cur_time = -1;
- if (have_audio && td.audio_handle != NULL) {
- if (
- sa_stream_write(td.audio_handle, td.frame_data.samples, td.frame_data.size) == SA_SUCCESS
- &&
- sa_stream_get_position(td.audio_handle, SA_POSITION_WRITE_SOFTWARE, &bytes) == SA_SUCCESS
- ) {
- cur_time = bytes * 1000 / get_audio_rate(info->oggplay_handle) /
- (sizeof(short) * get_audio_channels(info->oggplay_handle));
- } else {
- /*
- * Something's gone wrong with the audio; revert to using the system
- * clock for controlling our playback time.
- */
- shutdown_audio(info, &td);
- playback_target = 0;
+ if (have_audio) {
+ if (td.audio_handle == NULL) {
+ init_audio(info, &td);
}
+ if (td.audio_handle != NULL) {
+ if (sa_stream_write(td.audio_handle, td.frame_data.samples,
+ td.frame_data.size) != SA_SUCCESS) {
+ /*
+ * Something's gone wrong with the audio; revert to using the
+ * system clock for controlling our playback time.
+ */
+ shutdown_audio(info, &td);
+ playback_target = 0;
+ }
+ }
}
/*
- * If we can't use the audio device to determine our playback time, track
- * it with the system clock. Use the time at which the first frame is
- * displayed as a reference.
+ * Calculate our current playback time using the number of audio bytes
+ * consumed. If we can't do that, track it with the system clock, using
+ * the time at which the first frame is displayed as a reference.
*/
- if (cur_time == -1) {
+ if (td.audio_handle != NULL) {
+ sa_stream_get_position(td.audio_handle, SA_POSITION_WRITE_SOFTWARE, &bytes);
+ cur_time = bytes * 1000 / get_audio_rate(info->oggplay_handle) /
+ (sizeof(short) * get_audio_channels(info->oggplay_handle));
+ } else {
if (playback_target == 0) {
time_ref = oggplay_sys_time_in_ms();
}
@@ -532,7 +526,8 @@
offset = playback_target - cur_time;
drop_video_frame = (offset < 0);
#ifdef TIMING_TRACE
- printf("\npt %6lld ct %6lld off %6lld %s",
+ printf("\nv %d a %6d pt %6lld ct %6lld off %4lld %s",
+ td.frame_data.frame != NULL, td.frame_data.size,
playback_target, cur_time, offset, drop_video_frame ? "*" : "");
#endif
if (drop_video_frame) {
More information about the commits
mailing list