Просмотр исходного кода

Merge remote-tracking branch 'qatar/master'

* 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>
Michael Niedermayer 13 лет назад
Родитель
Сommit
537a9e5cc2
6 измененных файлов с 106 добавлено и 69 удалено
  1. 2 7
      avconv.c
  2. 2 7
      ffmpeg.c
  3. 16 7
      libavcodec/ppc/asm.S
  4. 4 3
      libavcodec/ppc/fft_altivec_s.S
  5. 79 42
      libavcodec/vmdav.c
  6. 3 3
      libswscale/ppc/swscale_altivec.c

+ 2 - 7
avconv.c

@@ -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;
             }
             }
         }
         }

+ 2 - 7
ffmpeg.c

@@ -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;
             }
             }
         }
         }

+ 16 - 7
libavcodec/ppc/asm.S

@@ -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

+ 4 - 3
libavcodec/ppc/fft_altivec_s.S

@@ -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

+ 79 - 42
libavcodec/vmdav.c

@@ -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;
 }
 }
 
 

+ 3 - 3
libswscale/ppc/swscale_altivec.c

@@ -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);