summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_lavf.c37
-rw-r--r--libmpdemux/demux_mkv.c107
-rw-r--r--libmpdemux/demux_ty.c4
-rw-r--r--libmpdemux/demuxer.c14
-rw-r--r--libmpdemux/ebml.h6
-rw-r--r--libmpdemux/matroska.h2
-rw-r--r--libmpdemux/video.c4
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]);