diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fc0ea22..6a0dd55 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -60,6 +60,7 @@ typedef struct MpegTSService {
     int pcr_packet_count;
     int pcr_packet_period;
     AVProgram *program;
+    AVStream *pcr_st;
 } MpegTSService;
 
 // service_type values as defined in ETSI 300 468
@@ -774,7 +775,7 @@ static int mpegts_init(AVFormatContext *s)
     MpegTSWrite *ts = s->priv_data;
     MpegTSWriteStream *ts_st;
     MpegTSService *service;
-    AVStream *st, *pcr_st = NULL;
+    AVStream *st;
     AVDictionaryEntry *title, *provider;
     int i, j;
     const char *service_name;
@@ -831,6 +832,11 @@ static int mpegts_init(AVFormatContext *s)
         }
     }
 
+    for (i = 0; i < ts->nb_services; i++) {
+        service = ts->services[i];
+        service->pcr_st = NULL;
+    }
+
     ts->pat.pid          = PAT_PID;
     /* Initialize at 15 so that it wraps and is equal to 0 for the
      * first packet we write. */
@@ -872,17 +878,6 @@ static int mpegts_init(AVFormatContext *s)
             goto fail;
         }
 
-        program = av_find_program_from_stream(s, NULL, i);
-        if (program) {
-            for (j = 0; j < ts->nb_services; j++) {
-                if (ts->services[j]->program == program) {
-                    service = ts->services[j];
-                    break;
-                }
-            }
-        }
-
-        ts_st->service = service;
         /* MPEG pid values < 16 are reserved. Applications which set st->id in
          * this range are assigned a calculated pid. */
         if (st->id < 16) {
@@ -895,11 +890,6 @@ static int mpegts_init(AVFormatContext *s)
             ret = AVERROR(EINVAL);
             goto fail;
         }
-        if (ts_st->pid == service->pmt.pid) {
-            av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
-            ret = AVERROR(EINVAL);
-            goto fail;
-        }
         for (j = 0; j < i; j++) {
             if (pids[j] == ts_st->pid) {
                 av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
@@ -913,12 +903,7 @@ static int mpegts_init(AVFormatContext *s)
         ts_st->first_pts_check = 1;
         ts_st->cc              = 15;
         ts_st->discontinuity   = ts->flags & MPEGTS_FLAG_DISCONT;
-        /* update PCR pid by using the first video stream */
-        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
-            service->pcr_pid == 0x1fff) {
-            service->pcr_pid = ts_st->pid;
-            pcr_st           = st;
-        }
+
         if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
             st->codecpar->extradata_size > 0) {
             AVStream *ast;
@@ -949,50 +934,109 @@ static int mpegts_init(AVFormatContext *s)
         if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
             ts_st->opus_pending_trim_start = st->codecpar->initial_padding * 48000 / st->codecpar->sample_rate;
         }
+
+        /* program service checks */
+        program = av_find_program_from_stream(s, NULL, i);
+        do {
+            for (j = 0; j < ts->nb_services; j++) {
+                if (program) {
+                    /* search for the services corresponding to this program */
+                    if (ts->services[j]->program == program)
+                        service = ts->services[j];
+                    else
+                        continue;
+                }
+
+                ts_st->service = service;
+
+                /* check for PMT pid conflicts */
+                if (ts_st->pid == service->pmt.pid) {
+                    av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+                    ret = AVERROR(EINVAL);
+                    goto fail;
+                }
+
+                /* update PCR pid by using the first video stream */
+                if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+                    service->pcr_pid == 0x1fff) {
+                    service->pcr_pid = ts_st->pid;
+                    service->pcr_st  = st;
+                }
+
+                /* store this stream as a candidate PCR if the service doesn't have any */
+                if (service->pcr_pid == 0x1fff &&
+                    !service->pcr_st) {
+                    service->pcr_st  = st;
+                }
+
+                /* exit when just one single service */
+                if (!program)
+                    break;
+            }
+            program = program ? av_find_program_from_stream(s, program, i) : NULL;
+        } while (program);
     }
 
     av_freep(&pids);
 
