diff options
Diffstat (limited to 'libmpdemux')
-rw-r--r-- | libmpdemux/demux_lavf.c | 37 | ||||
-rw-r--r-- | libmpdemux/demux_mkv.c | 107 | ||||
-rw-r--r-- | libmpdemux/demux_ty.c | 4 | ||||
-rw-r--r-- | libmpdemux/demuxer.c | 14 | ||||
-rw-r--r-- | libmpdemux/ebml.h | 6 | ||||
-rw-r--r-- | libmpdemux/matroska.h | 2 | ||||
-rw-r--r-- | libmpdemux/video.c | 4 |
7 files changed, 72 insertions, 102 deletions
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c index 6a32240ebd..3aca4b603c 100644 --- a/libmpdemux/demux_lavf.c +++ b/libmpdemux/demux_lavf.c @@ -357,12 +357,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) { if (st->disposition & AV_DISPOSITION_DEFAULT) sh_audio->default_track = 1; if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V); - // select the first audio stream - if (!demuxer->audio->sh) { - demuxer->audio->id = i; - demuxer->audio->sh= demuxer->a_streams[i]; - } else - st->discard= AVDISCARD_ALL; + st->discard= AVDISCARD_ALL; stream_id = priv->audio_streams++; break; } @@ -428,7 +423,8 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) { int biClrUsed; int biClrImportant; */ - if(demuxer->video->id != i && demuxer->video->id != -1) + if(demuxer->video->id != priv->video_streams + && demuxer->video->id != -1) st->discard= AVDISCARD_ALL; else{ demuxer->video->id = i; @@ -610,8 +606,7 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams); mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD); - if(!priv->audio_streams) demuxer->audio->id=-2; // nosound -// else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio; + demuxer->audio->id = -2; // wait for higher-level code to select track if(!priv->video_streams){ if(!priv->audio_streams){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n"); @@ -620,6 +615,9 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ demuxer->video->id=-2; // audio-only } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video; + // disabled because unreliable per-stream bitrate values returned + // by libavformat trigger this heuristic incorrectly and break things +#if 0 /* libavformat sets bitrate for mpeg based on pts at start and end * of file, which fails for files with pts resets. So calculate our * own bitrate estimate. */ @@ -635,6 +633,7 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ if (!priv->bitrate) priv->bitrate = 1440000; } +#endif demuxer->accurate_seek = !priv->seek_by_bytes; return demuxer; @@ -865,22 +864,18 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg) } } - if(id == -2) { // no sound - i = -1; - } else if(id == -1) { // next track + if (id == -1) { // next track i = (curridx + 2) % (nstreams + 1) - 1; if (i >= 0) newid = pstreams[i]; - } - else // select track by id - { - if (id >= 0 && id < nstreams) { - i = id; - newid = pstreams[i]; - } - } + } else if (id >= 0 && id < nstreams) { // select track by id + i = id; + newid = pstreams[i]; + } else // no sound + i = -1; + if (i == curridx) { - *(int *) arg = curridx; + *(int *) arg = curridx < 0 ? -2 : curridx; return DEMUXER_CTRL_OK; } else { ds_free_packs(ds); diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c index 7432b59d46..ba0eaf4800 100644 --- a/libmpdemux/demux_mkv.c +++ b/libmpdemux/demux_mkv.c @@ -184,6 +184,7 @@ typedef struct mkv_demuxer { int v_skip_to_keyframe, a_skip_to_keyframe; int num_audio_tracks; + int num_video_tracks; } mkv_demuxer_t; #define REALHEADER_SIZE 16 @@ -604,17 +605,17 @@ static void parse_trackentry(struct demuxer *demuxer, || !strcmp(track->codec_id, MKV_A_ACM)) track->ms_compat = 1; else if (!strcmp(track->codec_id, MKV_S_VOBSUB)) - track->subtitle_type = MATROSKA_SUBTYPE_VOBSUB; + track->subtitle_type = 'v'; else if (!strcmp(track->codec_id, MKV_S_TEXTSSA) || !strcmp(track->codec_id, MKV_S_TEXTASS) || !strcmp(track->codec_id, MKV_S_SSA) - || !strcmp(track->codec_id, MKV_S_ASS)) { - track->subtitle_type = MATROSKA_SUBTYPE_SSA; - } else if (!strcmp(track->codec_id, MKV_S_TEXTASCII)) - track->subtitle_type = MATROSKA_SUBTYPE_TEXT; - if (!strcmp(track->codec_id, MKV_S_TEXTUTF8)) { - track->subtitle_type = MATROSKA_SUBTYPE_TEXT; - } + || !strcmp(track->codec_id, MKV_S_ASS)) + track->subtitle_type = 'a'; + else if (!strcmp(track->codec_id, MKV_S_TEXTASCII) + || !strcmp(track->codec_id, MKV_S_TEXTUTF8)) + track->subtitle_type = 't'; + else if (!strcmp(track->codec_id, MKV_S_PGS)) + track->subtitle_type = 'p'; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Codec ID: %s\n", track->codec_id); } else @@ -867,7 +868,7 @@ static int demux_mkv_read_tags(demuxer_t *demuxer) tag.targets.target_chapter_uid || tag.targets.target_attachment_uid) continue; - for (int j; j < tag.n_simple_tag; j++) + for (int j = 0; j < tag.n_simple_tag; j++) demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name, tag.simple_tag[j].tag_string); } @@ -1112,6 +1113,7 @@ static void display_create_tracks(demuxer_t *demuxer) str); } mkv_d->num_audio_tracks = aid; + mkv_d->num_video_tracks = vid; } typedef struct { @@ -1317,6 +1319,8 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track, track->a_formattag = 0x0055; else if (!strncmp(track->codec_id, MKV_A_AC3, strlen(MKV_A_AC3))) track->a_formattag = 0x2000; + else if (!strncmp(track->codec_id, MKV_A_EAC3, strlen(MKV_A_EAC3))) + track->a_formattag = mmioFOURCC('E', 'A', 'C', '3'); else if (!strcmp(track->codec_id, MKV_A_DTS)) track->a_formattag = 0x2001; else if (!strcmp(track->codec_id, MKV_A_PCM) @@ -1390,6 +1394,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track, sh_a->wf->nAvgBytesPerSec = 16000; sh_a->wf->nBlockAlign = 1152; } else if ((track->a_formattag == 0x2000) /* AC3 */ + || track->a_formattag == mmioFOURCC('E', 'A', 'C', '3') || (track->a_formattag == 0x2001)) { /* DTS */ free(sh_a->wf); sh_a->wf = NULL; @@ -1564,16 +1569,12 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track, static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track, int sid) { - if (track->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN) { + if (track->subtitle_type) { int size; uint8_t *buffer; sh_sub_t *sh = new_sh_sub(demuxer, sid); track->sh_sub = sh; - sh->type = 't'; - if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB) - sh->type = 'v'; - if (track->subtitle_type == MATROSKA_SUBTYPE_SSA) - sh->type = 'a'; + sh->type = track->subtitle_type; size = track->private_size; demux_mkv_decode(track, track->private_data, &buffer, &size, 2); if (buffer && buffer != track->private_data) { @@ -1712,34 +1713,7 @@ static int demux_mkv_open(demuxer_t *demuxer) demuxer->video->id = -2; } - /* select audio track */ - track = NULL; - if (track == NULL) - /* search for an audio track that has the 'default' flag set */ - for (i = 0; i < mkv_d->num_tracks; i++) - if (mkv_d->tracks[i]->type == MATROSKA_TRACK_AUDIO - && mkv_d->tracks[i]->default_track) { - track = mkv_d->tracks[i]; - break; - } - - if (track == NULL) - /* no track has the 'default' flag set */ - /* let's take the first audio track */ - for (i = 0; i < mkv_d->num_tracks; i++) - if (mkv_d->tracks[i]->type == MATROSKA_TRACK_AUDIO - && mkv_d->tracks[i]->id >= 0) { - track = mkv_d->tracks[i]; - break; - } - - if (track && demuxer->a_streams[track->id]) { - demuxer->audio->id = track->id; - demuxer->audio->sh = demuxer->a_streams[track->id]; - } else { - mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] No audio track found/wanted.\n"); - demuxer->audio->id = -2; - } + demuxer->audio->id = -2; // wait for higher-level code to select track if (s->end_pos == 0) demuxer->seekable = 0; @@ -1864,26 +1838,6 @@ static int demux_mkv_read_block_lacing(uint8_t *buffer, uint64_t *size, return 1; } -static void handle_subtitles(demuxer_t *demuxer, mkv_track_t *track, - char *block, int64_t size, - uint64_t block_duration, uint64_t timecode) -{ - demux_packet_t *dp; - - if (block_duration == 0) { - mp_msg(MSGT_DEMUX, MSGL_WARN, - "[mkv] Warning: No BlockDuration for subtitle track found.\n"); - return; - } - - sub_utf8 = 1; - dp = new_demux_packet(size); - memcpy(dp->buffer, block, size); - dp->pts = timecode / 1e9; - dp->duration = block_duration / 1e9; - ds_add_packet(demuxer->sub, dp); -} - static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track, uint8_t *buffer, uint32_t size, int64_t block_bref) { @@ -2098,15 +2052,12 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length, } else if (track->type == MATROSKA_TRACK_SUBTITLE && track->id == demuxer->sub->id) { ds = demuxer->sub; - if (track->subtitle_type != MATROSKA_SUBTYPE_VOBSUB) { - uint8_t *buffer; - int size = length; - demux_mkv_decode(track, block, &buffer, &size, 1); - handle_subtitles(demuxer, track, buffer, size, block_duration, tc); - if (buffer != block) - talloc_free(buffer); + if (laces > 1) { + mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Subtitles use Matroska " + "lacing. This is abnormal and not supported.\n"); use_this_block = 0; } + sub_utf8 = 1; // XXX this variable should be eventually removed } else use_this_block = 0; @@ -2139,6 +2090,7 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length, if (i == 0 || track->default_duration) dp->pts = mkv_d->last_pts + i * track->default_duration; + dp->duration = block_duration / 1e9; ds_add_packet(ds, dp); } } @@ -2532,6 +2484,21 @@ static int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg) demuxer->audio->id = new_aid; return DEMUXER_CTRL_OK; + case DEMUXER_CTRL_SWITCH_VIDEO:; + int new_vid = *(int *) arg; + int current_vid = demuxer->video->id; + if (current_vid < 0) + current_vid = -1; + if (new_vid == -1) // cycle to next + new_vid = (current_vid + 2) % (mkv_d->num_video_tracks + 1) - 1; + if (new_vid < 0 || new_vid >= mkv_d->num_video_tracks) + new_vid = -2; + *(int *) arg = new_vid; + if (current_vid != new_vid) + ds_free_packs(demuxer->video); + demuxer->video->id = new_vid; + return DEMUXER_CTRL_OK; + default: return DEMUXER_CTRL_NOTIMPL; } diff --git a/libmpdemux/demux_ty.c b/libmpdemux/demux_ty.c index 4309ad1387..f81ea3d57b 100644 --- a/libmpdemux/demux_ty.c +++ b/libmpdemux/demux_ty.c @@ -41,7 +41,9 @@ #include "libmpcodecs/dec_audio.h" #include "stream/stream.h" #include "demuxer.h" +#ifdef DEMUX_TY_OSD #include "demux_ty_osd.h" +#endif #include "parse_es.h" #include "stheader.h" #include "sub/sub_cc.h" @@ -814,8 +816,10 @@ static void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, float audio_ if( i == 0x1B3 || i == 0x1B8 ) break; // found it! if( !i || !skip_video_packet( d_video ) ) break; // EOF? } +#ifdef DEMUX_TY_OSD if ( subcc_enabled ) ty_ClearOSD( 0 ); +#endif } static int demux_ty_control( demuxer_t *demuxer,int cmd, void *arg ) diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index 07b929b588..9efcf91862 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -1342,11 +1342,15 @@ int demuxer_switch_audio(demuxer_t *demuxer, int index) int demuxer_switch_video(demuxer_t *demuxer, int index) { int res = demux_control(demuxer, DEMUXER_CTRL_SWITCH_VIDEO, &index); - if (res == DEMUXER_CTRL_NOTIMPL) - index = demuxer->video->id; - if (demuxer->video->id >= 0) - demuxer->video->sh = demuxer->v_streams[demuxer->video->id]; - else + if (res == DEMUXER_CTRL_NOTIMPL) { + struct sh_video *sh_video = demuxer->video->sh; + return sh_video ? sh_video->vid : -2; + } + if (demuxer->video->id >= 0) { + struct sh_video *sh_video = demuxer->v_streams[demuxer->video->id]; + demuxer->video->sh = sh_video; + index = sh_video->vid; // internal MPEG demuxers don't set it right + } else demuxer->video->sh = NULL; return index; } diff --git a/libmpdemux/ebml.h b/libmpdemux/ebml.h index 395ffc4df5..866e620c61 100644 --- a/libmpdemux/ebml.h +++ b/libmpdemux/ebml.h @@ -76,12 +76,6 @@ struct ebml_parse_ctx { #define MATROSKA_TRACK_SUBTITLE 0x11 /* text-subtitles */ #define MATROSKA_TRACK_CONTROL 0x20 /* control-codes for menu or other stuff*/ -/* matroska subtitle types */ -#define MATROSKA_SUBTYPE_UNKNOWN 0 -#define MATROSKA_SUBTYPE_TEXT 1 -#define MATROSKA_SUBTYPE_SSA 2 -#define MATROSKA_SUBTYPE_VOBSUB 3 - #ifndef UINT64_MAX #define UINT64_MAX 18446744073709551615ULL #endif diff --git a/libmpdemux/matroska.h b/libmpdemux/matroska.h index 332f934f9c..c233cd1336 100644 --- a/libmpdemux/matroska.h +++ b/libmpdemux/matroska.h @@ -35,6 +35,7 @@ #define MKV_A_AAC "A_AAC" #define MKV_A_AC3 "A_AC3" #define MKV_A_DTS "A_DTS" +#define MKV_A_EAC3 "A_EAC3" #define MKV_A_MP2 "A_MPEG/L2" #define MKV_A_MP3 "A_MPEG/L3" #define MKV_A_PCM "A_PCM/INT/LIT" @@ -77,6 +78,7 @@ #define MKV_S_TEXTSSA "S_TEXT/SSA" #define MKV_S_TEXTASS "S_TEXT/ASS" #define MKV_S_VOBSUB "S_VOBSUB" +#define MKV_S_PGS "S_HDMV/PGS" #define MKV_S_SSA "S_SSA" // Deprecated #define MKV_S_ASS "S_ASS" // Deprecated diff --git a/libmpdemux/video.c b/libmpdemux/video.c index 7000ec5f6d..3244624e77 100644 --- a/libmpdemux/video.c +++ b/libmpdemux/video.c @@ -32,7 +32,9 @@ #include "stream/stream.h" #include "demuxer.h" +#ifdef DEMUX_TY_OSD #include "demux_ty_osd.h" +#endif #include "stheader.h" #include "parse_es.h" #include "mpeg_hdr.h" @@ -414,11 +416,13 @@ static void process_userdata(const unsigned char* buf,int len){ // mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"video.c: process_userdata() detected Closed Captions!\n"); subcc_process_data(buf+2,len-2); } +#ifdef DEMUX_TY_OSD if( len > 2 && buf[ 0 ] == 'T' && buf[ 1 ] == 'Y' ) { ty_processuserdata( buf + 2, len - 2 ); return; } +#endif if(verbose<2) return; fprintf(stderr, "user_data: len=%3d %02X %02X %02X %02X '", len, buf[0], buf[1], buf[2], buf[3]); |