From: Jaroslav Kysela Date: Mon, 3 Apr 2017 19:10:05 +0000 (+0200) Subject: mpeg2audio: handle the mpeg layer number changes X-Git-Tag: v4.2.1~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c49fdeed05821b496083881d5c7c59ed01fa0e6;p=thirdparty%2Ftvheadend.git mpeg2audio: handle the mpeg layer number changes --- diff --git a/src/api/api_service.c b/src/api/api_service.c index a4d7d2cbd..9ad855126 100644 --- a/src/api/api_service.c +++ b/src/api/api_service.c @@ -83,6 +83,8 @@ api_service_streams_get_one ( elementary_stream_t *es, int use_filter ) htsmsg_add_u32(e, "ancillary_id", es->es_ancillary_id); } else if (SCT_ISAUDIO(es->es_type)) { htsmsg_add_u32(e, "audio_type", es->es_audio_type); + if (es->es_audio_version) + htsmsg_add_u32(e, "audio_version", es->es_audio_version); } else if (SCT_ISVIDEO(es->es_type)) { htsmsg_add_u32(e, "width", es->es_width); htsmsg_add_u32(e, "height", es->es_height); diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 24d70c34e..3dc174b83 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -1009,6 +1009,8 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss) if(SCT_ISAUDIO(ssc->ssc_type)) { htsmsg_add_u32(e, "audio_type", ssc->ssc_audio_type); + if(ssc->ssc_audio_version) + htsmsg_add_u32(e, "audio_version", ssc->ssc_audio_version); if(ssc->ssc_sri) snprintf(sr, sizeof(sr), "%d", sri_to_rate(ssc->ssc_sri)); else diff --git a/src/htsp_server.c b/src/htsp_server.c index ea786f02f..7f66dd8f5 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -4010,6 +4010,8 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) if (SCT_ISAUDIO(ssc->ssc_type)) { htsmsg_add_u32(c, "audio_type", ssc->ssc_audio_type); + if (ssc->ssc_audio_version) + htsmsg_add_u32(c, "audio_version", ssc->ssc_audio_version); if (ssc->ssc_channels) htsmsg_add_u32(c, "channels", ssc->ssc_channels); if (ssc->ssc_sri) diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index bd833ad49..514ab31de 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -1004,19 +1004,21 @@ dvb_cat_callback /* PMT update reason flags */ #define PMT_UPDATE_PCR (1<<0) #define PMT_UPDATE_NEW_STREAM (1<<1) -#define PMT_UPDATE_LANGUAGE (1<<2) -#define PMT_UPDATE_AUDIO_TYPE (1<<3) -#define PMT_UPDATE_FRAME_DURATION (1<<4) -#define PMT_UPDATE_COMPOSITION_ID (1<<5) -#define PMT_UPDATE_ANCILLARY_ID (1<<6) -#define PMT_UPDATE_STREAM_DELETED (1<<7) -#define PMT_UPDATE_NEW_CA_STREAM (1<<8) -#define PMT_UPDATE_NEW_CAID (1<<9) -#define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<10) -#define PMT_UPDATE_PARENT_PID (1<<11) -#define PMT_UPDATE_CAID_DELETED (1<<12) -#define PMT_UPDATE_CAID_PID (1<<13) -#define PMT_REORDERED (1<<14) +#define PMT_UPDATE_STREAM_CHANGE (1<<2) +#define PMT_UPDATE_STREAM_DELETED (1<<3) +#define PMT_UPDATE_LANGUAGE (1<<4) +#define PMT_UPDATE_AUDIO_TYPE (1<<5) +#define PMT_UPDATE_AUDIO_VERSION (1<<6) +#define PMT_UPDATE_FRAME_DURATION (1<<7) +#define PMT_UPDATE_COMPOSITION_ID (1<<8) +#define PMT_UPDATE_ANCILLARY_ID (1<<9) +#define PMT_UPDATE_NEW_CA_STREAM (1<<10) +#define PMT_UPDATE_NEW_CAID (1<<11) +#define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<12) +#define PMT_UPDATE_PARENT_PID (1<<13) +#define PMT_UPDATE_CAID_DELETED (1<<14) +#define PMT_UPDATE_CAID_PID (1<<15) +#define PMT_REORDERED (1<<16) int dvb_pmt_callback @@ -2228,7 +2230,7 @@ psi_parse_pmt int tt_position; int video_stream; const char *lang; - uint8_t audio_type; + uint8_t audio_type, audio_version; mpegts_mux_t *mux = mt->mt_mux; caid_t *c, *cn; @@ -2293,6 +2295,7 @@ psi_parse_pmt tt_position = 1000; lang = NULL; audio_type = 0; + audio_version = 0; video_stream = 0; switch(estype) { @@ -2305,6 +2308,7 @@ psi_parse_pmt case 0x03: case 0x04: hts_stream_type = SCT_MPEG2AUDIO; + audio_version = 2; /* Assume Layer 2 */ break; case 0x06: @@ -2415,7 +2419,11 @@ psi_parse_pmt st = service_stream_create((service_t*)t, pid, hts_stream_type); } - st->es_type = hts_stream_type; + if (st->es_type != hts_stream_type) { + update |= PMT_UPDATE_STREAM_CHANGE; + st->es_type = hts_stream_type; + st->es_audio_version = audio_version; + } st->es_delete_me = 0; @@ -2441,6 +2449,15 @@ psi_parse_pmt if(st->es_audio_type != audio_type) { update |= PMT_UPDATE_AUDIO_TYPE; st->es_audio_type = audio_type; + st->es_audio_version = audio_version; + } + + /* FIXME: it might make sense that PMT info has greater priority */ + /* but we use this field only for MPEG1/2/3 audio which */ + /* is detected in the parser code */ + if(audio_version && !st->es_audio_version) { + update |= PMT_UPDATE_AUDIO_VERSION; + st->es_audio_version = audio_version; } if(composition_id != -1 && st->es_composition_id != composition_id) { @@ -2469,7 +2486,6 @@ psi_parse_pmt } } - if(st->es_delete_me) { service_stream_destroy((service_t*)t, st); update |= PMT_UPDATE_STREAM_DELETED; @@ -2481,16 +2497,19 @@ psi_parse_pmt if(update) { tvhdebug(mt->mt_subsys, "%s: Service \"%s\" PMT (version %d) updated" - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", mt->mt_name, service_nicename((service_t*)t), version, update&PMT_UPDATE_PCR ? ", PCR PID changed":"", update&PMT_UPDATE_NEW_STREAM ? ", New elementary stream":"", + update&PMT_UPDATE_STREAM_CHANGE ? ", Changed elementary stream":"", + update&PMT_UPDATE_STREAM_DELETED ? ", Stream deleted":"", update&PMT_UPDATE_LANGUAGE ? ", Language changed":"", + update&PMT_UPDATE_AUDIO_TYPE ? ", Audio type changed":"", + update&PMT_UPDATE_AUDIO_VERSION ? ", Audio version changed":"", update&PMT_UPDATE_FRAME_DURATION ? ", Frame duration changed":"", update&PMT_UPDATE_COMPOSITION_ID ? ", Composition ID changed":"", update&PMT_UPDATE_ANCILLARY_ID ? ", Ancillary ID changed":"", - update&PMT_UPDATE_STREAM_DELETED ? ", Stream deleted":"", update&PMT_UPDATE_NEW_CA_STREAM ? ", New CA stream":"", update&PMT_UPDATE_NEW_CAID ? ", New CAID":"", update&PMT_UPDATE_CA_PROVIDER_CHANGE? ", CA provider changed":"", @@ -2515,6 +2534,11 @@ psi_parse_pmt if (service_has_audio_or_video((service_t *)t)) dvb_service_autoenable(t, "PAT and PMT"); + /* FIXME: Move pending_restart handling to another place? */ + if (atomic_set(&t->s_pending_restart, 0) && !ret) + tvhdebug(mt->mt_subsys, "%s: Service \"%s\" forced restart", + mt->mt_name, service_nicename((service_t*)t)); + *_update = update; return ret; } diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index e567391e1..736b604c9 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -688,6 +688,11 @@ parse_mpa123(service_t *t, elementary_stream_t *st) default: fsize = 0; } + if (fsize && st->es_audio_version != layer) { + st->es_audio_version = layer; + atomic_set(&t->s_pending_restart, 1); + } + duration = 90000 * 1152 / sr; channels = ((h >> 6) & 3) == 3 ? 1 : 2; dts = st->es_curdts; diff --git a/src/service.c b/src/service.c index 7a760b8c5..6d1fd8d6c 100644 --- a/src/service.c +++ b/src/service.c @@ -1448,7 +1448,6 @@ refresh: descrambler_service_start(t); } - /** * Generate a message containing info about all components */ @@ -1478,6 +1477,7 @@ service_build_stream_start(service_t *t) memcpy(ssc->ssc_lang, st->es_lang, 4); ssc->ssc_audio_type = st->es_audio_type; + ssc->ssc_audio_version = st->es_audio_version; ssc->ssc_composition_id = st->es_composition_id; ssc->ssc_ancillary_id = st->es_ancillary_id; ssc->ssc_pid = st->es_pid; @@ -1977,8 +1977,11 @@ void service_save ( service_t *t, htsmsg_t *m ) if(st->es_lang[0]) htsmsg_add_str(sub, "language", st->es_lang); - if (SCT_ISAUDIO(st->es_type)) + if (SCT_ISAUDIO(st->es_type)) { htsmsg_add_u32(sub, "audio_type", st->es_audio_type); + if (st->es_audio_version) + htsmsg_add_u32(sub, "audio_version", st->es_audio_version); + } if(st->es_type == SCT_CA) { caid_t *c; @@ -2177,6 +2180,8 @@ void service_load ( service_t *t, htsmsg_t *c ) if (SCT_ISAUDIO(type)) { if(!htsmsg_get_u32(c, "audio_type", &u32)) st->es_audio_type = u32; + if(!htsmsg_get_u32(c, "audio_version", &u32)) + st->es_audio_version = u32; } if(!htsmsg_get_u32(c, "position", &u32)) diff --git a/src/service.h b/src/service.h index 9a5c13fe7..daba9b43d 100644 --- a/src/service.h +++ b/src/service.h @@ -70,6 +70,7 @@ typedef struct elementary_stream { char es_lang[4]; /* ISO 639 2B 3-letter language code */ uint8_t es_audio_type; /* Audio type */ + uint8_t es_audio_version; /* Audio version/layer */ uint16_t es_composition_id; uint16_t es_ancillary_id; @@ -441,6 +442,7 @@ typedef struct service { */ int s_streaming_live; int s_running; + int s_pending_restart; // Live status #define TSS_LIVE 0x01 diff --git a/src/streaming.h b/src/streaming.h index b35647d50..832055c5d 100644 --- a/src/streaming.h +++ b/src/streaming.h @@ -29,6 +29,7 @@ typedef struct streaming_start_component { int ssc_type; char ssc_lang[4]; uint8_t ssc_audio_type; + uint8_t ssc_audio_version; uint16_t ssc_composition_id; uint16_t ssc_ancillary_id; uint16_t ssc_pid;