-    /* if no video stream, use the first stream as PCR */
-    if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
-        pcr_st           = s->streams[0];
-        ts_st            = pcr_st->priv_data;
-        service->pcr_pid = ts_st->pid;
-    } else
-        ts_st = pcr_st->priv_data;
-
-    if (ts->mux_rate > 1) {
-        service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period /
-                                     (TS_PACKET_SIZE * 8 * 1000);
-        ts->sdt_packet_period      = (int64_t)ts->mux_rate * SDT_RETRANS_TIME /
-                                     (TS_PACKET_SIZE * 8 * 1000);
-        ts->pat_packet_period      = (int64_t)ts->mux_rate * PAT_RETRANS_TIME /
-                                     (TS_PACKET_SIZE * 8 * 1000);
-
-        if (ts->copyts < 1)
-            ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
-    } else {
-        /* Arbitrary values, PAT/PMT will also be written on video key frames */
-        ts->sdt_packet_period = 200;
-        ts->pat_packet_period = 40;
-        if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
-            int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0);
-            if (!frame_size) {
-                av_log(s, AV_LOG_WARNING, "frame size not set\n");
-                service->pcr_packet_period =
-                    pcr_st->codecpar->sample_rate / (10 * 512);
+    for (i = 0; i < ts->nb_services; i++) {
+        service = ts->services[i];
+
+        if (!service->pcr_st) {
+            av_log(s, AV_LOG_ERROR, "no PCR selected for the service %i\n", service->sid);
+            ret = AVERROR(EINVAL);
+            goto fail_at_end;
+        }
+        /* get the PCR stream (real or candidate) */
+        ts_st = service->pcr_st->priv_data;
+
+        /* if no video stream then use the pid of the candidate PCR */
+        if (service->pcr_pid == 0x1fff)
+            service->pcr_pid = ts_st->pid;
+
+        if (ts->mux_rate > 1) {
+            service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period /
+                                        (TS_PACKET_SIZE * 8 * 1000);
+            ts->sdt_packet_period      = (int64_t)ts->mux_rate * SDT_RETRANS_TIME /
+                                        (TS_PACKET_SIZE * 8 * 1000);
+            ts->pat_packet_period      = (int64_t)ts->mux_rate * PAT_RETRANS_TIME /
+                                        (TS_PACKET_SIZE * 8 * 1000);
+            if (ts->copyts < 1)
+                ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
+        } else {
+            /* Arbitrary values, PAT/PMT will also be written on video key frames */
+            ts->sdt_packet_period = 200;
+            ts->pat_packet_period = 40;
+            if (service->pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+                int frame_size = av_get_audio_frame_duration2(service->pcr_st->codecpar, 0);
+                if (!frame_size) {
+                    av_log(s, AV_LOG_WARNING, "frame size not set\n");
+                    service->pcr_packet_period =
+                        service->pcr_st->codecpar->sample_rate / (10 * 512);
+                } else {
+                    service->pcr_packet_period =
+                        service->pcr_st->codecpar->sample_rate / (10 * frame_size);
+                }
             } else {
+                // max delta PCR 0.1s
+                // TODO: should be avg_frame_rate
                 service->pcr_packet_period =
-                    pcr_st->codecpar->sample_rate / (10 * frame_size);
+                    ts_st->user_tb.den / (10 * ts_st->user_tb.num);
             }
-        } else {
-            // max delta PCR 0.1s
-            // TODO: should be avg_frame_rate
-            service->pcr_packet_period =
-                ts_st->user_tb.den / (10 * ts_st->user_tb.num);
+            if (!service->pcr_packet_period)
+                service->pcr_packet_period = 1;
         }
-        if (!service->pcr_packet_period)
-            service->pcr_packet_period = 1;
+
+        // output a PCR as soon as possible
+        service->pcr_packet_count = service->pcr_packet_period;
+
+        av_log(s, AV_LOG_VERBOSE, "service %i using PCR in pid=%i\n", service->sid, service->pcr_pid);
+    }
+
+    if (!ts_st->service) {
+        av_log(s, AV_LOG_ERROR, "empty services!\n");
+        ret = AVERROR(EINVAL);
+        goto fail_at_end;
     }
 
     ts->last_pat_ts = AV_NOPTS_VALUE;
@@ -1005,8 +1049,6 @@ static int mpegts_init(AVFormatContext *s)
         ts->sdt_packet_period = INT_MAX;
     }
 
-    // output a PCR as soon as possible
-    service->pcr_packet_count = service->pcr_packet_period;
     ts->pat_packet_count      = ts->pat_packet_period - 1;
     ts->sdt_packet_count      = ts->sdt_packet_period - 1;
 
@@ -1016,7 +1058,7 @@ static int mpegts_init(AVFormatContext *s)
         av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate);
     av_log(s, AV_LOG_VERBOSE,
            "pcr every %d pkts, sdt every %d, pat/pmt every %d pkts\n",
-           service->pcr_packet_period,
+           ts_st->service->pcr_packet_period,
            ts->sdt_packet_period, ts->pat_packet_period);
 
     if (ts->m2ts_mode == -1) {
@@ -1031,6 +1073,7 @@ static int mpegts_init(AVFormatContext *s)
 
 fail:
     av_freep(&pids);
+fail_at_end:
     return ret;
 }
 
