Browse code

Merge remote-tracking branch 'qatar/master'

* qatar/master: (22 commits)
configure: add check for w32threads to enable it automatically
rtmp: do not hardcode invoke numbers
cinepack: return non-generic errors
fate-lavf-ts: use -mpegts_transport_stream_id option.
Add an APIchanges entry and a minor bump for avio changes.
avio: Mark the old interrupt callback mechanism as deprecated
avplay: Set the new interrupt callback
avconv: Set new interrupt callbacks for all AVFormatContexts, use avio_open2() everywhere
cinepak: remove redundant coordinate checks
cinepak: check strip_size
cinepak, simplify, use AV_RB24()
cinepak: simplify, use FFMIN()
cinepak: Fix division by zero, ask for sample if encoded_buf_size is 0
applehttp: Fix seeking in streams not starting at DTS=0
http: Don't use the normal http proxy mechanism for https
tls: Handle connection via a http proxy
http: Reorder two code blocks
http: Add a new protocol for opening connections via http proxies
http: Split out the non-chunked buffer reading part from http_read
segafilm: add support for raw videos
...

Conflicts:
avconv.c
configure
doc/APIchanges
libavcodec/cinepak.c
libavformat/applehttp.c
libavformat/version.h
tests/lavf-regression.sh
tests/ref/lavf/ts

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2011/11/19 09:55:55
Showing 20 changed files
... ...
@@ -588,12 +588,14 @@ static int read_key(void)
588 588
     return -1;
589 589
 }
590 590
 
591
-static int decode_interrupt_cb(void)
591
+static int decode_interrupt_cb(void *ctx)
592 592
 {
593 593
     q_pressed += read_key() == 'q';
594 594
     return q_pressed > 1;
595 595
 }
596 596
 
597
+static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
598
+
597 599
 void exit_program(int ret)
598 600
 {
599 601
     int i;
... ...
@@ -2336,6 +2338,7 @@ static int transcode_init(OutputFile *output_files,
2336 2336
     /* open files and write file headers */
2337 2337
     for (i = 0; i < nb_output_files; i++) {
2338 2338
         os = output_files[i].ctx;
2339
+        os->interrupt_callback = int_cb;
2339 2340
         if (avformat_write_header(os, &output_files[i].opts) < 0) {
2340 2341
             snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
2341 2342
             ret = AVERROR(EINVAL);
... ...
@@ -3010,7 +3013,7 @@ static void dump_attachment(AVStream *st, const char *filename)
3010 3010
 
3011 3011
     assert_file_overwrite(filename);
3012 3012
 
3013
-    if ((ret = avio_open (&out, filename, AVIO_FLAG_WRITE)) < 0) {
3013
+    if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
3014 3014
         av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
3015 3015
                filename);
3016 3016
         exit_program(1);
... ...
@@ -3068,6 +3071,7 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
3068 3068
         av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
3069 3069
 
3070 3070
     ic->flags |= AVFMT_FLAG_NONBLOCK;
3071
+    ic->interrupt_callback = int_cb;
3071 3072
 
3072 3073
     /* open the input file with generic libav function */
3073 3074
     err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
... ...
@@ -3197,12 +3201,12 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV
3197 3197
         if (codec_name) {
3198 3198
             snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
3199 3199
                      i != 1 ? "" : "/.avconv", codec_name, preset_name);
3200
-            ret = avio_open(s, filename, AVIO_FLAG_READ);
3200
+            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
3201 3201
         }
3202 3202
         if (ret) {
3203 3203
             snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
3204 3204
                      i != 1 ? "" : "/.avconv", preset_name);
3205
-            ret = avio_open(s, filename, AVIO_FLAG_READ);
3205
+            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
3206 3206
         }
3207 3207
     }
3208 3208
     return ret;
... ...
@@ -3588,8 +3592,9 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
3588 3588
 static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
3589 3589
 {
3590 3590
     int i, err;
3591
-    AVFormatContext *ic = NULL;
3591
+    AVFormatContext *ic = avformat_alloc_context();
3592 3592
 
3593
+    ic->interrupt_callback = int_cb;
3593 3594
     err = avformat_open_input(&ic, filename, NULL, NULL);
3594 3595
     if (err < 0)
3595 3596
         return err;
... ...
@@ -3638,6 +3643,7 @@ static void opt_output_file(void *optctx, const char *filename)
3638 3638
     }
3639 3639
 
3640 3640
     file_oformat= oc->oformat;
3641
+    oc->interrupt_callback = int_cb;
3641 3642
 
3642 3643
     if (!strcmp(file_oformat->name, "ffm") &&
3643 3644
         av_strstart(filename, "http:", NULL)) {
... ...
@@ -3729,7 +3735,7 @@ static void opt_output_file(void *optctx, const char *filename)
3729 3729
         const char *p;
3730 3730
         int64_t len;
3731 3731
 
3732
-        if ((err = avio_open(&pb, o->attachments[i], AVIO_FLAG_READ)) < 0) {
3732
+        if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
3733 3733
             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
3734 3734
                    o->attachments[i]);
3735 3735
             exit_program(1);
... ...
@@ -3779,7 +3785,9 @@ static void opt_output_file(void *optctx, const char *filename)
3779 3779
         assert_file_overwrite(filename);
3780 3780
 
3781 3781
         /* open the file */
3782
-        if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
3782
+        if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
3783
+                              &oc->interrupt_callback,
3784
+                              &output_files[nb_output_files - 1].opts)) < 0) {
3783 3785
             print_error(filename, err);
3784 3786
             exit_program(1);
3785 3787
         }
