Mercurial > mplayer.hg
comparison libmpdemux/demux_ts.c @ 18688:a109f55ad8d8
support for audio stream switching
author | nicodvb |
---|---|
date | Mon, 12 Jun 2006 23:06:21 +0000 |
parents | 0eaccc94c90c |
children | 8fc996a3b4e1 |
comparison
equal
deleted
inserted
replaced
18687:86020c65b1d5 | 18688:a109f55ad8d8 |
---|---|
53 | 53 |
54 #ifndef SIZE_MAX | 54 #ifndef SIZE_MAX |
55 #define SIZE_MAX ((size_t)-1) | 55 #define SIZE_MAX ((size_t)-1) |
56 #endif | 56 #endif |
57 | 57 |
58 #define TYPE_AUDIO 1 | |
59 #define TYPE_VIDEO 2 | |
60 | |
58 int ts_prog; | 61 int ts_prog; |
59 int ts_keep_broken=0; | 62 int ts_keep_broken=0; |
60 off_t ts_probe = TS_MAX_PROBE_SIZE; | 63 off_t ts_probe = TS_MAX_PROBE_SIZE; |
61 extern char *dvdsub_lang, *audio_lang; //for -alang | 64 extern char *dvdsub_lang, *audio_lang; //for -alang |
62 extern int demux_aid_vid_mismatch; | 65 extern int demux_aid_vid_mismatch; |
103 struct { | 106 struct { |
104 uint8_t au_start, au_end, last_au_end; | 107 uint8_t au_start, au_end, last_au_end; |
105 } sl; | 108 } sl; |
106 } ES_stream_t; | 109 } ES_stream_t; |
107 | 110 |
111 typedef struct { | |
112 void *sh; | |
113 int id; | |
114 int type; | |
115 } sh_av_t; | |
108 | 116 |
109 typedef struct MpegTSContext { | 117 typedef struct MpegTSContext { |
110 int packet_size; // raw packet size, including FEC if present e.g. 188 bytes | 118 int packet_size; // raw packet size, including FEC if present e.g. 188 bytes |
111 ES_stream_t *pids[NB_PID_MAX]; | 119 ES_stream_t *pids[NB_PID_MAX]; |
120 sh_av_t streams[NB_PID_MAX]; | |
112 } MpegTSContext; | 121 } MpegTSContext; |
113 | 122 |
114 | 123 |
115 typedef struct { | 124 typedef struct { |
116 demux_stream_t *ds; | 125 demux_stream_t *ds; |
220 pmt_t *pmt; | 229 pmt_t *pmt; |
221 uint16_t pmt_cnt; | 230 uint16_t pmt_cnt; |
222 uint32_t prog; | 231 uint32_t prog; |
223 uint32_t vbitrate; | 232 uint32_t vbitrate; |
224 int keep_broken; | 233 int keep_broken; |
234 int last_aid; | |
225 char packet[TS_FEC_PACKET_SIZE]; | 235 char packet[TS_FEC_PACKET_SIZE]; |
226 TS_stream_info vstr, astr; | 236 TS_stream_info vstr, astr; |
227 } ts_priv_t; | 237 } ts_priv_t; |
228 | 238 |
229 | 239 |
871 mp_msg(MSGT_DEMUX, MSGL_FATAL, "DEMUX_OPEN_TS, couldn't allocate enough memory for ts->priv, exit\n"); | 881 mp_msg(MSGT_DEMUX, MSGL_FATAL, "DEMUX_OPEN_TS, couldn't allocate enough memory for ts->priv, exit\n"); |
872 return NULL; | 882 return NULL; |
873 } | 883 } |
874 | 884 |
875 for(i=0; i < 8192; i++) | 885 for(i=0; i < 8192; i++) |
886 { | |
876 priv->ts.pids[i] = NULL; | 887 priv->ts.pids[i] = NULL; |
888 priv->ts.streams[i].id = -3; | |
889 } | |
877 priv->pat.progs = NULL; | 890 priv->pat.progs = NULL; |
878 priv->pat.progs_cnt = 0; | 891 priv->pat.progs_cnt = 0; |
879 priv->pat.section.buffer = NULL; | 892 priv->pat.section.buffer = NULL; |
880 priv->pat.section.buffer_len = 0; | 893 priv->pat.section.buffer_len = 0; |
881 | 894 |
916 else | 929 else |
917 memset(params.alang, 0, 4); | 930 memset(params.alang, 0, 4); |
918 | 931 |
919 start_pos = ts_detect_streams(demuxer, ¶ms); | 932 start_pos = ts_detect_streams(demuxer, ¶ms); |
920 | 933 |
921 demuxer->audio->id = params.apid; | |
922 demuxer->video->id = params.vpid; | 934 demuxer->video->id = params.vpid; |
923 demuxer->sub->id = params.spid; | 935 demuxer->sub->id = params.spid; |
924 priv->prog = params.prog; | 936 priv->prog = params.prog; |
925 | 937 |
926 demux_aid_vid_mismatch = 1; // don't identify in new_sh_* since ids don't match | 938 demux_aid_vid_mismatch = 1; // don't identify in new_sh_* since ids don't match |
953 | 965 |
954 if(params.atype != UNKNOWN) | 966 if(params.atype != UNKNOWN) |
955 { | 967 { |
956 ES_stream_t *es = priv->ts.pids[params.apid]; | 968 ES_stream_t *es = priv->ts.pids[params.apid]; |
957 sh_audio = new_sh_audio(demuxer, 0); | 969 sh_audio = new_sh_audio(demuxer, 0); |
970 priv->ts.streams[params.apid].id = 0; | |
971 priv->ts.streams[params.apid].sh = sh_audio; | |
972 priv->ts.streams[params.apid].type = TYPE_AUDIO; | |
973 priv->last_aid = 0; | |
974 demuxer->audio->id = 0; | |
958 sh_audio->ds = demuxer->audio; | 975 sh_audio->ds = demuxer->audio; |
959 sh_audio->format = params.atype; | 976 sh_audio->format = params.atype; |
960 demuxer->audio->sh = sh_audio; | 977 demuxer->audio->sh = sh_audio; |
961 if(es->extradata && es->extradata_len) | 978 if(es->extradata && es->extradata_len) |
962 { | 979 { |
2750 pid_type = pid_type_from_pmt(priv, pid); | 2767 pid_type = pid_type_from_pmt(priv, pid); |
2751 | 2768 |
2752 // PES CONTENT STARTS HERE | 2769 // PES CONTENT STARTS HERE |
2753 if(! probe) | 2770 if(! probe) |
2754 { | 2771 { |
2772 if((IS_AUDIO(tss->type) || IS_AUDIO(tss->subtype)) && is_start && !priv->ts.streams[pid].sh && priv->last_aid+1 < MAX_A_STREAMS) | |
2773 { | |
2774 sh_audio_t *sh = new_sh_audio(demuxer, priv->last_aid+1); | |
2775 if(sh) | |
2776 { | |
2777 sh->format = IS_AUDIO(tss->type) ? tss->type : tss->subtype; | |
2778 sh->ds = demuxer->audio; | |
2779 | |
2780 priv->last_aid++; | |
2781 priv->ts.streams[pid].id = priv->last_aid; | |
2782 priv->ts.streams[pid].sh = sh; | |
2783 priv->ts.streams[pid].type = TYPE_AUDIO; | |
2784 mp_msg(MSGT_DEMUX, MSGL_V, "\r\nADDED AUDIO PID %d, type: %x stream n. %d\r\n", pid, sh->format, priv->last_aid); | |
2785 } | |
2786 } | |
2787 | |
2755 if((pid == demuxer->sub->id)) //or the lang is right | 2788 if((pid == demuxer->sub->id)) //or the lang is right |
2756 { | 2789 { |
2757 pid_type = SPU_DVD; | 2790 pid_type = SPU_DVD; |
2758 } | 2791 } |
2759 | 2792 |
2764 dp = &priv->fifo[1].pack; | 2797 dp = &priv->fifo[1].pack; |
2765 dp_offset = &priv->fifo[1].offset; | 2798 dp_offset = &priv->fifo[1].offset; |
2766 buffer_size = &priv->fifo[1].buffer_size; | 2799 buffer_size = &priv->fifo[1].buffer_size; |
2767 si = &priv->vstr; | 2800 si = &priv->vstr; |
2768 } | 2801 } |
2769 else if(is_audio && (demuxer->audio->id == tss->pid)) | 2802 else if(is_audio && (demuxer->audio->id == priv->ts.streams[pid].id)) |
2770 { | 2803 { |
2771 ds = demuxer->audio; | 2804 ds = demuxer->audio; |
2772 | 2805 |
2773 dp = &priv->fifo[0].pack; | 2806 dp = &priv->fifo[0].pack; |
2774 dp_offset = &priv->fifo[0].offset; | 2807 dp_offset = &priv->fifo[0].offset; |
3210 static int ts_check_file_dmx(demuxer_t *demuxer) | 3243 static int ts_check_file_dmx(demuxer_t *demuxer) |
3211 { | 3244 { |
3212 return ts_check_file(demuxer) ? DEMUXER_TYPE_MPEG_TS : 0; | 3245 return ts_check_file(demuxer) ? DEMUXER_TYPE_MPEG_TS : 0; |
3213 } | 3246 } |
3214 | 3247 |
3248 static int demux_ts_control(demuxer_t *demuxer, int cmd, void *arg) | |
3249 { | |
3250 ts_priv_t* priv = (ts_priv_t *)demuxer->priv; | |
3251 | |
3252 switch(cmd) | |
3253 { | |
3254 case DEMUXER_CTRL_SWITCH_AUDIO: | |
3255 { | |
3256 sh_audio_t *sh_audio = demuxer->audio->sh; | |
3257 sh_audio_t *sh_a = NULL; | |
3258 int i, n; | |
3259 if(!sh_audio) | |
3260 return DEMUXER_CTRL_NOTIMPL; | |
3261 | |
3262 n = *((int*)arg); | |
3263 if(n < 0) | |
3264 { | |
3265 for(i = 0; i < 8192; i++) | |
3266 { | |
3267 if(priv->ts.streams[i].id == demuxer->audio->id && priv->ts.streams[i].type == TYPE_AUDIO) | |
3268 break; | |
3269 } | |
3270 | |
3271 while(!sh_a) | |
3272 { | |
3273 i = (i+1) % 8192; | |
3274 if(priv->ts.streams[i].id == demuxer->audio->id) //we made a complete loop | |
3275 break; | |
3276 if(priv->ts.streams[i].type == TYPE_AUDIO) | |
3277 sh_a = (sh_audio_t*)priv->ts.streams[i].sh; | |
3278 } | |
3279 } | |
3280 else if(n <= priv->last_aid) | |
3281 { | |
3282 for(i = 0; i < 8192; i++) | |
3283 { | |
3284 if(priv->ts.streams[i].id == n && priv->ts.streams[i].type == TYPE_AUDIO) | |
3285 { | |
3286 sh_a = (sh_audio_t*)priv->ts.streams[i].sh; | |
3287 break; | |
3288 } | |
3289 } | |
3290 } | |
3291 | |
3292 if(sh_a) | |
3293 { | |
3294 demuxer->audio->id = priv->ts.streams[i].id; | |
3295 demuxer->audio->sh = sh_a; | |
3296 ds_free_packs(demuxer->audio); | |
3297 mp_msg(MSGT_DEMUX, MSGL_V, "\r\ndemux_ts, switched to audio pid %d, id: %d, sh: %p\r\n", i, demuxer->audio->id, sh_a); | |
3298 } | |
3299 | |
3300 *((int*)arg) = demuxer->audio->id; | |
3301 return DEMUXER_CTRL_OK; | |
3302 } | |
3303 | |
3304 | |
3305 default: | |
3306 return DEMUXER_CTRL_NOTIMPL; | |
3307 } | |
3308 } | |
3309 | |
3215 | 3310 |
3216 demuxer_desc_t demuxer_desc_mpeg_ts = { | 3311 demuxer_desc_t demuxer_desc_mpeg_ts = { |
3217 "MPEG-TS demuxer", | 3312 "MPEG-TS demuxer", |
3218 "mpegts", | 3313 "mpegts", |
3219 "TS", | 3314 "TS", |
3224 ts_check_file_dmx, | 3319 ts_check_file_dmx, |
3225 demux_ts_fill_buffer, | 3320 demux_ts_fill_buffer, |
3226 demux_open_ts, | 3321 demux_open_ts, |
3227 demux_close_ts, | 3322 demux_close_ts, |
3228 demux_seek_ts, | 3323 demux_seek_ts, |
3229 NULL | 3324 demux_ts_control |
3230 }; | 3325 }; |