diff options
author | Mike Melanson <mike@multimedia.cx> | 2002-11-18 19:29:46 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2002-11-18 19:29:46 +0000 |
commit | 83af983e30b7fff22cef8d42bd7a0e2682ef23de (patch) | |
tree | 291e19dac17e508a0e189cb8a6ccde1e0d60a3c2 /src | |
parent | 725da24d4ae418cb8a0c9a1cf3960d2278ecec48 (diff) | |
download | xine-lib-83af983e30b7fff22cef8d42bd7a0e2682ef23de.tar.gz xine-lib-83af983e30b7fff22cef8d42bd7a0e2682ef23de.tar.bz2 |
be more diligent at initializing variables; fix QT/PCM audio pop problem
CVS patchset: 3296
CVS date: 2002/11/18 19:29:46
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_qt.c | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index dd61cb60c..9ef23ea88 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -30,7 +30,7 @@ * build_frame_table * free_qt_info * - * $Id: demux_qt.c,v 1.113 2002/11/18 08:20:36 esnel Exp $ + * $Id: demux_qt.c,v 1.114 2002/11/18 19:29:46 tmmm Exp $ * */ @@ -342,31 +342,31 @@ typedef struct { #if DEBUG_ATOM_LOAD #define debug_atom_load printf #else -void debug_atom_load(const char *format, ...) { } +static inline void debug_atom_load(const char *format, ...) { } #endif #if DEBUG_EDIT_LIST #define debug_edit_list printf #else -void debug_edit_list(const char *format, ...) { } +static inline void debug_edit_list(const char *format, ...) { } #endif #if DEBUG_FRAME_TABLE #define debug_frame_table printf #else -void debug_frame_table(const char *format, ...) { } +static inline void debug_frame_table(const char *format, ...) { } #endif #if DEBUG_VIDEO_DEMUX #define debug_video_demux printf #else -void debug_video_demux(const char *format, ...) { } +static inline void debug_video_demux(const char *format, ...) { } #endif #if DEBUG_AUDIO_DEMUX #define debug_audio_demux printf #else -void debug_audio_demux(const char *format, ...) { } +static inline void debug_audio_demux(const char *format, ...) { } #endif void dump_moov_atom(unsigned char *moov_atom, int moov_atom_size) { @@ -477,13 +477,26 @@ qt_info *create_qt_info(void) { info->duration = 0; info->audio_codec = 0; + info->audio_type = 0; info->audio_sample_rate = 0; info->audio_channels = 0; info->audio_bits = 0; + info->audio_vbr = 0; info->audio_decoder_config = NULL; + info->audio_decoder_config_len = 0; info->video_codec = 0; + info->video_type = 0; + info->video_width = 0; + info->video_height = 0; + info->video_depth = 0; info->video_decoder_config = NULL; + info->video_decoder_config_len = 0; + + info->frames = NULL; + info->frame_count = 0; + + info->palette_count = 0; info->copyright = NULL; info->description = NULL; @@ -590,14 +603,28 @@ static qt_error parse_trak_atom(qt_sample_table *sample_table, unsigned char *color_table; /* initialize sample table structure */ + sample_table->edit_list_count = 0; sample_table->edit_list_table = NULL; + sample_table->chunk_offset_count = 0; sample_table->chunk_offset_table = NULL; + sample_table->sample_size = 0; + sample_table->sample_size_count = 0; sample_table->sample_size_table = NULL; + sample_table->sync_sample_table = 0; sample_table->sync_sample_table = NULL; + sample_table->sample_to_chunk_count = 0; sample_table->sample_to_chunk_table = NULL; + sample_table->time_to_sample_count = 0; sample_table->time_to_sample_table = NULL; sample_table->decoder_config = NULL; - sample_table->frames = NULL; + sample_table->decoder_config_len = 0; + + /* special audio parameters */ + sample_table->samples_per_packet = 0; + sample_table->bytes_per_packet = 0; + sample_table->bytes_per_frame = 0; + sample_table->bytes_per_sample = 0; + sample_table->samples_per_frame = 0; /* default type */ sample_table->type = MEDIA_OTHER; @@ -1442,11 +1469,15 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom) { info->comment[string_size - 1] = 0; } } + debug_atom_load(" qt: finished parsing moov atom\n"); /* build frame tables corresponding to each sample table */ info->frame_count = 0; + debug_frame_table(" qt: preparing to build %d frame tables\n", + sample_table_count); for (i = 0; i < sample_table_count; i++) { + debug_frame_table(" qt: building frame table #%d\n", i); build_frame_table(&sample_tables[i], info->timescale); info->frame_count += sample_tables[i].frame_count; @@ -1494,6 +1525,7 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom) { info->audio_sample_size_table = sample_tables[i].sample_size_table; } } + debug_frame_table(" qt: finished building frame tables, merging into one...\n"); /* allocate the master frame index */ info->frames = (qt_frame *)malloc(info->frame_count * sizeof(qt_frame)); @@ -1563,10 +1595,8 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom) { free(sample_tables[i].time_to_sample_table); free(sample_tables[i].sample_to_chunk_table); free(sample_tables[i].sync_sample_table); - free(sample_tables[i].frames); } free(sample_tables); - free(sample_table_indices); } static qt_error open_qt_file(qt_info *info, input_plugin_t *input) { @@ -1596,7 +1626,6 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input) { /* seek to the start of moov atom */ if (input->seek(input, info->moov_first_offset, SEEK_SET) != info->moov_first_offset) { - free(moov_atom); info->last_error = QT_FILE_READ_ERROR; return info->last_error; } @@ -1617,7 +1646,6 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input) { z_state.avail_out = BE_32(&moov_atom[0x24]); unzip_buffer = (unsigned char *)malloc(BE_32(&moov_atom[0x24])); if (!unzip_buffer) { - free(moov_atom); info->last_error = QT_NO_MEMORY; return info->last_error; } @@ -1629,24 +1657,18 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input) { z_ret_code = inflateInit (&z_state); if (Z_OK != z_ret_code) { - free(unzip_buffer); - free(moov_atom); info->last_error = QT_ZLIB_ERROR; return info->last_error; } z_ret_code = inflate(&z_state, Z_NO_FLUSH); if ((z_ret_code != Z_OK) && (z_ret_code != Z_STREAM_END)) { - free(unzip_buffer); - free(moov_atom); info->last_error = QT_ZLIB_ERROR; return info->last_error; } z_ret_code = inflateEnd(&z_state); if (Z_OK != z_ret_code) { - free(unzip_buffer); - free(moov_atom); info->last_error = QT_ZLIB_ERROR; return info->last_error; } @@ -1668,8 +1690,6 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input) { /* take apart the moov atom */ parse_moov_atom(info, moov_atom); - free(moov_atom); - return QT_OK; } @@ -1685,6 +1705,7 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { unsigned int remaining_sample_bytes; int edit_list_compensation = 0; int frame_duration; + int first_buf; i = this->current_frame; @@ -1745,6 +1766,9 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { edit_list_compensation = 0; } + this->stream->stream_info[XINE_STREAM_INFO_FRAME_DURATION] = + frame_duration; + debug_video_demux(" qt: sending off frame %d (video) %d bytes, %lld pts, duration %d\n", i, this->qt->frames[i].size, @@ -1795,13 +1819,32 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { this->qt->frames[i].size, this->qt->frames[i].pts); + first_buf = 1; while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->qt->audio_type; buf->input_pos = this->qt->frames[i].offset - this->data_start; buf->input_length = this->data_size; - buf->input_time = this->qt->frames[i].pts / 90000; - buf->pts = this->qt->frames[i].pts; + /* The audio chunk is often broken up into multiple 8K buffers when + * it is sent to the audio decoder. Only attach the proper timestamp + * to the first buffer. This is for the linear PCM decoder which + * turns around and sends out audio buffers as soon as they are + * received. If 2 or more consecutive audio buffers are dispatched to + * the audio out unit, the engine will compensate with pops. */ + if ((buf->type == BUF_AUDIO_LPCM_BE) || + (buf->type == BUF_AUDIO_LPCM_LE)) { + if (first_buf) { + buf->input_time = this->qt->frames[i].pts / 90000; + buf->pts = this->qt->frames[i].pts; + first_buf = 0; + } else { + buf->input_time = 0; + buf->pts = 0; + } + } else { + buf->input_time = this->qt->frames[i].pts / 90000; + buf->pts = this->qt->frames[i].pts; + } if (remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; |