... ...
@@ -4350,12 +4358,6 @@ int main(int argc, char **argv)
4350 4350
     av_register_all();
4351 4351
     avformat_network_init();
4352 4352
 
4353
-#if HAVE_ISATTY
4354
-    if(isatty(STDIN_FILENO))
4355
-        avio_set_interrupt_cb(decode_interrupt_cb);
4356
-#endif
4357
-
4358
-    show_banner();
4359 4353
 
4360 4354
     /* parse options */
4361 4355
     parse_options(&o, argc, argv, options, opt_output_file);
... ...
@@ -2583,7 +2583,6 @@ case $target_os in
2583 2583
             disable network
2584 2584
         else
2585 2585
             target_os=mingw32
2586
-            enable_weak w32threads
2587 2586
         fi
2588 2587
         LIBTARGET=i386
2589 2588
         if enabled x86_64; then
... ...
@@ -2999,6 +2998,10 @@ if ! disabled vda; then
2999 2999
     fi
3000 3000
 fi
3001 3001
 
3002
+if ! disabled w32threads && ! enabled pthreads; then
3003
+    check_func _beginthreadex && enable w32threads
3004
+fi
3005
+
3002 3006
 # check for some common methods of building with pthread support
3003 3007
 # do this before the optional library checks as some of them require pthreads
3004 3008
 if ! disabled pthreads && ! enabled w32threads && ! enabled os2threads; then
... ...
@@ -19,6 +19,16 @@ API changes, most recent first:
19 19
 2011-10-20 - b35e9e1 - lavu 51.22.0
20 20
   Add av_strtok() to avstring.h.
21 21
 
22
+2011-11-13 - lavf 53.15.0
23
+  New interrupt callback API, allowing per-AVFormatContext/AVIOContext
24
+  interrupt callbacks.
25
+  6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to
26
+          AVFormatContext.
27
+  1dee0ac Add avio_open2() with additional parameters. Those are
28
+          an interrupt callback and an options AVDictionary.
29
+          This will allow passing AVOptions to protocols after lavf
30
+          54.0.
31
+
22 32
 2011-11-xx - xxxxxxx - lavu 51.16.0
23 33
   Add av_timegm()
24 34
 
... ...
@@ -635,11 +635,13 @@ static int read_key(void)
635 635
     return -1;
636 636
 }
637 637
 
638
-static int decode_interrupt_cb(void)
638
+static int decode_interrupt_cb(void *ctx)
639 639
 {
640 640
     return received_nb_signals > 1;
641 641
 }
642 642
 
643
+static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
644
+
643 645
 void av_noreturn exit_program(int ret)
