* qatar/master: ppc: fix some pointer to integer casts ppc: fix 32-bit PIC build vmdaudio: fix decoding of 16-bit audio format. lavf: do not set codec_tag for rawvideo h264: check for out of bounds reads in ff_h264_decode_extradata(). flvdec: Check for overflow before allocating arrays avconv: use correct output stream index when checking max_frames avconv: remove fake coded_frame on streamcopy hack Conflicts: avconv.c libavcodec/h264.c libavcodec/ppc/asm.S libavcodec/vmdav.c libavformat/flvdec.c libavformat/utils.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
| @@ -1826,7 +1826,6 @@ static int output_packet(InputStream *ist, int ist_index, | |||||
| abort(); | abort(); | ||||
| } | } | ||||
| } else { | } else { | ||||
| AVFrame avframe; //FIXME/XXX remove this | |||||
| AVPicture pict; | AVPicture pict; | ||||
| AVPacket opkt; | AVPacket opkt; | ||||
| int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); | int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); | ||||
| @@ -1842,10 +1841,6 @@ static int output_packet(InputStream *ist, int ist_index, | |||||
| /* no reencoding needed : output the packet directly */ | /* no reencoding needed : output the packet directly */ | ||||
| /* force the input stream PTS */ | /* force the input stream PTS */ | ||||
| avcodec_get_frame_defaults(&avframe); | |||||
| ost->st->codec->coded_frame= &avframe; | |||||
| avframe.key_frame = pkt->flags & AV_PKT_FLAG_KEY; | |||||
| if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) | if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) | ||||
| audio_size += data_size; | audio_size += data_size; | ||||
| else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { | else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { | ||||
| @@ -2455,8 +2450,8 @@ static int transcode(OutputFile *output_files, | |||||
| } | } | ||||
| if (ost->frame_number >= ost->max_frames) { | if (ost->frame_number >= ost->max_frames) { | ||||
| int j; | int j; | ||||
| for (j = of->ost_index; j < of->ctx->nb_streams; j++) | |||||
| output_streams[j].is_past_recording_time = 1; | |||||
| for (j = 0; j < of->ctx->nb_streams; j++) | |||||
| output_streams[of->ost_index + j].is_past_recording_time = 1; | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1845,7 +1845,6 @@ static int output_packet(InputStream *ist, int ist_index, | |||||
| abort(); | abort(); | ||||
| } | } | ||||
| } else { | } else { | ||||
| AVFrame avframe; //FIXME/XXX remove this | |||||
| AVPicture pict; | AVPicture pict; | ||||
| AVPacket opkt; | AVPacket opkt; | ||||
| int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); | int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); | ||||
| @@ -1861,10 +1860,6 @@ static int output_packet(InputStream *ist, int ist_index, | |||||
| /* no reencoding needed : output the packet directly */ | /* no reencoding needed : output the packet directly */ | ||||
| /* force the input stream PTS */ | /* force the input stream PTS */ | ||||
| avcodec_get_frame_defaults(&avframe); | |||||
| ost->st->codec->coded_frame= &avframe; | |||||
| avframe.key_frame = pkt->flags & AV_PKT_FLAG_KEY; | |||||
| if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) | if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) | ||||
| audio_size += data_size; | audio_size += data_size; | ||||
| else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { | else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { | ||||
| @@ -2503,8 +2498,8 @@ static int transcode(OutputFile *output_files, int nb_output_files, | |||||
| } | } | ||||
| if (ost->frame_number >= ost->max_frames) { | if (ost->frame_number >= ost->max_frames) { | ||||
| int j; | int j; | ||||
| for (j = of->ost_index; j < of->ctx->nb_streams; j++) | |||||
| output_streams[j].is_past_recording_time = 1; | |||||
| for (j = 0; j < of->ctx->nb_streams; j++) | |||||
| output_streams[of->ost_index + j].is_past_recording_time = 1; | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| @@ -44,10 +44,13 @@ X(\name): | |||||
| L(\name): | L(\name): | ||||
| .endm | .endm | ||||
| .macro movrel rd, sym | |||||
| .macro movrel rd, sym, gp | |||||
| ld \rd, \sym@got(r2) | ld \rd, \sym@got(r2) | ||||
| .endm | .endm | ||||
| .macro get_got rd | |||||
| .endm | |||||
| #else /* ARCH_PPC64 */ | #else /* ARCH_PPC64 */ | ||||
| #define PTR .int | #define PTR .int | ||||
| @@ -65,19 +68,25 @@ X(\name): | |||||
| \name: | \name: | ||||
| .endm | .endm | ||||
| .macro movrel rd, sym | |||||
| .macro movrel rd, sym, gp | |||||
| #if CONFIG_PIC | #if CONFIG_PIC | ||||
| bcl 20, 31, lab_pic_\@ | |||||
| lab_pic_\@: | |||||
| mflr \rd | |||||
| addis \rd, \rd, (\sym - lab_pic_\@)@ha | |||||
| addi \rd, \rd, (\sym - lab_pic_\@)@l | |||||
| lwz \rd, \sym@got(\gp) | |||||
| #else | #else | ||||
| lis \rd, \sym@ha | lis \rd, \sym@ha | ||||
| la \rd, \sym@l(\rd) | la \rd, \sym@l(\rd) | ||||
| #endif | #endif | ||||
| .endm | .endm | ||||
| .macro get_got rd | |||||
| #if CONFIG_PIC | |||||
| bcl 20, 31, .Lgot\@ | |||||
| .Lgot\@: | |||||
| mflr \rd | |||||
| addis \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@ha | |||||
| addi \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@l | |||||
| #endif | |||||
| .endm | |||||
| #endif /* ARCH_PPC64 */ | #endif /* ARCH_PPC64 */ | ||||
| #if HAVE_IBM_ASM | #if HAVE_IBM_ASM | ||||
| @@ -353,6 +353,7 @@ extfunc ff_fft_calc\interleave\()_altivec | |||||
| mflr r0 | mflr r0 | ||||
| stp r0, 2*PS(r1) | stp r0, 2*PS(r1) | ||||
| stpu r1, -(160+16*PS)(r1) | stpu r1, -(160+16*PS)(r1) | ||||
| get_got r11 | |||||
| addi r6, r1, 16*PS | addi r6, r1, 16*PS | ||||
| stvm r6, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 | stvm r6, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 | ||||
| mfvrsave r0 | mfvrsave r0 | ||||
| @@ -360,14 +361,14 @@ extfunc ff_fft_calc\interleave\()_altivec | |||||
| li r6, 0xfffffffc | li r6, 0xfffffffc | ||||
| mtvrsave r6 | mtvrsave r6 | ||||
| movrel r6, fft_data | |||||
| movrel r6, fft_data, r11 | |||||
| lvm r6, v14, v15, v16, v17, v18, v19, v20, v21 | lvm r6, v14, v15, v16, v17, v18, v19, v20, v21 | ||||
| lvm r6, v22, v23, v24, v25, v26, v27, v28, v29 | lvm r6, v22, v23, v24, v25, v26, v27, v28, v29 | ||||
| li r9, 16 | li r9, 16 | ||||
| movrel r12, X(ff_cos_tabs) | |||||
| movrel r12, X(ff_cos_tabs), r11 | |||||
| movrel r6, fft_dispatch_tab\interleave\()_altivec | |||||
| movrel r6, fft_dispatch_tab\interleave\()_altivec, r11 | |||||
| lwz r3, 0(r3) | lwz r3, 0(r3) | ||||
| subi r3, r3, 2 | subi r3, r3, 2 | ||||
| slwi r3, r3, 2+ARCH_PPC64 | slwi r3, r3, 2+ARCH_PPC64 | ||||
| @@ -465,9 +465,8 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) | |||||
| #define BLOCK_TYPE_SILENCE 3 | #define BLOCK_TYPE_SILENCE 3 | ||||
| typedef struct VmdAudioContext { | typedef struct VmdAudioContext { | ||||
| AVCodecContext *avctx; | |||||
| int out_bps; | int out_bps; | ||||
| int predictors[2]; | |||||
| int chunk_size; | |||||
| } VmdAudioContext; | } VmdAudioContext; | ||||
| static const uint16_t vmdaudio_table[128] = { | static const uint16_t vmdaudio_table[128] = { | ||||
| @@ -490,13 +489,23 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) | |||||
| { | { | ||||
| VmdAudioContext *s = avctx->priv_data; | VmdAudioContext *s = avctx->priv_data; | ||||
| s->avctx = avctx; | |||||
| if (avctx->channels < 1 || avctx->channels > 2) { | |||||
| av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n"); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| if (avctx->block_align < 1) { | |||||
| av_log(avctx, AV_LOG_ERROR, "invalid block align\n"); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| if (avctx->bits_per_coded_sample == 16) | if (avctx->bits_per_coded_sample == 16) | ||||
| avctx->sample_fmt = AV_SAMPLE_FMT_S16; | avctx->sample_fmt = AV_SAMPLE_FMT_S16; | ||||
| else | else | ||||
| avctx->sample_fmt = AV_SAMPLE_FMT_U8; | avctx->sample_fmt = AV_SAMPLE_FMT_U8; | ||||
| s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt); | s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt); | ||||
| s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2); | |||||
| av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " | av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " | ||||
| "block align = %d, sample rate = %d\n", | "block align = %d, sample rate = %d\n", | ||||
| avctx->channels, avctx->bits_per_coded_sample, avctx->block_align, | avctx->channels, avctx->bits_per_coded_sample, avctx->block_align, | ||||
| @@ -505,41 +514,33 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, | |||||
| const uint8_t *buf, int buf_size, int stereo) | |||||
| static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size, | |||||
| int channels) | |||||
| { | { | ||||
| int i; | |||||
| int chan = 0; | |||||
| int16_t *out = (int16_t*)data; | |||||
| for(i = 0; i < buf_size; i++) { | |||||
| if(buf[i] & 0x80) | |||||
| s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; | |||||
| else | |||||
| s->predictors[chan] += vmdaudio_table[buf[i]]; | |||||
| s->predictors[chan] = av_clip_int16(s->predictors[chan]); | |||||
| out[i] = s->predictors[chan]; | |||||
| chan ^= stereo; | |||||
| int ch; | |||||
| const uint8_t *buf_end = buf + buf_size; | |||||
| int predictor[2]; | |||||
| int st = channels - 1; | |||||
| /* decode initial raw sample */ | |||||
| for (ch = 0; ch < channels; ch++) { | |||||
| predictor[ch] = (int16_t)AV_RL16(buf); | |||||
| buf += 2; | |||||
| *out++ = predictor[ch]; | |||||
| } | } | ||||
| } | |||||
| static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, | |||||
| const uint8_t *buf, int silent_chunks, int data_size) | |||||
| { | |||||
| int silent_size = s->avctx->block_align * silent_chunks * s->out_bps; | |||||
| if (silent_chunks) { | |||||
| memset(data, s->out_bps == 2 ? 0x00 : 0x80, silent_size); | |||||
| data += silent_size; | |||||
| } | |||||
| if (s->avctx->bits_per_coded_sample == 16) | |||||
| vmdaudio_decode_audio(s, data, buf, data_size, s->avctx->channels == 2); | |||||
| else { | |||||
| /* just copy the data */ | |||||
| memcpy(data, buf, data_size); | |||||
| /* decode DPCM samples */ | |||||
| ch = 0; | |||||
| while (buf < buf_end) { | |||||
| uint8_t b = *buf++; | |||||
| if (b & 0x80) | |||||
| predictor[ch] -= vmdaudio_table[b & 0x7F]; | |||||
| else | |||||
| predictor[ch] += vmdaudio_table[b]; | |||||
| predictor[ch] = av_clip_int16(predictor[ch]); | |||||
| *out++ = predictor[ch]; | |||||
| ch ^= st; | |||||
| } | } | ||||
| return silent_size + data_size * s->out_bps; | |||||
| } | } | ||||
| static int vmdaudio_decode_frame(AVCodecContext *avctx, | static int vmdaudio_decode_frame(AVCodecContext *avctx, | ||||
| @@ -547,10 +548,13 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, | |||||
| AVPacket *avpkt) | AVPacket *avpkt) | ||||
| { | { | ||||
| const uint8_t *buf = avpkt->data; | const uint8_t *buf = avpkt->data; | ||||
| const uint8_t *buf_end; | |||||
| int buf_size = avpkt->size; | int buf_size = avpkt->size; | ||||
| VmdAudioContext *s = avctx->priv_data; | VmdAudioContext *s = avctx->priv_data; | ||||
| int block_type, silent_chunks; | |||||
| unsigned char *output_samples = (unsigned char *)data; | |||||
| int block_type, silent_chunks, audio_chunks; | |||||
| int nb_samples, out_size; | |||||
| uint8_t *output_samples_u8 = data; | |||||
| int16_t *output_samples_s16 = data; | |||||
| if (buf_size < 16) { | if (buf_size < 16) { | ||||
| av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n"); | av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n"); | ||||
| @@ -566,13 +570,16 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, | |||||
| buf += 16; | buf += 16; | ||||
| buf_size -= 16; | buf_size -= 16; | ||||
| /* get number of silent chunks */ | |||||
| silent_chunks = 0; | silent_chunks = 0; | ||||
| if (block_type == BLOCK_TYPE_INITIAL) { | if (block_type == BLOCK_TYPE_INITIAL) { | ||||
| uint32_t flags; | uint32_t flags; | ||||
| if (buf_size < 4) | |||||
| return -1; | |||||
| flags = AV_RB32(buf); | |||||
| silent_chunks = av_popcount(flags); | |||||
| if (buf_size < 4) { | |||||
| av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| flags = AV_RB32(buf); | |||||
| silent_chunks = av_popcount(flags); | |||||
| buf += 4; | buf += 4; | ||||
| buf_size -= 4; | buf_size -= 4; | ||||
| } else if (block_type == BLOCK_TYPE_SILENCE) { | } else if (block_type == BLOCK_TYPE_SILENCE) { | ||||
| @@ -581,11 +588,41 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, | |||||
| } | } | ||||
| /* ensure output buffer is large enough */ | /* ensure output buffer is large enough */ | ||||
| if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps) | |||||
| audio_chunks = buf_size / s->chunk_size; | |||||
| nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels; | |||||
| out_size = nb_samples * avctx->channels * s->out_bps; | |||||
| if (*data_size < out_size) | |||||
| return -1; | return -1; | ||||
| *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size); | |||||
| /* decode silent chunks */ | |||||
| if (silent_chunks > 0) { | |||||
| int silent_size = avctx->block_align * silent_chunks; | |||||
| if (s->out_bps == 2) { | |||||
| memset(output_samples_s16, 0x00, silent_size * 2); | |||||
| output_samples_s16 += silent_size; | |||||
| } else { | |||||
| memset(output_samples_u8, 0x80, silent_size); | |||||
| output_samples_u8 += silent_size; | |||||
| } | |||||
| } | |||||
| /* decode audio chunks */ | |||||
| if (audio_chunks > 0) { | |||||
| buf_end = buf + buf_size; | |||||
| while (buf < buf_end) { | |||||
| if (s->out_bps == 2) { | |||||
| decode_audio_s16(output_samples_s16, buf, s->chunk_size, | |||||
| avctx->channels); | |||||
| output_samples_s16 += avctx->block_align; | |||||
| } else { | |||||
| memcpy(output_samples_u8, buf, s->chunk_size); | |||||
| output_samples_u8 += avctx->block_align; | |||||
| } | |||||
| buf += s->chunk_size; | |||||
| } | |||||
| } | |||||
| *data_size = out_size; | |||||
| return avpkt->size; | return avpkt->size; | ||||
| } | } | ||||
| @@ -242,7 +242,7 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW, | |||||
| vector unsigned char src_v1, src_vF; | vector unsigned char src_v1, src_vF; | ||||
| vector signed short src_v, filter_v; | vector signed short src_v, filter_v; | ||||
| vector signed int val_vEven, val_s; | vector signed int val_vEven, val_s; | ||||
| if ((((int)src + srcPos)% 16) > 12) { | |||||
| if ((((uintptr_t)src + srcPos) % 16) > 12) { | |||||
| src_v1 = vec_ld(srcPos + 16, src); | src_v1 = vec_ld(srcPos + 16, src); | ||||
| } | } | ||||
| src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); | src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); | ||||
| @@ -281,7 +281,7 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW, | |||||
| vector unsigned char src_v1, src_vF; | vector unsigned char src_v1, src_vF; | ||||
| vector signed short src_v, filter_v; | vector signed short src_v, filter_v; | ||||
| vector signed int val_v, val_s; | vector signed int val_v, val_s; | ||||
| if ((((int)src + srcPos)% 16) > 8) { | |||||
| if ((((uintptr_t)src + srcPos) % 16) > 8) { | |||||
| src_v1 = vec_ld(srcPos + 16, src); | src_v1 = vec_ld(srcPos + 16, src); | ||||
| } | } | ||||
| src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); | src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); | ||||
| @@ -367,7 +367,7 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW, | |||||
| //vector unsigned char src_v0 = vec_ld(srcPos + j, src); | //vector unsigned char src_v0 = vec_ld(srcPos + j, src); | ||||
| vector unsigned char src_v1, src_vF; | vector unsigned char src_v1, src_vF; | ||||
| vector signed short src_v, filter_v1R, filter_v; | vector signed short src_v, filter_v1R, filter_v; | ||||
| if ((((int)src + srcPos)% 16) > 8) { | |||||
| if ((((uintptr_t)src + srcPos) % 16) > 8) { | |||||
| src_v1 = vec_ld(srcPos + j + 16, src); | src_v1 = vec_ld(srcPos + j + 16, src); | ||||
| } | } | ||||
| src_vF = vec_perm(src_v0, src_v1, permS); | src_vF = vec_perm(src_v0, src_v1, permS); | ||||