diff options
-rw-r--r-- | src/demuxers/demux_matroska.c | 94 | ||||
-rw-r--r-- | src/demuxers/matroska.h | 3 |
2 files changed, 63 insertions, 34 deletions
diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c index 76c1f4375..80a690b50 100644 --- a/src/demuxers/demux_matroska.c +++ b/src/demuxers/demux_matroska.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_matroska.c,v 1.14 2004/01/17 01:50:43 tmattern Exp $ + * $Id: demux_matroska.c,v 1.15 2004/01/22 00:41:53 tmattern Exp $ * * demultiplexer for matroska streams * @@ -63,6 +63,7 @@ #define INIT_STD_VIDEO 0 #define INIT_STD_AUDIO 1 #define INIT_VORBIS 2 +#define INIT_SUBTITLE 3 typedef struct { @@ -377,6 +378,7 @@ static void init_codec_vorbis(demux_matroska_t *this, matroska_track_t *track) { } static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track, + int decoder_flags, uint8_t *data, int data_len, int64_t data_pts, int data_duration, off_t input_pos, off_t input_length, @@ -393,7 +395,7 @@ static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track, _x_demux_send_data(track->fifo, data + chunk_tab_size + 1, data_len - chunk_tab_size - 1, - data_pts, track->buf_type, 0, + data_pts, track->buf_type, decoder_flags, input_pos, input_length, input_time, this->duration, 0); @@ -403,7 +405,7 @@ static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track, buf = track->fifo->buffer_pool_alloc(track->fifo); - buf->decoder_flags = BUF_FLAG_SPECIAL | BUF_FLAG_FRAMERATE; + buf->decoder_flags = decoder_flags | BUF_FLAG_SPECIAL | BUF_FLAG_FRAMERATE; buf->decoder_info[0] = data_duration; buf->decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE; buf->decoder_info[2] = chunks; @@ -419,6 +421,7 @@ static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track, } static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track, + int decoder_flags, uint8_t *data, int data_len, int64_t data_pts, int data_duration, off_t input_pos, off_t input_length, @@ -430,6 +433,7 @@ static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track, char last_char = 0; char *dest; int dest_len; + int skip = 0; lprintf ("pts: %lld, duration: %d\n", data_pts, data_duration); /* skip ',' */ @@ -440,23 +444,34 @@ static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track, buf = track->fifo->buffer_pool_alloc(track->fifo); buf->type = track->buf_type; + buf->decoder_flags = decoder_flags; val = (uint32_t *)buf->content; - *val++ = 1; /* number of lines */ - *val++ = 1; /* use time */ *val++ = data_pts / 90; /* start time */ *val++ = (data_pts + data_duration) / 90; /* end time */ - dest = (char *)buf->content + 16; - dest_len = buf->max_size; + dest = buf->content + 8; + dest_len = buf->max_size - 8; while (data_len && dest_len) { - if ((last_char == '\\') && ((*data == 'n') || (*data == 'N'))) { - lines++; - *dest = '\0'; + if (skip) { + if (*data == '}') + skip--; + else if (*data == '{') + skip++; } else { - if (*data != '\\') { - *dest = *data; + if ((last_char == '\\') && ((*data == 'n') || (*data == 'N'))) { + lines++; + *dest = '\n'; dest++; dest_len--; + } else { + if (*data != '\\') { + if (*data == '{') { + skip++; + } else { + *dest = *data; + dest++; dest_len--; + } + } } } @@ -468,10 +483,10 @@ static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track, *dest = '\0'; dest++; dest_len--; buf->size = dest - (char *)buf->content; + buf->extra_info->input_pos = input_pos; + buf->extra_info->input_length = input_length; + buf->extra_info->input_time = input_time; - val = (uint32_t *)buf->content; - *val = lines; - track->fifo->put(track->fifo, buf); } else { buf->free_buffer(buf); @@ -479,6 +494,7 @@ static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track, } static void handle_sub_utf8 (demux_plugin_t *this_gen, matroska_track_t *track, + int decoder_flags, uint8_t *data, int data_len, int64_t data_pts, int data_duration, off_t input_pos, off_t input_length, @@ -489,6 +505,8 @@ static void handle_sub_utf8 (demux_plugin_t *this_gen, matroska_track_t *track, buf = track->fifo->buffer_pool_alloc(track->fifo); buf->size = data_len + 9; /* 2 uint32_t + '\0' */ + buf->decoder_flags = decoder_flags; + if (buf->max_size >= buf->size) { buf->type = track->buf_type; @@ -500,6 +518,9 @@ static void handle_sub_utf8 (demux_plugin_t *this_gen, matroska_track_t *track, buf->content[8 + data_len] = '\0'; lprintf("sub: %s\n", buf->content + 8); + buf->extra_info->input_pos = input_pos; + buf->extra_info->input_length = input_length; + buf->extra_info->input_time = input_time; track->fifo->put(track->fifo, buf); } else { buf->free_buffer(buf); @@ -704,20 +725,24 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { lprintf("MATROSKA_CODEC_ID_S_TEXT_UTF8\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_utf8; + init_mode = INIT_SUBTITLE; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_SSA) || !strcmp(track->codec_id, MATROSKA_CODEC_ID_S_SSA)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_SSA\n"); - track->buf_type = BUF_SPU_TEXT; + track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_ssa; + init_mode = INIT_SUBTITLE; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_ASS) || !strcmp(track->codec_id, MATROSKA_CODEC_ID_S_ASS)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_ASS\n"); - track->buf_type = BUF_SPU_TEXT; + track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_ssa; + init_mode = INIT_SUBTITLE; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_USF)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_USF\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_utf8; + init_mode = INIT_SUBTITLE; } else { lprintf("unknown codec\n"); } @@ -1035,9 +1060,10 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size, if (track->handle_content != NULL) { track->handle_content((demux_plugin_t *)this, track, - data, block_size_left, - pts, xduration, - block_pos, file_len, pts / 90); + decoder_flags, + data, block_size_left, + pts, xduration, + block_pos, file_len, pts / 90); } else { _x_demux_send_data(track->fifo, data, block_size_left, pts, track->buf_type, decoder_flags, @@ -1127,16 +1153,18 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size, } /* send each frame to the decoder */ for (i = 0; i <= lace_num; i++) { - if (track->handle_content != NULL) { - track->handle_content((demux_plugin_t *)this, track, - data, frame[i], pts, - block_pos, file_len, pts / 90, this->duration); - } else { - _x_demux_send_data(track->fifo, data, frame[i], - pts, track->buf_type, decoder_flags, - block_pos, file_len, pts / 90, - 0, 0); - } + if (track->handle_content != NULL) { + track->handle_content((demux_plugin_t *)this, track, + decoder_flags, + data, frame[i], + pts, 0, + block_pos, file_len, pts / 90); + } else { + _x_demux_send_data(track->fifo, data, frame[i], + pts, track->buf_type, decoder_flags, + block_pos, file_len, pts / 90, + this->duration, 0); + } data += frame[i]; pts = 0; } @@ -1671,11 +1699,11 @@ static int demux_matroska_get_optional_data (demux_plugin_t *this_gen, switch (data_type) { case DEMUX_OPTIONAL_DATA_SPULANG: lprintf ("DEMUX_OPTIONAL_DATA_SPULANG channel = %d\n",channel); - if ((channel >= 0) && (channel < this->num_tracks)) { + if ((channel >= 0) && (channel < this->num_sub_tracks)) { for (track_num = 0; track_num < this->num_tracks; track_num++) { matroska_track_t *track = this->tracks[track_num]; - if ((track->buf_type & 0xFF00001F) == BUF_SPU_BASE + channel) { + if ((track->buf_type & 0xFF00001F) == (BUF_SPU_BASE + channel)) { if (track->language) { strncpy (str, track->language, XINE_LANG_MAX); str[XINE_LANG_MAX - 1] = '\0'; @@ -1697,7 +1725,7 @@ static int demux_matroska_get_optional_data (demux_plugin_t *this_gen, for (track_num = 0; track_num < this->num_tracks; track_num++) { matroska_track_t *track = this->tracks[track_num]; - if ((track->buf_type & 0xFF00001F) == BUF_AUDIO_BASE + channel) { + if ((track->buf_type & 0xFF00001F) == (BUF_AUDIO_BASE + channel)) { if (track->language) { strncpy (str, track->language, XINE_LANG_MAX); str[XINE_LANG_MAX - 1] = '\0'; diff --git a/src/demuxers/matroska.h b/src/demuxers/matroska.h index 5e94f6150..07b772896 100644 --- a/src/demuxers/matroska.h +++ b/src/demuxers/matroska.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: matroska.h,v 1.4 2004/01/17 01:50:43 tmattern Exp $ + * $Id: matroska.h,v 1.5 2004/01/22 00:41:53 tmattern Exp $ * */ #ifndef MATROSKA_H @@ -221,6 +221,7 @@ struct matroska_track_s { void (*handle_content) (demux_plugin_t *this_gen, matroska_track_t *track, + int decoder_flags, uint8_t *data, int data_len, int64_t data_pts, int data_duration, off_t input_pos, off_t input_length, |