644 646
 {
645 647
     int i;
... ...
@@ -2403,6 +2405,7 @@ static int transcode_init(OutputFile *output_files, int nb_output_files,
2403 2403
     /* open files and write file headers */
2404 2404
     for (i = 0; i < nb_output_files; i++) {
2405 2405
         os = output_files[i].ctx;
2406
+        os->interrupt_callback = int_cb;
2406 2407
         if (avformat_write_header(os, &output_files[i].opts) < 0) {
2407 2408
             snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
2408 2409
             ret = AVERROR(EINVAL);
... ...
@@ -2495,7 +2498,6 @@ static int transcode(OutputFile *output_files, int nb_output_files,
2495 2495
 
2496 2496
     if (!using_stdin) {
2497 2497
         av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
2498
-        avio_set_interrupt_cb(decode_interrupt_cb);
2499 2498
     }
2500 2499
 
2501 2500
     timer_start = av_gettime();
... ...
@@ -3243,7 +3245,7 @@ static void dump_attachment(AVStream *st, const char *filename)
3243 3243
 
3244 3244
     assert_file_overwrite(filename);
3245 3245
 
3246
-    if ((ret = avio_open (&out, filename, AVIO_FLAG_WRITE)) < 0) {
3246
+    if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
3247 3247
         av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
3248 3248
                filename);
3249 3249
         exit_program(1);
... ...
@@ -3307,6 +3309,7 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
3307 3307
     ic->subtitle_codec_id= subtitle_codec_name ?
3308 3308
         find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0)->id : CODEC_ID_NONE;
3309 3309
     ic->flags |= AVFMT_FLAG_NONBLOCK;
3310
+    ic->interrupt_callback = int_cb;
3310 3311
 
3311 3312
     if (loop_input) {
3312 3313
         av_log(NULL, AV_LOG_WARNING, "-loop_input is deprecated, use -loop 1\n");
... ...
@@ -3438,12 +3441,12 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV
3438 3438
         if (codec_name) {
3439 3439
             snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
3440 3440
                      i != 1 ? "" : "/.avconv", codec_name, preset_name);
3441
-            ret = avio_open(s, filename, AVIO_FLAG_READ);
3441
+            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
3442 3442
         }
3443 3443
         if (ret) {
3444 3444
             snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
3445 3445
                      i != 1 ? "" : "/.avconv", preset_name);
3446
-            ret = avio_open(s, filename, AVIO_FLAG_READ);
3446
+            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
3447 3447
         }
3448 3448
     }
3449 3449
     return ret;
... ...
@@ -3856,8 +3859,9 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
3856 3856
 static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
3857 3857
 {
3858 3858
     int i, err;
3859
-    AVFormatContext *ic = NULL;
3859
+    AVFormatContext *ic = avformat_alloc_context();
3860 3860
 
3861
+    ic->interrupt_callback = int_cb;
3861 3862
     err = avformat_open_input(&ic, filename, NULL, NULL);
3862 3863
     if (err < 0)
3863 3864
         return err;
... ...
@@ -3908,6 +3912,7 @@ static void opt_output_file(void *optctx, const char *filename)
3908 3908
         exit_program(1);
3909 3909
     }
3910 3910
     file_oformat= oc->oformat;
3911
+    oc->interrupt_callback = int_cb;
3911 3912
 
3912 3913
     if (!strcmp(file_oformat->name, "ffm") &&
3913 3914
         av_strstart(filename, "http:", NULL)) {
... ...
@@ -4019,7 +4024,7 @@ static void opt_output_file(void *optctx, const char *filename)
4019 4019
         const char *p;
4020 4020
         int64_t len;
4021 4021
 
4022
-        if ((err = avio_open(&pb, o->attachments[i], AVIO_FLAG_READ)) < 0) {
4022
+        if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
4023 4023
             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
4024 4024
                    o->attachments[i]);
4025 4025
             exit_program(1);
... ...
@@ -4069,7 +4074,9 @@ static void opt_output_file(void *optctx, const char *filename)
4069 4069
         assert_file_overwrite(filename);
4070 4070
 
4071 4071
         /* open the file */
4072
-        if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
4072
+        if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
4073
+                              &oc->interrupt_callback,
4074
+                              &output_files[nb_output_files - 1].opts)) < 0) {
4073 4075
             print_error(filename, err);
4074 4076
             exit_program(1);
4075 4077
         }
... ...
@@ -4725,12 +4732,6 @@ int main(int argc, char **argv)
4725 4725
     av_register_all();
4726 4726
     avformat_network_init();
4727 4727
 
4728
-#if HAVE_ISATTY
4729
-    if(isatty(STDIN_FILENO))
4730
-        avio_set_interrupt_cb(decode_interrupt_cb);
4731
-#endif
4732
-
4733
-    show_banner();
4734 4728
 
4735 4729
     term_init();
4736 4730
 
... ...
@@ -2414,7 +2414,7 @@ static void stream_component_close(VideoState *is, int stream_index)
2414 2414
    variable instead of a thread local variable */
2415 2415
 static VideoState *global_video_state;
2416 2416
 
2417
-static int decode_interrupt_cb(void)
2417
+static int decode_interrupt_cb(void *ctx)
2418 2418
 {
2419 2419
     return (global_video_state && global_video_state->abort_request);
2420 2420
 }
... ...
@@ -2439,8 +2439,9 @@ static int read_thread(void *arg)
2439 2439
     is->subtitle_stream = -1;
2440 2440
 
2441 2441
     global_video_state = is;
2442
-    avio_set_interrupt_cb(decode_interrupt_cb);
2443 2442
 
