diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-11-12 02:50:25 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-11-12 02:50:25 +0100 |
commit | 29582df797745fa6c5eec22b007e4fd3a47e7dd9 (patch) | |
tree | 59c487e218e4f750b48151d548db9091236d096f | |
parent | 6761b6b825c4aafff311a180a09c7013288480aa (diff) | |
parent | 29ae0565d98bb41e54fc74f74c330d3214825f47 (diff) | |
download | ffmpeg-29582df797745fa6c5eec22b007e4fd3a47e7dd9.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
vble: remove vble_error_close
VBLE Decoder
tta: use an integer instead of a pointer to iterate output samples
shorten: do not modify samples pointer when interleaving
mpc7: only support stereo input.
dpcm: do not try to decode empty packets
dpcm: remove unneeded buf_size==0 check.
twinvq: add SSE/AVX optimized sum/difference stereo interleaving
vqf/twinvq: pass vqf COMM chunk info in extradata
vqf: do not set bits_per_coded_sample for TwinVQ.
twinvq: check for allocation failure in init_mdct_win()
swscale: add padding to conversion buffer.
rtpdec: Simplify finalize_packet
http: Handle proxy authentication
http: Print an error message for Authorization Required, too
AVOptions: don't return an invalid option when option list is empty
AIFF: add 'twos' FourCC for the mux/demuxer (big endian PCM audio)
Conflicts:
libavcodec/avcodec.h
libavcodec/tta.c
libavcodec/vble.c
libavcodec/version.h
libavutil/opt.c
libswscale/utils.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/dpcm.c | 5 | ||||
-rw-r--r-- | libavcodec/dsputil.c | 13 | ||||
-rw-r--r-- | libavcodec/dsputil.h | 17 | ||||
-rw-r--r-- | libavcodec/mpc7.c | 9 | ||||
-rw-r--r-- | libavcodec/shorten.c | 7 | ||||
-rw-r--r-- | libavcodec/twinvq.c | 128 | ||||
-rw-r--r-- | libavcodec/version.h | 2 | ||||
-rw-r--r-- | libavcodec/x86/dsputil_mmx.c | 7 | ||||
-rw-r--r-- | libavcodec/x86/dsputil_yasm.asm | 48 | ||||
-rw-r--r-- | libavformat/aiff.h | 1 | ||||
-rw-r--r-- | libavformat/http.c | 76 | ||||
-rw-r--r-- | libavformat/httpauth.c | 2 | ||||
-rw-r--r-- | libavformat/rtpdec.c | 8 | ||||
-rw-r--r-- | libavformat/vqf.c | 15 | ||||
-rw-r--r-- | libavutil/opt.c | 7 |
15 files changed, 253 insertions, 92 deletions
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 8f6cd8e115..2f87f51774 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -179,9 +179,6 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int stereo = s->channels - 1; int16_t *output_samples = data; - if (!buf_size) - return 0; - /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: @@ -201,7 +198,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, break; } out *= av_get_bytes_per_sample(avctx->sample_fmt); - if (out < 0) { + if (out <= 0) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 6a33ef4f87..4c13cb3ca4 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -2543,6 +2543,18 @@ static void butterflies_float_c(float *restrict v1, float *restrict v2, } } +static void butterflies_float_interleave_c(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + for (i = 0; i < len; i++) { + float f1 = src0[i]; + float f2 = src1[i]; + dst[2*i ] = f1 + f2; + dst[2*i + 1] = f1 - f2; + } +} + static float scalarproduct_float_c(const float *v1, const float *v2, int len) { float p = 0.0; @@ -3066,6 +3078,7 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->vector_clip_int32 = vector_clip_int32_c; c->scalarproduct_float = scalarproduct_float_c; c->butterflies_float = butterflies_float_c; + c->butterflies_float_interleave = butterflies_float_interleave_c; c->vector_fmul_scalar = vector_fmul_scalar_c; c->vector_fmac_scalar = vector_fmac_scalar_c; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 92e081c411..a44c146af9 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -451,6 +451,23 @@ typedef struct DSPContext { */ void (*butterflies_float)(float *restrict v1, float *restrict v2, int len); + /** + * Calculate the sum and difference of two vectors of floats and interleave + * results into a separate output vector of floats, with each sum + * positioned before the corresponding difference. + * + * @param dst output vector + * constraints: 16-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 8 + */ + void (*butterflies_float_interleave)(float *dst, const float *src0, + const float *src1, int len); + /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); void (*fdct248)(DCTELEM *block/* align 16*/); diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 3418b7b4f8..1e76ddf56a 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -61,6 +61,13 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) static VLC_TYPE hdr_table[1 << MPC7_HDR_BITS][2]; static VLC_TYPE quant_tables[7224][2]; + /* Musepack SV7 is always stereo */ + if (avctx->channels != 2) { + av_log_ask_for_sample(avctx, "Unsupported number of channels: %d\n", + avctx->channels); + return AVERROR_PATCHWELCOME; + } + if(avctx->extradata_size < 16){ av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); return -1; @@ -88,7 +95,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) c->frames_to_skip = 0; avctx->sample_fmt = AV_SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; if(vlc_initialized) return 0; av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index df1daebb33..ee01e886a9 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -252,12 +252,13 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, return 0; } -static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) { +static void interleave_buffer(int16_t *samples, int nchan, int blocksize, + int32_t **buffer) +{ int i, chan; for (i=0; i<blocksize; i++) for (chan=0; chan < nchan; chan++) *samples++ = av_clip_int16(buffer[chan][i]); - return samples; } static const int fixed_coeffs[3][3] = { @@ -576,7 +577,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); return AVERROR(EINVAL); } - samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded); + interleave_buffer(samples, s->channels, s->blocksize, s->decoded); *data_size = out_size; } } diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 2ce7b306fc..bf8b48b15e 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -665,8 +665,9 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, float *out) { const ModeTab *mtab = tctx->mtab; + int size1, size2; float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0]; - int i, j; + int i; for (i = 0; i < tctx->avctx->channels; i++) { imdct_and_window(tctx, ftype, wtype, @@ -675,27 +676,24 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, i); } + size2 = tctx->last_block_pos[0]; + size1 = mtab->size - size2; if (tctx->avctx->channels == 2) { - for (i = 0; i < mtab->size - tctx->last_block_pos[0]; i++) { - float f1 = prev_buf[ i]; - float f2 = prev_buf[2*mtab->size + i]; - out[2*i ] = f1 + f2; - out[2*i + 1] = f1 - f2; - } - for (j = 0; i < mtab->size; j++,i++) { - float f1 = tctx->curr_frame[ j]; - float f2 = tctx->curr_frame[2*mtab->size + j]; - out[2*i ] = f1 + f2; - out[2*i + 1] = f1 - f2; - } + tctx->dsp.butterflies_float_interleave(out, prev_buf, + &prev_buf[2*mtab->size], + size1); + + out += 2 * size1; + + tctx->dsp.butterflies_float_interleave(out, tctx->curr_frame, + &tctx->curr_frame[2*mtab->size], + size2); } else { - memcpy(out, prev_buf, - (mtab->size - tctx->last_block_pos[0]) * sizeof(*out)); + memcpy(out, prev_buf, size1 * sizeof(*out)); - out += mtab->size - tctx->last_block_pos[0]; + out += size1; - memcpy(out, tctx->curr_frame, - (tctx->last_block_pos[0]) * sizeof(*out)); + memcpy(out, tctx->curr_frame, size2 * sizeof(*out)); } } @@ -871,9 +869,9 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, /** * Init IMDCT and windowing tables */ -static av_cold void init_mdct_win(TwinContext *tctx) +static av_cold int init_mdct_win(TwinContext *tctx) { - int i,j; + int i, j, ret; const ModeTab *mtab = tctx->mtab; int size_s = mtab->size / mtab->fmode[FT_SHORT].sub; int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub; @@ -882,20 +880,29 @@ static av_cold void init_mdct_win(TwinContext *tctx) for (i = 0; i < 3; i++) { int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub; - ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1, - -sqrt(norm/bsize) / (1<<15)); + if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1, + -sqrt(norm/bsize) / (1<<15)))) + return ret; } - tctx->tmp_buf = av_malloc(mtab->size * sizeof(*tctx->tmp_buf)); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->tmp_buf, + mtab->size * sizeof(*tctx->tmp_buf), alloc_fail); - tctx->spectrum = av_malloc(2*mtab->size*channels*sizeof(float)); - tctx->curr_frame = av_malloc(2*mtab->size*channels*sizeof(float)); - tctx->prev_frame = av_malloc(2*mtab->size*channels*sizeof(float)); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->spectrum, + 2 * mtab->size * channels * sizeof(*tctx->spectrum), + alloc_fail); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->curr_frame, + 2 * mtab->size * channels * sizeof(*tctx->curr_frame), + alloc_fail); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->prev_frame, + 2 * mtab->size * channels * sizeof(*tctx->prev_frame), + alloc_fail); for (i = 0; i < 3; i++) { int m = 4*mtab->size/mtab->fmode[i].sub; double freq = 2*M_PI/m; - tctx->cos_tabs[i] = av_malloc((m/4)*sizeof(*tctx->cos_tabs)); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i], + (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail); for (j = 0; j <= m/8; j++) tctx->cos_tabs[i][j] = cos((2*j + 1)*freq); @@ -907,6 +914,10 @@ static av_cold void init_mdct_win(TwinContext *tctx) ff_init_ff_sine_windows(av_log2(size_m)); ff_init_ff_sine_windows(av_log2(size_s/2)); ff_init_ff_sine_windows(av_log2(mtab->size)); + + return 0; +alloc_fail: + return AVERROR(ENOMEM); } /** @@ -1068,20 +1079,54 @@ static av_cold void init_bitstream_params(TwinContext *tctx) construct_perm_table(tctx, frametype); } +static av_cold int twin_decode_close(AVCodecContext *avctx) +{ + TwinContext *tctx = avctx->priv_data; + int i; + + for (i = 0; i < 3; i++) { + ff_mdct_end(&tctx->mdct_ctx[i]); + av_free(tctx->cos_tabs[i]); + } + + + av_free(tctx->curr_frame); + av_free(tctx->spectrum); + av_free(tctx->prev_frame); + av_free(tctx->tmp_buf); + + return 0; +} + static av_cold int twin_decode_init(AVCodecContext *avctx) { + int ret; TwinContext *tctx = avctx->priv_data; - int isampf = avctx->sample_rate/1000; - int ibps = avctx->bit_rate/(1000 * avctx->channels); + int isampf, ibps; tctx->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + if (!avctx->extradata || avctx->extradata_size < 12) { + av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n"); + return AVERROR_INVALIDDATA; + } + avctx->channels = AV_RB32(avctx->extradata ) + 1; + avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000; + isampf = AV_RB32(avctx->extradata + 8); + switch (isampf) { + case 44: avctx->sample_rate = 44100; break; + case 22: avctx->sample_rate = 22050; break; + case 11: avctx->sample_rate = 11025; break; + default: avctx->sample_rate = isampf * 1000; break; + } + if (avctx->channels > CHANNELS_MAX) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", avctx->channels); return -1; } + ibps = avctx->bit_rate / (1000 * avctx->channels); switch ((isampf << 8) + ibps) { case (8 <<8) + 8: tctx->mtab = &mode_08_08; break; @@ -1099,7 +1144,11 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) } dsputil_init(&tctx->dsp, avctx); - init_mdct_win(tctx); + if ((ret = init_mdct_win(tctx))) { + av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); + twin_decode_close(avctx); + return ret; + } init_bitstream_params(tctx); memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist)); @@ -1107,25 +1156,6 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int twin_decode_close(AVCodecContext *avctx) -{ - TwinContext *tctx = avctx->priv_data; - int i; - - for (i = 0; i < 3; i++) { - ff_mdct_end(&tctx->mdct_ctx[i]); - av_free(tctx->cos_tabs[i]); - } - - - av_free(tctx->curr_frame); - av_free(tctx->spectrum); - av_free(tctx->prev_frame); - av_free(tctx->tmp_buf); - - return 0; -} - AVCodec ff_twinvq_decoder = { .name = "twinvq", .type = AVMEDIA_TYPE_AUDIO, diff --git a/libavcodec/version.h b/libavcodec/version.h index f9328d8128..cd21d9504a 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 32 +#define LIBAVCODEC_VERSION_MINOR 33 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index 844066200b..83b9219135 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -2407,6 +2407,11 @@ void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, int32_t min void ff_vector_clip_int32_sse4 (int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len); +extern void ff_butterflies_float_interleave_sse(float *dst, const float *src0, + const float *src1, int len); +extern void ff_butterflies_float_interleave_avx(float *dst, const float *src0, + const float *src1, int len); + void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) { int mm_flags = av_get_cpu_flags(); @@ -2849,6 +2854,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->vector_clipf = vector_clipf_sse; #if HAVE_YASM c->scalarproduct_float = ff_scalarproduct_float_sse; + c->butterflies_float_interleave = ff_butterflies_float_interleave_sse; #endif } if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW)) @@ -2906,6 +2912,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_avx; c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_avx; } + c->butterflies_float_interleave = ff_butterflies_float_interleave_avx; } #endif } diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm index 82678f1880..0e497c9cda 100644 --- a/libavcodec/x86/dsputil_yasm.asm +++ b/libavcodec/x86/dsputil_yasm.asm @@ -1129,3 +1129,51 @@ VECTOR_CLIP_INT32 11, 1, 1, 0 %else VECTOR_CLIP_INT32 6, 1, 0, 0 %endif + +;----------------------------------------------------------------------------- +; void ff_butterflies_float_interleave(float *dst, const float *src0, +; const float *src1, int len); +;----------------------------------------------------------------------------- + +%macro BUTTERFLIES_FLOAT_INTERLEAVE 0 +cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len +%ifdef ARCH_X86_64 + movsxd lenq, lend +%endif + test lenq, lenq + jz .end + shl lenq, 2 + lea src0q, [src0q + lenq] + lea src1q, [src1q + lenq] + lea dstq, [ dstq + 2*lenq] + neg lenq +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + subps m2, m0, m1 + addps m0, m0, m1 + unpcklps m1, m0, m2 + unpckhps m0, m0, m2 +%if cpuflag(avx) + vextractf128 [dstq + 2*lenq ], m1, 0 + vextractf128 [dstq + 2*lenq + 16], m0, 0 + vextractf128 [dstq + 2*lenq + 32], m1, 1 + vextractf128 [dstq + 2*lenq + 48], m0, 1 +%else + mova [dstq + 2*lenq ], m1 + mova [dstq + 2*lenq + mmsize], m0 +%endif + add lenq, mmsize + jl .loop +%if mmsize == 32 + vzeroupper + RET +%endif +.end: + REP_RET +%endmacro + +INIT_XMM sse +BUTTERFLIES_FLOAT_INTERLEAVE +INIT_YMM avx +BUTTERFLIES_FLOAT_INTERLEAVE diff --git a/libavformat/aiff.h b/libavformat/aiff.h index 047f81dc1d..d909bdd83e 100644 --- a/libavformat/aiff.h +++ b/libavformat/aiff.h @@ -43,6 +43,7 @@ static const AVCodecTag ff_codec_aiff_tags[] = { { CODEC_ID_MACE6, MKTAG('M','A','C','6') }, { CODEC_ID_GSM, MKTAG('G','S','M',' ') }, { CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') }, + { CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') }, { CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, { CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, { CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, diff --git a/libavformat/http.c b/libavformat/http.c index 5f1837d6ad..2e6eb1627d 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -47,6 +47,7 @@ typedef struct { int64_t off, filesize; char location[MAX_URL_SIZE]; HTTPAuthState auth_state; + HTTPAuthState proxy_auth_state; char *headers; int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */ int chunked_post; @@ -71,25 +72,29 @@ static const AVClass flavor ## _context_class = {\ HTTP_CLASS(http); HTTP_CLASS(https); -static int http_connect(URLContext *h, const char *path, const char *hoststr, - const char *auth, int *new_location); +static int http_connect(URLContext *h, const char *path, const char *local_path, + const char *hoststr, const char *auth, + const char *proxyauth, int *new_location); void ff_http_init_auth_state(URLContext *dest, const URLContext *src) { memcpy(&((HTTPContext*)dest->priv_data)->auth_state, &((HTTPContext*)src->priv_data)->auth_state, sizeof(HTTPAuthState)); + memcpy(&((HTTPContext*)dest->priv_data)->proxy_auth_state, + &((HTTPContext*)src->priv_data)->proxy_auth_state, + sizeof(HTTPAuthState)); } /* return non zero if error */ static int http_open_cnx(URLContext *h) { - const char *path, *proxy_path, *lower_proto = "tcp"; + const char *path, *proxy_path, *lower_proto = "tcp", *local_path; char hostname[1024], hoststr[1024], proto[10]; - char auth[1024]; + char auth[1024], proxyauth[1024]; char path1[1024]; - char buf[1024]; + char buf[1024], urlbuf[1024]; int port, use_proxy, err, location_changed = 0, redirects = 0; - HTTPAuthType cur_auth_type; + HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; URLContext *hd = NULL; @@ -105,15 +110,19 @@ static int http_open_cnx(URLContext *h) path1, sizeof(path1), s->location); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); + if (path1[0] == '\0') + path = "/"; + else + path = path1; + local_path = path; if (use_proxy) { - av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - NULL, 0, proxy_path); - path = s->location; - } else { - if (path1[0] == '\0') - path = "/"; - else - path = path1; + /* Reassemble the request URL without auth string - we don't + * want to leak the auth to the proxy. */ + ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s", + path1); + path = urlbuf; + av_url_split(NULL, 0, proxyauth, sizeof(proxyauth), + hostname, sizeof(hostname), &port, NULL, 0, proxy_path); } if (!strcmp(proto, "https")) { lower_proto = "tls"; @@ -130,7 +139,8 @@ static int http_open_cnx(URLContext *h) s->hd = hd; cur_auth_type = s->auth_state.auth_type; - if (http_connect(h, path, hoststr, auth, &location_changed) < 0) + cur_proxy_auth_type = s->auth_state.auth_type; + if (http_connect(h, path, local_path, hoststr, auth, proxyauth, &location_changed) < 0) goto fail; if (s->http_code == 401) { if (cur_auth_type == HTTP_AUTH_NONE && s->auth_state.auth_type != HTTP_AUTH_NONE) { @@ -139,6 +149,14 @@ static int http_open_cnx(URLContext *h) } else goto fail; } + if (s->http_code == 407) { + if (cur_proxy_auth_type == HTTP_AUTH_NONE && + s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) { + ffurl_close(hd); + goto redo; + } else + goto fail; + } if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307) && location_changed == 1) { /* url moved, get next */ @@ -236,7 +254,9 @@ static int process_line(URLContext *h, char *line, int line_count, /* error codes are 4xx and 5xx, but regard 401 as a success, so we * don't abort until all headers have been parsed. */ - if (s->http_code >= 400 && s->http_code < 600 && s->http_code != 401) { + if (s->http_code >= 400 && s->http_code < 600 && (s->http_code != 401 + || s->auth_state.auth_type != HTTP_AUTH_NONE) && + (s->http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) { end += strspn(end, SPACE_CHARS); av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", s->http_code, end); @@ -277,6 +297,8 @@ static int process_line(URLContext *h, char *line, int line_count, ff_http_auth_handle_header(&s->auth_state, tag, p); } else if (!av_strcasecmp (tag, "Authentication-Info")) { ff_http_auth_handle_header(&s->auth_state, tag, p); + } else if (!av_strcasecmp (tag, "Proxy-Authenticate")) { + ff_http_auth_handle_header(&s->proxy_auth_state, tag, p); } else if (!av_strcasecmp (tag, "Connection")) { if (!strcmp(p, "close")) s->willclose = 1; @@ -293,22 +315,27 @@ static inline int has_header(const char *str, const char *header) return av_stristart(str, header + 2, NULL) || av_stristr(str, header); } -static int http_connect(URLContext *h, const char *path, const char *hoststr, - const char *auth, int *new_location) +static int http_connect(URLContext *h, const char *path, const char *local_path, + const char *hoststr, const char *auth, + const char *proxyauth, int *new_location) { HTTPContext *s = h->priv_data; int post, err; char line[1024]; char headers[1024] = ""; - char *authstr = NULL; + char *authstr = NULL, *proxyauthstr = NULL; int64_t off = s->off; int len = 0; + const char *method; /* send http header */ post = h->flags & AVIO_FLAG_WRITE; - authstr = ff_http_auth_create_response(&s->auth_state, auth, path, - post ? "POST" : "GET"); + method = post ? "POST" : "GET"; + authstr = ff_http_auth_create_response(&s->auth_state, auth, local_path, + method); + proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth, + local_path, method); /* set default headers if needed */ if (!has_header(s->headers, "\r\nUser-Agent: ")) @@ -336,14 +363,17 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr, "%s" "%s" "%s" + "%s%s" "\r\n", - post ? "POST" : "GET", + method, path, post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "", headers, - authstr ? authstr : ""); + authstr ? authstr : "", + proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : ""); av_freep(&authstr); + av_freep(&proxyauthstr); if (ffurl_write(s->hd, s->buffer, strlen(s->buffer)) < 0) return AVERROR(EIO); diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c index 58e0e82ed1..2ce5432993 100644 --- a/libavformat/httpauth.c +++ b/libavformat/httpauth.c @@ -87,7 +87,7 @@ static void choose_qop(char *qop, int size) void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, const char *value) { - if (!strcmp(key, "WWW-Authenticate")) { + if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) { const char *p; if (av_stristart(value, "Basic ", &p) && state->auth_type <= HTTP_AUTH_BASIC) { diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 20e5bd7e82..f264efe92e 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -426,7 +426,10 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam { if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE) return; /* Timestamp already set by depacketizer */ - if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && timestamp != RTP_NOTS_VALUE) { + if (timestamp == RTP_NOTS_VALUE) + return; + + if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { int64_t addend; int delta_timestamp; @@ -438,8 +441,7 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam delta_timestamp; return; } - if (timestamp == RTP_NOTS_VALUE) - return; + if (!s->base_timestamp) s->base_timestamp = timestamp; pkt->pts = s->range_start_offset + timestamp - s->base_timestamp; diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 1530128f4a..b05eb05249 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -70,6 +70,7 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) int header_size; int read_bitrate = 0; int size; + uint8_t comm_chunk[12]; if (!st) return AVERROR(ENOMEM); @@ -100,13 +101,13 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) switch(chunk_tag){ case MKTAG('C','O','M','M'): - st->codec->channels = avio_rb32(s->pb) + 1; - read_bitrate = avio_rb32(s->pb); - rate_flag = avio_rb32(s->pb); + avio_read(s->pb, comm_chunk, 12); + st->codec->channels = AV_RB32(comm_chunk ) + 1; + read_bitrate = AV_RB32(comm_chunk + 4); + rate_flag = AV_RB32(comm_chunk + 8); avio_skip(s->pb, len-12); st->codec->bit_rate = read_bitrate*1000; - st->codec->bits_per_coded_sample = 16; break; case MKTAG('N','A','M','E'): add_metadata(s, "title" , len, header_size); @@ -193,6 +194,12 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate; av_set_pts_info(st, 64, 1, st->codec->sample_rate); + /* put first 12 bytes of COMM chunk in extradata */ + if (!(st->codec->extradata = av_malloc(12 + FF_INPUT_BUFFER_PADDING_SIZE))) + return AVERROR(ENOMEM); + st->codec->extradata_size = 12; + memcpy(st->codec->extradata, comm_chunk, 12); + return 0; } diff --git a/libavutil/opt.c b/libavutil/opt.c index 0666a60d66..2421ee8bf1 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -55,9 +55,10 @@ const AVOption *av_next_option(void *obj, const AVOption *last) const AVOption *av_opt_next(void *obj, const AVOption *last) { - if (last && last[1].name) return ++last; - else if (last || !(*(AVClass**)obj)->option->name) return NULL; - else return (*(AVClass**)obj)->option; + AVClass *class = *(AVClass**)obj; + if (!last && class->option[0].name) return class->option; + if (last && last[1].name) return ++last; + return NULL; } static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum) |