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, &params); 932 start_pos = ts_detect_streams(demuxer, &params);
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 };