2443
+    ic = avformat_alloc_context();
2444
+    ic->interrupt_callback.callback = decode_interrupt_cb;
2444 2445
     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2445 2446
     if (err < 0) {
2446 2447
         print_error(is->filename, err);
... ...
@@ -147,7 +147,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
147 147
         for (x=strip->x1; x < strip->x2; x+=4) {
148 148
             if ((chunk_id & 0x01) && !(mask >>= 1)) {
149 149
                 if ((data + 4) > eod)
150
-                    return -1;
150
+                    return AVERROR_INVALIDDATA;
151 151
 
152 152
                 flag  = AV_RB32 (data);
153 153
                 data += 4;
... ...
@@ -157,7 +157,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
157 157
             if (!(chunk_id & 0x01) || (flag & mask)) {
158 158
                 if (!(chunk_id & 0x02) && !(mask >>= 1)) {
159 159
                     if ((data + 4) > eod)
160
-                        return -1;
160
+                        return AVERROR_INVALIDDATA;
161 161
 
162 162
                     flag  = AV_RB32 (data);
163 163
                     data += 4;
... ...
@@ -166,7 +166,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
166 166
 
167 167
                 if ((chunk_id & 0x02) || (~flag & mask)) {
168 168
                     if (data >= eod)
169
-                        return -1;
169
+                        return AVERROR_INVALIDDATA;
170 170
 
171 171
                     codebook = &strip->v1_codebook[*data++];
172 172
                     s->frame.data[0][iy[0] + 0] = codebook->y0;
... ...
@@ -207,7 +207,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
207 207
 
208 208
                 } else if (flag & mask) {
209 209
                     if ((data + 4) > eod)
210
-                        return -1;
210
+                        return AVERROR_INVALIDDATA;
211 211
 
212 212
                     codebook = &strip->v4_codebook[*data++];
213 213
                     s->frame.data[0][iy[0] + 0] = codebook->y0;
... ...
@@ -269,16 +269,16 @@ static int cinepak_decode_strip (CinepakContext *s,
269 269
     int      chunk_id, chunk_size;
270 270
 
271 271
     /* coordinate sanity checks */
272
-    if (strip->x2 > s->width  ||
273
-        strip->y2 > s->height ||
272
+    if (strip->x2 > s->width   ||
273
+        strip->y2 > s->height  ||
274 274
         strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
275
-        return -1;
275
+        return AVERROR_INVALIDDATA;
276 276
 
277 277
     while ((data + 4) <= eod) {
278 278
         chunk_id   = data[0];
279 279
         chunk_size = AV_RB24 (&data[1]) - 4;
280 280
         if(chunk_size < 0)
281
-            return -1;
281
+            return AVERROR_INVALIDDATA;
282 282
 
283 283
         data      += 4;
284 284
         chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;
... ...
@@ -311,7 +311,7 @@ static int cinepak_decode_strip (CinepakContext *s,
311 311
         data += chunk_size;
312 312
     }
313 313
 
314
-    return -1;
314
+    return AVERROR_INVALIDDATA;
315 315
 }
316 316
 
317 317
 static int cinepak_decode (CinepakContext *s)
... ...
@@ -322,7 +322,7 @@ static int cinepak_decode (CinepakContext *s)
322 322
     int           encoded_buf_size;
323 323
 
324 324
     if (s->size < 10)
325
-        return -1;
325
+        return AVERROR_INVALIDDATA;
326 326
 
327 327
     frame_flags = s->data[0];
328 328
     num_strips  = AV_RB16 (&s->data[8]);
... ...
@@ -330,9 +330,9 @@ static int cinepak_decode (CinepakContext *s)
330 330
 
331 331
     /* if this is the first frame, check for deviant Sega FILM data */
332 332
     if (s->sega_film_skip_bytes == -1) {
333
-        if (!encoded_buf_size){
333
+        if (!encoded_buf_size) {
334 334
             av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0");
335
-            return -1;
335
+            return AVERROR_INVALIDDATA;
336 336
         }
337 337
         if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
338 338
             /* If the encoded frame size differs from the frame size as indicated
... ...
@@ -363,7 +363,7 @@ static int cinepak_decode (CinepakContext *s)
363 363
 
364 364
     for (i=0; i < num_strips; i++) {
365 365
         if ((s->data + 12) > eod)
366
-            return -1;
366
+            return AVERROR_INVALIDDATA;
367 367
 
368 368
         s->strips[i].id = s->data[0];
369 369
         s->strips[i].y1 = y0;
... ...
@@ -375,8 +375,8 @@ static int cinepak_decode (CinepakContext *s)
375 375
             s->frame.key_frame = 1;
376 376
 
377 377
         strip_size = AV_RB24 (&s->data[1]) - 12;
378
-        if(strip_size < 0)
379
-            return -1;
378
+        if (strip_size < 0)
379
+            return AVERROR_INVALIDDATA;
380 380
         s->data   += 12;
381 381
         strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;
382 382
 
... ...
@@ -427,7 +427,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
427 427
                                 AVPacket *avpkt)
428 428
 {
429 429
     const uint8_t *buf = avpkt->data;
430
-    int buf_size = avpkt->size;
430
+    int ret = 0, buf_size = avpkt->size;
431 431
     CinepakContext *s = avctx->priv_data;
432 432
 
433 433
     s->data = buf;
... ...
@@ -436,9 +436,9 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
436 436
     s->frame.reference = 3;
437 437
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
438 438
                             FF_BUFFER_HINTS_REUSABLE;
439
-    if (avctx->reget_buffer(avctx, &s->frame)) {
439
+    if ((ret = avctx->reget_buffer(avctx, &s->frame))) {
440 440
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
441
-        return -1;
441
+        return ret;
442 442
     }
443 443
 
444 444
     if (s->palette_video) {
... ...
@@ -259,6 +259,7 @@ void av_register_all(void)
259 259
     REGISTER_PROTOCOL (FILE, file);
260 260
     REGISTER_PROTOCOL (GOPHER, gopher);
261 261
     REGISTER_PROTOCOL (HTTP, http);
262
+    REGISTER_PROTOCOL (HTTPPROXY, httpproxy);
262 263
     REGISTER_PROTOCOL (HTTPS, https);
263 264
     REGISTER_PROTOCOL (MMSH, mmsh);
264 265
     REGISTER_PROTOCOL (MMST, mmst);
... ...
@@ -644,7 +644,8 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index,
644 644
     for (i = 0; i < c->n_variants; i++) {
645 645
         /* Reset reading */
646 646
         struct variant *var = c->variants[i];
647
-        int64_t pos = av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
647
+        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
648
+                      av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
648 649
                                s->streams[stream_index]->time_base.den :
649 650
                                AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
650 651
                                AV_ROUND_DOWN : AV_ROUND_UP);
... ...
@@ -83,9 +83,11 @@ const AVClass ffurl_context_class = {
83 83
 };
84 84
 /*@}*/
85 85
 
86
-static int default_interrupt_cb(void);
87 86
 
87
+#if FF_API_OLD_INTERRUPT_CB
88
+static int default_interrupt_cb(void);
88 89
 int (*url_interrupt_cb)(void) = default_interrupt_cb;
90
+#endif
89 91
 
90 92
 URLProtocol *av_protocol_next(URLProtocol *p)
91 93
 {
... ...
@@ -444,6 +446,7 @@ int ffurl_get_file_handle(URLContext *h)
444 444
     return h->prot->url_get_file_handle(h);
445 445
 }
446 446
 
447
+#if FF_API_OLD_INTERRUPT_CB
447 448
 static int default_interrupt_cb(void)
448 449
 {
449 450
     return 0;
... ...
@@ -455,13 +458,18 @@ void avio_set_interrupt_cb(int (*interrupt_cb)(void))
455 455
         interrupt_cb = default_interrupt_cb;
456 456
     url_interrupt_cb = interrupt_cb;
457 457
 }
458
+#endif
458 459
 
459 460
 int ff_check_interrupt(AVIOInterruptCB *cb)
460 461
 {
461 462
     int ret;
462 463
     if (cb && cb->callback && (ret = cb->callback(cb->opaque)))
463 464
         return ret;
465
+#if FF_API_OLD_INTERRUPT_CB
464 466
     return url_interrupt_cb();
467
+#else
468
+    return 0;
469
+#endif
465 470
 }
466 471
 
467 472
 #if FF_API_OLD_AVIO
... ...
@@ -386,13 +386,17 @@ attribute_deprecated int url_exist(const char *url);
386 386
  */
387 387
 int avio_check(const char *url, int flags);
388 388
 
389
+#if FF_API_OLD_INTERRUPT_CB
389 390
 /**
390 391
  * The callback is called in blocking functions to test regulary if
391 392
  * asynchronous interruption is needed. AVERROR_EXIT is returned
392 393
  * in this case by the interrupted function. 'NULL' means no interrupt
393 394
  * callback is given.
395
+ * @deprecated Use interrupt_callback in AVFormatContext/avio_open2
396
+ *             instead.
394 397
  */
395
-void avio_set_interrupt_cb(int (*interrupt_cb)(void));
398
+attribute_deprecated void avio_set_interrupt_cb(int (*interrupt_cb)(void));
399
+#endif
396 400
 
397 401
 /**
398 402
  * Allocate and initialize an AVIOContext for buffered I/O. It must be later
... ...
@@ -110,6 +110,15 @@ static int http_open_cnx(URLContext *h)
110 110
                  path1, sizeof(path1), s->location);
111 111
     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
112 112
 
113
+    if (!strcmp(proto, "https")) {
114
+        lower_proto = "tls";
115
+        use_proxy = 0;
116
+        if (port < 0)
117
+            port = 443;
118
+    }
119
+    if (port < 0)
120
+        port = 80;
121
+
113 122
     if (path1[0] == '\0')
114 123
         path = "/";
115 124
     else
... ...
@@ -124,13 +133,6 @@ static int http_open_cnx(URLContext *h)
124 124
         av_url_split(NULL, 0, proxyauth, sizeof(proxyauth),
125 125
                      hostname, sizeof(hostname), &port, NULL, 0, proxy_path);
126 126
     }
127
-    if (!strcmp(proto, "https")) {
128
-        lower_proto = "tls";
129
-        if (port < 0)
130
-            port = 443;
131
-    }
132
-    if (port < 0)
133
-        port = 80;
134 127
 
135 128
     ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
136 129
     err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE,
... ...
@@ -413,10 +415,33 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
413 413
 }
414 414
 
415 415
 
416
-static int http_read(URLContext *h, uint8_t *buf, int size)
416
+static int http_buf_read(URLContext *h, uint8_t *buf, int size)
417 417
 {
418 418
     HTTPContext *s = h->priv_data;
419 419
     int len;
420
+    /* read bytes from input buffer first */
421
+    len = s->buf_end - s->buf_ptr;
422
+    if (len > 0) {
423
+        if (len > size)
424
+            len = size;
425
+        memcpy(buf, s->buf_ptr, len);
426
+        s->buf_ptr += len;
427
+    } else {
428
+        if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize)
429
+            return AVERROR_EOF;
430
+        len = ffurl_read(s->hd, buf, size);
431
+    }
432
+    if (len > 0) {
433
+        s->off += len;
434
+        if (s->chunksize > 0)
435
+            s->chunksize -= len;
436
+    }
437
+    return len;
438
+}
439
+
440
+static int http_read(URLContext *h, uint8_t *buf, int size)
441
+{
442
+    HTTPContext *s = h->priv_data;
420 443
 
421 444
     if (s->chunksize >= 0) {
422 445
         if (!s->chunksize) {
... ...
@@ -439,24 +464,7 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
439 439
         }
440 440
         size = FFMIN(size, s->chunksize);
441 441
     }
442
-    /* read bytes from input buffer first */
443
-    len = s->buf_end - s->buf_ptr;
444
-    if (len > 0) {
445
-        if (len > size)
446
-            len = size;
447
-        memcpy(buf, s->buf_ptr, len);
448
-        s->buf_ptr += len;
449
-    } else {
450
-        if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize)
451
-            return AVERROR_EOF;
452
-        len = ffurl_read(s->hd, buf, size);
453
-    }
454
-    if (len > 0) {
455
-        s->off += len;
456
-        if (s->chunksize > 0)
457
-            s->chunksize -= len;
458
-    }
459
-    return len;
442
+    return http_buf_read(h, buf, size);
460 443
 }
461 444
 
462 445
 /* used only when posting data */
... ...
@@ -572,3 +580,118 @@ URLProtocol ff_https_protocol = {
572 572
     .priv_data_class     = &https_context_class,
573 573
 };
574 574
 #endif
575
+
576
+#if CONFIG_HTTPPROXY_PROTOCOL
577
+static int http_proxy_close(URLContext *h)
578
+{
579
+    HTTPContext *s = h->priv_data;
580
+    if (s->hd)
581
+        ffurl_close(s->hd);
582
+    return 0;
583
+}
584
+
585
+static int http_proxy_open(URLContext *h, const char *uri, int flags)
586
+{
587
+    HTTPContext *s = h->priv_data;
588
+    char hostname[1024], hoststr[1024];
589
+    char auth[1024], pathbuf[1024], *path;
590
+    char line[1024], lower_url[100];
591
+    int port, ret = 0;
592
+    HTTPAuthType cur_auth_type;
593
+    char *authstr;
594
+
595
+    h->is_streamed = 1;
596
+
597
+    av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
598
+                 pathbuf, sizeof(pathbuf), uri);
599
+    ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
600
+    path = pathbuf;
601
+    if (*path == '/')
602
+        path++;
603
+
604
+    ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,
605
+                NULL);
606
+redo:
607
+    ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
608
+                     &h->interrupt_callback, NULL);
609
+    if (ret < 0)
610
+        return ret;
611
+
612
+    authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,
613
+                                           path, "CONNECT");
614
+    snprintf(s->buffer, sizeof(s->buffer),
615
+             "CONNECT %s HTTP/1.1\r\n"
616
+             "Host: %s\r\n"
617
+             "Connection: close\r\n"
618
+             "%s%s"
619
+             "\r\n",
620
+             path,
621
+             hoststr,
622
+             authstr ? "Proxy-" : "", authstr ? authstr : "");
623
+    av_freep(&authstr);
624
+
625
+    if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
626
+        goto fail;
627
+
628
+    s->buf_ptr = s->buffer;
629
+    s->buf_end = s->buffer;
630
+    s->line_count = 0;
631
+    s->filesize = -1;
632
+    cur_auth_type = s->proxy_auth_state.auth_type;
633
+
634
+    for (;;) {
635
+        int new_loc;
636
+        // Note: This uses buffering, potentially reading more than the
637
+        // HTTP header. If tunneling a protocol where the server starts
638
+        // the conversation, we might buffer part of that here, too.
639
+        // Reading that requires using the proper ffurl_read() function
640
+        // on this URLContext, not using the fd directly (as the tls
641
+        // protocol does). This shouldn't be an issue for tls though,
642
+        // since the client starts the conversation there, so there
643
+        // is no extra data that we might buffer up here.
644
+        if (http_get_line(s, line, sizeof(line)) < 0) {
645
+            ret = AVERROR(EIO);
646
+            goto fail;
647
+        }
648
+
649
+        av_dlog(h, "header='%s'\n", line);
650
+
651
+        ret = process_line(h, line, s->line_count, &new_loc);
652
+        if (ret < 0)
653
+            goto fail;
654
+        if (ret == 0)
655
+            break;
656
+        s->line_count++;
657
+    }
658
+    if (s->http_code == 407 && cur_auth_type == HTTP_AUTH_NONE &&
659
+        s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) {
660
+        ffurl_close(s->hd);
661
+        s->hd = NULL;
662
+        goto redo;
663
+    }
664
+
665
+    if (s->http_code < 400)
666
+        return 0;
667
+    ret = AVERROR(EIO);
668
+
669
+fail:
670
+    http_proxy_close(h);
671
+    return ret;
672
+}
673
+
674
+static int http_proxy_write(URLContext *h, const uint8_t *buf, int size)
675
+{
676
+    HTTPContext *s = h->priv_data;
677
+    return ffurl_write(s->hd, buf, size);
678
+}
679
+
680
+URLProtocol ff_httpproxy_protocol = {
681
+    .name                = "httpproxy",
682
+    .url_open            = http_proxy_open,
683
+    .url_read            = http_buf_read,
684
+    .url_write           = http_proxy_write,
685
+    .url_close           = http_proxy_close,
686
+    .url_get_file_handle = http_get_file_handle,
687
+    .priv_data_size      = sizeof(HTTPContext),
688
+};
689
+#endif
... ...
@@ -74,6 +74,7 @@ typedef struct RTMPContext {
74 74
     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
75 75
     uint8_t       flv_header[11];             ///< partial incoming flv packet header
76 76
     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
77
+    int           nb_invokes;                 ///< keeps track of invoke messages
77 78
 } RTMPContext;
78 79
 
79 80
 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
... ...
@@ -166,7 +167,7 @@ static void gen_release_stream(URLContext *s, RTMPContext *rt)
166 166
     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
167 167
     p = pkt.data;
168 168
     ff_amf_write_string(&p, "releaseStream");
169
-    ff_amf_write_number(&p, 2.0);
169
+    ff_amf_write_number(&p, ++rt->nb_invokes);
170 170
     ff_amf_write_null(&p);
171 171
     ff_amf_write_string(&p, rt->playpath);
172 172
 
... ...
@@ -189,7 +190,7 @@ static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
189 189
     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
190 190
     p = pkt.data;
191 191
     ff_amf_write_string(&p, "FCPublish");
192
-    ff_amf_write_number(&p, 3.0);
192
+    ff_amf_write_number(&p, ++rt->nb_invokes);
193 193
     ff_amf_write_null(&p);
194 194
     ff_amf_write_string(&p, rt->playpath);
195 195
 
... ...
@@ -212,7 +213,7 @@ static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
212 212
     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
213 213
     p = pkt.data;
214 214
     ff_amf_write_string(&p, "FCUnpublish");
215
-    ff_amf_write_number(&p, 5.0);
215
+    ff_amf_write_number(&p, ++rt->nb_invokes);
216 216
     ff_amf_write_null(&p);
217 217
     ff_amf_write_string(&p, rt->playpath);
218 218
 
... ...
@@ -234,7 +235,7 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt)
234 234
 
235 235
     p = pkt.data;
236 236
     ff_amf_write_string(&p, "createStream");
237
-    ff_amf_write_number(&p, rt->is_input ? 3.0 : 4.0);
237
+    ff_amf_write_number(&p, ++rt->nb_invokes);
238 238
     ff_amf_write_null(&p);
239 239
 
240 240
     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
... ...
@@ -429,7 +429,7 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
429 429
     if (timestamp == RTP_NOTS_VALUE)
430 430
         return;
431 431
 
432
-    if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
432
+    if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && s->ic->nb_streams > 1) {
433 433
         int64_t addend;
434 434
         int delta_timestamp;
435 435
 
... ...
@@ -444,7 +444,13 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
444 444
 
445 445
     if (!s->base_timestamp)
446 446
         s->base_timestamp = timestamp;
447
-    pkt->pts = s->range_start_offset + timestamp - s->base_timestamp;
447
+    /* assume that the difference is INT32_MIN < x < INT32_MAX, but allow the first timestamp to exceed INT32_MAX */
448
+    if (!s->timestamp)
449
+        s->unwrapped_timestamp += timestamp;
450
+    else
451
+        s->unwrapped_timestamp += (int32_t)(timestamp - s->timestamp);
452
+    s->timestamp = timestamp;
453
+    pkt->pts = s->unwrapped_timestamp + s->range_start_offset - s->base_timestamp;
448 454
 }
449 455
 
450 456
 static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
... ...
@@ -151,6 +151,7 @@ struct RTPDemuxContext {
151 151
     uint32_t timestamp;
152 152
     uint32_t base_timestamp;
153 153
     uint32_t cur_timestamp;
154
+    int64_t  unwrapped_timestamp;
154 155
     int64_t  range_start_offset;
155 156
     int max_payload_size;
156 157
     struct MpegTSContext *ts;   /* only used for MP2T payloads */
... ...
@@ -52,6 +52,8 @@ static int rtsp_read_play(AVFormatContext *s)
52 52
                 rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE;
53 53
                 rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
54 54
                 rtpctx->base_timestamp      = 0;
55
+                rtpctx->timestamp           = 0;
56
+                rtpctx->unwrapped_timestamp = 0;
55 57
                 rtpctx->rtcp_ts_offset      = 0;
56 58
             }
57 59
         }
