* 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>
| ... | ... |
@@ -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 */ |