version update, color_space/range tweak, lv2 build fixes
[goodguy/cinelerra.git] / cinelerra-5.1 / thirdparty / src / ffmpeg.git.patch2
1 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
2 --- a/libavformat/mpegtsenc.c
3 +++ b/libavformat/mpegtsenc.c
4 @@ -56,7 +56,8 @@ typedef struct MpegTSService {
5      int sid;           /* service ID */
6      uint8_t name[256];
7      uint8_t provider_name[256];
8 -    int pcr_pid;
9 +    int pcr_sid;       /* stream triggering pcr writes */
10 +    int pcr_pid;       /* pid of pcr stream */
11      AVProgram *program;
12  } MpegTSService;
13  
14 @@ -79,10 +80,8 @@ typedef struct MpegTSWrite {
15      int64_t sdt_period; /* SDT period in PCR time base */
16      int64_t pat_period; /* PAT/PMT period in PCR time base */
17      int nb_services;
18 -    int onid;
19 -    int tsid;
20 -    int64_t first_pcr;
21 -    int64_t next_pcr;
22 +    int onid, tsid;
23 +    int64_t pcr, first_pcr, next_pcr, delay;
24      int mux_rate; ///< set to 1 when VBR
25      int pes_payload_size;
26  
27 @@ -94,8 +93,8 @@ typedef struct MpegTSWrite {
28      int pmt_start_pid;
29      int start_pid;
30      int m2ts_mode;
31 +    int64_t ts_offset;
32  
33 -    int pcr_period_ms;
34  #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
35  #define MPEGTS_FLAG_AAC_LATM        0x02
36  #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES           0x04
37 @@ -104,11 +103,11 @@ typedef struct MpegTSWrite {
38      int flags;
39      int copyts;
40      int tables_version;
41 -    int64_t pat_period_us;
42 -    int64_t sdt_period_us;
43 -    int64_t last_pat_ts;
44 +    double pcr_period_ms;
45 +    double sdt_period_ms;
46 +    double pat_period_ms;
47      int64_t last_sdt_ts;
48 -
49 +    int64_t last_pat_ts;
50      int omit_video_pes_length;
51  } MpegTSWrite;
52  
53 @@ -217,10 +216,10 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
54  #define DEFAULT_PROVIDER_NAME   "FFmpeg"
55  #define DEFAULT_SERVICE_NAME    "Service"
56  
57 -/* we retransmit the SI info at this rate */
58 +/* we retransmit the SI info at this rate (ms) */
59  #define SDT_RETRANS_TIME 500
60  #define PAT_RETRANS_TIME 100
61 -#define PCR_RETRANS_TIME 20
62 +#define PCR_RETRANS_TIME 50
63  
64  typedef struct MpegTSWriteStream {
65      int pid; /* stream associated pid */
66 @@ -234,7 +233,7 @@ typedef struct MpegTSWriteStream {
67      int payload_flags;
68      uint8_t *payload;
69      AVFormatContext *amux;
70 -
71 +    MpegTSService *service;
72      int64_t pcr_period; /* PCR period in PCR time base */
73      int64_t last_pcr;
74  
75 @@ -713,18 +712,11 @@ invalid:
76      return 0;
77  }
78  
79 -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
80 -{
81 -    return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
82 -           ts->first_pcr;
83 -}
84 -
85  static void write_packet(AVFormatContext *s, const uint8_t *packet)
86  {
87      MpegTSWrite *ts = s->priv_data;
88      if (ts->m2ts_mode) {
89 -        int64_t pcr = get_pcr(s->priv_data, s->pb);
90 -        uint32_t tp_extra_header = pcr % 0x3fffffff;
91 +        uint32_t tp_extra_header = ts->pcr % 0x3fffffff;
92          tp_extra_header = AV_RB32(&tp_extra_header);
93          avio_write(s->pb, (unsigned char *) &tp_extra_header,
94                     sizeof(tp_extra_header));
95 @@ -763,6 +755,7 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid,
96      service->pmt.pid       = ts->pmt_start_pid + ts->nb_services;
97      service->sid           = sid;
98      service->pcr_pid       = 0x1fff;
99 +    service->pcr_sid       = 0x1fff;
100      if (encode_str8(service->provider_name, provider_name) < 0 ||
101          encode_str8(service->name, service_name) < 0) {
102          av_log(s, AV_LOG_ERROR, "Too long service or provider name\n");
103 @@ -788,30 +781,32 @@ static void enable_pcr_generation_for_stream(AVFormatContext *s, AVStream *pcr_s
104      MpegTSWrite *ts = s->priv_data;
105      MpegTSWriteStream *ts_st = pcr_st->priv_data;
106  
107 -    if (ts->mux_rate > 1 || ts->pcr_period_ms >= 0) {
108 -        int pcr_period_ms = ts->pcr_period_ms == -1 ? PCR_RETRANS_TIME : ts->pcr_period_ms;
109 -        ts_st->pcr_period = av_rescale(pcr_period_ms, PCR_TIME_BASE, 1000);
110 -    } else {
111 +    int64_t pcr_period = -1;
112 +    if (ts->pcr_period_ms >= 0)
113 +        pcr_period = av_rescale(ts->pcr_period_ms, PCR_TIME_BASE, 1000);
114 +    else if (ts->mux_rate == 1) {
115          /* By default, for VBR we select the highest multiple of frame duration which is less than 100 ms. */
116          int64_t frame_period = 0;
117          if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
118              int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0);
119 -            if (!frame_size) {
120 +            if (frame_size > 0)
121 +               frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP);
122 +            else
123                 av_log(s, AV_LOG_WARNING, "frame size not set\n");
124 -               frame_size = 512;
125 -            }
126 -            frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP);
127          } else if (pcr_st->avg_frame_rate.num) {
128              frame_period = av_rescale_rnd(pcr_st->avg_frame_rate.den, PCR_TIME_BASE, pcr_st->avg_frame_rate.num, AV_ROUND_UP);
129          }
130 -        if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10)
131 -            ts_st->pcr_period = frame_period * (PCR_TIME_BASE / 10 / frame_period);
132 -        else
133 -            ts_st->pcr_period = 1;
134 +        if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10) {
135 +            int pcr_frames = (PCR_TIME_BASE / 10) / frame_period;
136 +            if( pcr_frames > 0 )
137 +                pcr_period = frame_period * pcr_frames;
138 +        }
139      }
140 -
141 +    if( pcr_period < 0 ) 
142 +       pcr_period = av_rescale(PCR_RETRANS_TIME, PCR_TIME_BASE, 1000);
143 +    ts_st->pcr_period = pcr_period;
144      // output a PCR as soon as possible
145 -    ts_st->last_pcr   = ts->first_pcr - ts_st->pcr_period;
146 +    ts_st->last_pcr   = ts->first_pcr - pcr_period;
147  }
148  
149  static void select_pcr_streams(AVFormatContext *s)
150 @@ -823,22 +818,32 @@ static void select_pcr_streams(AVFormatContext *s)
151          AVStream *pcr_st = NULL;
152          AVProgram *program = service->program;
153          int nb_streams = program ? program->nb_stream_indexes : s->nb_streams;
154 -
155 +        /* find first video stream, or just use first stream */
156          for (int j = 0; j < nb_streams; j++) {
157              AVStream *st = s->streams[program ? program->stream_index[j] : j];
158 -            if (!pcr_st ||
159 -                pcr_st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
160 -            {
161 +            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
162                  pcr_st = st;
163 +                break;
164              }
165          }
166 -
167 +        if (!pcr_st && s->nb_streams > 0)
168 +            pcr_st = s->streams[0];
169          if (pcr_st) {
170              MpegTSWriteStream *ts_st = pcr_st->priv_data;
171 -            service->pcr_pid = ts_st->pid;
172 +            service->pcr_sid = ts_st->pid;  /* stream id for pcr writes */
173 +            service->pcr_pid = ts->m2ts_mode > 1 ? /* pcr pid */
174 +               0x1000 + ts->service_id : ts_st->pid;
175              enable_pcr_generation_for_stream(s, pcr_st);
176              av_log(s, AV_LOG_VERBOSE, "service %i using PCR in pid=%i, pcr_period=%"PRId64"ms\n",
177                  service->sid, service->pcr_pid, av_rescale(ts_st->pcr_period, 1000, PCR_TIME_BASE));
178 +            for (int j = 0; j < nb_streams; j++) {
179 +                AVStream *st = s->streams[program ? program->stream_index[j] : j];
180 +                MpegTSWriteStream *ts_st = st->priv_data;
181 +                ts_st->service = service;
182 +            }
183 +            if (service->pmt.pid == service->pcr_pid) {
184 +                av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid);
185 +            }
186          }
187      }
188  }
189 @@ -860,6 +865,15 @@ static int mpegts_init(AVFormatContext *s)
190  
191      if (s->max_delay < 0) /* Not set by the caller */
192          s->max_delay = 0;
193 +    ts->delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
194 +
195 +    if (ts->m2ts_mode == -1) {
196 +        if (av_match_ext(s->url, "m2ts")) {
197 +            ts->m2ts_mode = 1;
198 +        } else {
199 +            ts->m2ts_mode = 0;
200 +        }
201 +    }
202  
203      // round up to a whole number of TS packets
204      ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
205 @@ -920,14 +934,11 @@ static int mpegts_init(AVFormatContext *s)
206  
207          /* MPEG pid values < 16 are reserved. Applications which set st->id in
208           * this range are assigned a calculated pid. */
209 -        if (st->id < 16) {
210 -            ts_st->pid = ts->start_pid + i;
211 -        } else {
212 -            ts_st->pid = st->id;
213 -        }
214 -        if (ts_st->pid >= 0x1FFF) {
215 +        ts_st->pid = ts->start_pid >= 0 ?  ts->start_pid + i :
216 +            st->id >= 16 ? st->id : FIRST_OTHER_PID + i;
217 +        if (ts_st->pid < 16 || ts_st->pid >= 0x1FFF) {
218              av_log(s, AV_LOG_ERROR,
219 -                   "Invalid stream id %d, must be less than 8191\n", st->id);
220 +                   "Invalid stream id %d, must be in 16...8191\n", ts_st->pid);
221              ret = AVERROR(EINVAL);
222              goto fail;
223          }
224 @@ -998,8 +1009,8 @@ static int mpegts_init(AVFormatContext *s)
225  
226      ts->last_pat_ts = AV_NOPTS_VALUE;
227      ts->last_sdt_ts = AV_NOPTS_VALUE;
228 -    ts->pat_period = av_rescale(ts->pat_period_us, PCR_TIME_BASE, AV_TIME_BASE);
229 -    ts->sdt_period = av_rescale(ts->sdt_period_us, PCR_TIME_BASE, AV_TIME_BASE);
230 +    ts->pat_period = av_rescale(ts->pat_period_ms, PCR_TIME_BASE, 1000);
231 +    ts->sdt_period = av_rescale(ts->sdt_period_ms, PCR_TIME_BASE, 1000);
232  
233      if (ts->mux_rate == 1)
234          av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");
235 @@ -1022,20 +1033,16 @@ static void retransmit_si_info(AVFormatContext *s, int force_pat, int force_sdt,
236  {
237      MpegTSWrite *ts = s->priv_data;
238      int i;
239 -
240 -    if ((pcr != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
241 -        (pcr != AV_NOPTS_VALUE && pcr - ts->last_sdt_ts >= ts->sdt_period) ||
242 -        force_sdt
243 -    ) {
244 -        if (pcr != AV_NOPTS_VALUE)
245 -            ts->last_sdt_ts = FFMAX(pcr, ts->last_sdt_ts);
246 +    if (force_sdt || (ts->sdt_period >= 0 && pcr != AV_NOPTS_VALUE &&
247 +         (ts->last_sdt_ts == AV_NOPTS_VALUE || (pcr - ts->last_sdt_ts >= ts->sdt_period)) )) {
248 +        if (pcr > ts->last_sdt_ts)
249 +            ts->last_sdt_ts = pcr;
250          mpegts_write_sdt(s);
251      }
252 -    if ((pcr != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
253 -        (pcr != AV_NOPTS_VALUE && pcr - ts->last_pat_ts >= ts->pat_period) ||
254 -        force_pat) {
255 -        if (pcr != AV_NOPTS_VALUE)
256 -            ts->last_pat_ts = FFMAX(pcr, ts->last_pat_ts);
257 +    if (force_pat || (ts->pat_period >= 0 && pcr != AV_NOPTS_VALUE &&
258 +         (ts->last_pat_ts == AV_NOPTS_VALUE || (pcr - ts->last_pat_ts >= ts->pat_period)) )) {
259 +        if (pcr > ts->last_pat_ts)
260 +            ts->last_pat_ts = pcr;
261          mpegts_write_pat(s);
262          for (i = 0; i < ts->nb_services; i++)
263              mpegts_write_pmt(s, ts->services[i]);
264 @@ -1076,13 +1083,14 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
265  {
266      MpegTSWrite *ts = s->priv_data;
267      MpegTSWriteStream *ts_st = st->priv_data;
268 +    uint32_t pcr_pid = ts_st->service->pcr_pid;
269      uint8_t *q;
270      uint8_t buf[TS_PACKET_SIZE];
271  
272      q    = buf;
273      *q++ = 0x47;
274 -    *q++ = ts_st->pid >> 8;
275 -    *q++ = ts_st->pid;
276 +    *q++ = pcr_pid >> 8;
277 +    *q++ = pcr_pid;
278      *q++ = 0x20 | ts_st->cc;   /* Adaptation only */
279      /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
280      *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
281 @@ -1093,7 +1101,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
282      }
283  
284      /* PCR coded into 6 bytes */
285 -    q += write_pcr_bits(q, get_pcr(ts, s->pb));
286 +    q += write_pcr_bits(q, ts->pcr);
287  
288      /* stuffing bytes */
289      memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
290 @@ -1161,7 +1169,6 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
291      uint8_t *q;
292      int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
293      int afc_len, stuffing_len;
294 -    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
295      int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
296      int force_sdt = 0;
297  
298 @@ -1178,67 +1185,46 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
299  
300      is_start = 1;
301      while (payload_size > 0) {
302 -        int64_t pcr = AV_NOPTS_VALUE;
303 -        if (ts->mux_rate > 1)
304 -            pcr = get_pcr(ts, s->pb);
305 -        else if (dts != AV_NOPTS_VALUE)
306 -            pcr = (dts - delay) * 300;
307 +        ts->pcr = ts->first_pcr + (ts->mux_rate == 1 ?
308 +            (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300) :
309 +            // add 11, pcr references the last byte of program clock reference base
310 +            av_rescale(avio_tell(s->pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate));
311  
312 -        retransmit_si_info(s, force_pat, force_sdt, pcr);
313 +        retransmit_si_info(s, force_pat, force_sdt, ts->pcr);
314          force_pat = 0;
315          force_sdt = 0;
316  
317          write_pcr = 0;
318 -        if (ts->mux_rate > 1) {
319 -            /* Send PCR packets for all PCR streams if needed */
320 -            pcr = get_pcr(ts, s->pb);
321 -            if (pcr >= ts->next_pcr) {
322 -                int64_t next_pcr = INT64_MAX;
323 -                for (int i = 0; i < s->nb_streams; i++) {
324 -                    /* Make the current stream the last, because for that we
325 -                     * can insert the pcr into the payload later */
326 -                    int st2_index = i < st->index ? i : (i + 1 == s->nb_streams ? st->index : i + 1);
327 -                    AVStream *st2 = s->streams[st2_index];
328 -                    MpegTSWriteStream *ts_st2 = st2->priv_data;
329 -                    if (ts_st2->pcr_period) {
330 -                        if (pcr - ts_st2->last_pcr >= ts_st2->pcr_period) {
331 -                            ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period);
332 -                            if (st2 != st) {
333 -                                mpegts_insert_pcr_only(s, st2);
334 -                                pcr = get_pcr(ts, s->pb);
335 -                            } else {
336 -                                write_pcr = 1;
337 -                            }
338 -                        }
339 -                        next_pcr = FFMIN(next_pcr, ts_st2->last_pcr + ts_st2->pcr_period);
340 -                    }
341 -                }
342 -                ts->next_pcr = next_pcr;
343 -            }
344 -            if (dts != AV_NOPTS_VALUE && (dts - pcr / 300) > delay) {
345 -                /* pcr insert gets priority over null packet insert */
346 -                if (write_pcr)
347 -                    mpegts_insert_pcr_only(s, st);
348 -                else
349 -                    mpegts_insert_null_packet(s);
350 -                /* recalculate write_pcr and possibly retransmit si_info */
351 -                continue;
352 -            }
353 -        } else if (ts_st->pcr_period && pcr != AV_NOPTS_VALUE) {
354 -            if (pcr - ts_st->last_pcr >= ts_st->pcr_period && is_start) {
355 -                ts_st->last_pcr = FFMAX(pcr - ts_st->pcr_period, ts_st->last_pcr + ts_st->pcr_period);
356 -                write_pcr = 1;
357 -            }
358 +        if (ts_st->pcr_period > 0 && ts_st->pid == ts_st->service->pcr_sid &&
359 +            ts->pcr - ts_st->last_pcr >= ts_st->pcr_period) {
360 +            ts_st->last_pcr = ts->pcr;
361 +            write_pcr = 1;
362 +        }
363 +        if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) {
364 +            /* pcr is on a seperate stream */
365 +            mpegts_insert_pcr_only(s, st);
366 +            continue;
367 +        }
368 +
369 +        if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
370 +               (dts - ts->pcr / 300) > ts->delay) {
371 +            /* pcr insert gets priority over null packet insert */
372 +            if (write_pcr)
373 +                mpegts_insert_pcr_only(s, st);
374 +            else
375 +                mpegts_insert_null_packet(s);
376 +            /* recalculate write_pcr and possibly retransimit si_info */
377 +            continue;
378          }
379  
380          /* prepare packet header */
381          q    = buf;
382          *q++ = 0x47;
383          val  = ts_st->pid >> 8;
384 -        if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3)
385 -            val |= 0x20;
386          if (is_start)
387              val |= 0x40;
388 +        if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3)
389 +            val |= 0x20;
390          *q++      = val;
391          *q++      = ts_st->pid;
392          ts_st->cc = ts_st->cc + 1 & 0xf;
393 @@ -1250,7 +1236,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
394          }
395          if (key && is_start && pts != AV_NOPTS_VALUE) {
396              // set Random Access for key frames
397 -            if (ts_st->pcr_period)
398 +            if ( ts_st->pcr_period > 0 && ts_st->pid == ts_st->service->pcr_sid )
399                  write_pcr = 1;
400              set_af_flag(buf, 0x40);
401              q = get_ts_payload_start(buf);
402 @@ -1258,10 +1244,9 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
403          if (write_pcr) {
404              set_af_flag(buf, 0x10);
405              q = get_ts_payload_start(buf);
406 -            // add 11, pcr references the last byte of program clock reference base
407 -            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
408 +            if (dts != AV_NOPTS_VALUE && dts < ts->pcr / 300)
409                  av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
410 -            extend_af(buf, write_pcr_bits(q, pcr));
411 +            extend_af(buf, write_pcr_bits(q, ts->pcr));
412              q = get_ts_payload_start(buf);
413          }
414          if (is_start) {
415 @@ -1362,11 +1347,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
416              *q++ = flags;
417              *q++ = header_len;
418              if (pts != AV_NOPTS_VALUE) {
419 -                write_pts(q, flags >> 6, pts);
420 +                int64_t ts_pts = pts + ts->ts_offset;
421 +                write_pts(q, flags >> 6, ts_pts);
422                  q += 5;
423              }
424              if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {
425 -                write_pts(q, 1, dts);
426 +                int64_t ts_dts = dts + ts->ts_offset;
427 +                write_pts(q, 1, ts_dts);
428                  q += 5;
429              }
430              if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {
431 @@ -1536,7 +1523,6 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
432      uint8_t *data = NULL;
433      MpegTSWrite *ts = s->priv_data;
434      MpegTSWriteStream *ts_st = st->priv_data;
435 -    const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2;
436      const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2;
437      int64_t dts = pkt->dts, pts = pkt->pts;
438      int opus_samples = 0;
439 @@ -1552,9 +1538,9 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
440  
441      if (ts->copyts < 1) {
442          if (pts != AV_NOPTS_VALUE)
443 -            pts += delay;
444 +            pts += ts->delay * 2;
445          if (dts != AV_NOPTS_VALUE)
446 -            dts += delay;
447 +            dts += ts->delay * 2;
448      }
449  
450      if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
451 @@ -1904,10 +1890,13 @@ static const AVOption options[] = {
452        { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
453      { "mpegts_start_pid", "Set the first pid.",
454        offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
455 -      { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
456 +      { .i64 = -1 }, -1, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
457      { "mpegts_m2ts_mode", "Enable m2ts mode.",
458 -      offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
459 -      { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
460 +      offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT,
461 +      { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM },
462 +    { "mpegts_pcr_offset", "clock offset.",
463 +      offsetof(MpegTSWrite, ts_offset), AV_OPT_TYPE_BOOL,
464 +      { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
465      { "muxrate", NULL,
466        offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
467        { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
468 @@ -1941,15 +1930,15 @@ static const AVOption options[] = {
469      { "omit_video_pes_length", "Omit the PES packet length for video packets",
470        offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL,
471        { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
472 -    { "pcr_period", "PCR retransmission time in milliseconds",
473 -      offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_INT,
474 -      { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
475 -    { "pat_period", "PAT/PMT retransmission time limit in seconds",
476 -      offsetof(MpegTSWrite, pat_period_us), AV_OPT_TYPE_DURATION,
477 -      { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
478 -    { "sdt_period", "SDT retransmission time limit in seconds",
479 -      offsetof(MpegTSWrite, sdt_period_us), AV_OPT_TYPE_DURATION,
480 -      { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
481 +    { "pcr_period", "PCR retransmission time limit in msecs",
482 +      offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_DOUBLE,
483 +      { .dbl = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
484 +    { "pat_period", "PAT/PMT retransmission time limit in msecs",
485 +      offsetof(MpegTSWrite, pat_period_ms), AV_OPT_TYPE_DOUBLE,
486 +      { .dbl = PAT_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
487 +    { "sdt_period", "SDT retransmission time limit in msecs",
488 +      offsetof(MpegTSWrite, sdt_period_ms), AV_OPT_TYPE_DOUBLE,
489 +      { .dbl = SDT_RETRANS_TIME }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
490      { NULL },
491  };
492