... ...
@@ -34,6 +34,7 @@
34 34
 #define FDSC_TAG MKBETAG('F', 'D', 'S', 'C')
35 35
 #define STAB_TAG MKBETAG('S', 'T', 'A', 'B')
36 36
 #define CVID_TAG MKBETAG('c', 'v', 'i', 'd')
37
+#define RAW_TAG  MKBETAG('r', 'a', 'w', ' ')
37 38
 
38 39
 typedef struct {
39 40
   int stream;
... ...
@@ -129,8 +130,11 @@ static int film_read_header(AVFormatContext *s,
129 129
 
130 130
     if (AV_RB32(&scratch[8]) == CVID_TAG) {
131 131
         film->video_type = CODEC_ID_CINEPAK;
132
-    } else
132
+    } else if (AV_RB32(&scratch[8]) == RAW_TAG) {
133
+        film->video_type = CODEC_ID_RAWVIDEO;
134
+    } else {
133 135
         film->video_type = CODEC_ID_NONE;
136
+    }
134 137
 
135 138
     /* initialize the decoder streams */
136 139
     if (film->video_type) {
... ...
@@ -143,6 +147,15 @@ static int film_read_header(AVFormatContext *s,
143 143
         st->codec->codec_tag = 0;  /* no fourcc */
144 144
         st->codec->width = AV_RB32(&scratch[16]);
145 145
         st->codec->height = AV_RB32(&scratch[12]);
146
+
147
+        if (film->video_type == CODEC_ID_RAWVIDEO) {
148
+            if (scratch[20] == 24) {
149
+                st->codec->pix_fmt = PIX_FMT_RGB24;
150
+            } else {
151
+                av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]);
152
+                return -1;
153
+            }
154
+        }
146 155
     }
