* 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>tags/n0.9
| @@ -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); | |||
| } | |||
| @@ -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; | |||
| @@ -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*/); | |||
| @@ -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"); | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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, | |||
| @@ -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, \ | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| @@ -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') }, | |||
| @@ -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); | |||
| @@ -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) { | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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) | |||