147 156
 
148 157
     if (film->audio_type) {
... ...
@@ -111,9 +111,15 @@ static int tls_open(URLContext *h, const char *uri, int flags)
111 111
     char buf[200], host[200];
112 112
     int numerichost = 0;
113 113
     struct addrinfo hints = { 0 }, *ai = NULL;
114
+    const char *proxy_path;
115
+    int use_proxy;
114 116
 
115 117
     ff_tls_init();
116 118
 
119
+    proxy_path = getenv("http_proxy");
120
+    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
121
+        av_strstart(proxy_path, "http://", NULL);
122
+
117 123
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri);
118 124
     ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, NULL);
119 125
 
... ...
@@ -123,6 +129,17 @@ static int tls_open(URLContext *h, const char *uri, int flags)
123 123
         freeaddrinfo(ai);
124 124
     }
125 125
 
126
+    if (use_proxy) {
127
+        char proxy_host[200], proxy_auth[200], dest[200];
128
+        int proxy_port;
129
+        av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth),
130
+                     proxy_host, sizeof(proxy_host), &proxy_port, NULL, 0,
131
+                     proxy_path);
132
+        ff_url_join(dest, sizeof(dest), NULL, NULL, host, port, NULL);
133
+        ff_url_join(buf, sizeof(buf), "httpproxy", proxy_auth, proxy_host,
134
+                    proxy_port, "/%s", dest);
135
+    }
136
+
126 137
     ret = ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE,
127 138
                      &h->interrupt_callback, NULL);
128 139
     if (ret)
... ...
@@ -24,7 +24,7 @@
24 24
 #include "libavutil/avutil.h"
25 25
 
26 26
 #define LIBAVFORMAT_VERSION_MAJOR 53
27
-#define LIBAVFORMAT_VERSION_MINOR 20
27
+#define LIBAVFORMAT_VERSION_MINOR 21
28 28
 #define LIBAVFORMAT_VERSION_MICRO  0
29 29
 
30 30
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
... ...
@@ -113,5 +113,8 @@
113 113
 #ifndef FF_API_REORDER_PRIVATE
114 114
 #define FF_API_REORDER_PRIVATE         (LIBAVFORMAT_VERSION_MAJOR < 54)
115 115
 #endif
116
+#ifndef FF_API_OLD_INTERRUPT_CB
117
+#define FF_API_OLD_INTERRUPT_CB        (LIBAVFORMAT_VERSION_MAJOR < 54)
118
+#endif
116 119
 
117 120
 #endif /* AVFORMAT_VERSION_H */
... ...
@@ -71,7 +71,7 @@ do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec m
71 71
 fi
72 72
 
73 73
 if [ -n "$do_ts" ] ; then
74
-do_lavf ts "-ab 64k"
74
+do_lavf ts "-ab 64k -mpegts_transport_stream_id 42"
75 75
 fi
76 76
 
77 77
 if [ -n "$do_swf" ] ; then
... ...
@@ -1,3 +1,3 @@
1
-151774afed45b19da9b7e83613a1e72b *./tests/data/lavf/lavf.ts
1
+024f0cdd4c51a158b2a38b901d2ed2e5 *./tests/data/lavf/lavf.ts
2 2
 406644 ./tests/data/lavf/lavf.ts
3 3
 ./tests/data/lavf/lavf.ts CRC=0x133216c1