Revision 716ba2d0

View differences:

libavcodec/vmdav.c
456 456
}
457 457

  
458 458
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
459
    const uint8_t *buf, int stereo)
459
    const uint8_t *buf, int buf_size, int stereo)
460 460
{
461 461
    int i;
462 462
    int chan = 0;
463 463
    int16_t *out = (int16_t*)data;
464 464

  
465
    for(i = 0; i < s->block_align; i++) {
465
    for(i = 0; i < buf_size; i++) {
466 466
        if(buf[i] & 0x80)
467 467
            s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
468 468
        else
......
474 474
}
475 475

  
476 476
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
477
    const uint8_t *buf, int silence)
477
    const uint8_t *buf, int silence, int data_size)
478 478
{
479 479
    int bytes_decoded = 0;
480 480
    int i;
......
485 485

  
486 486
        /* stereo handling */
487 487
        if (silence) {
488
            memset(data, 0, s->block_align * 2);
488
            memset(data, 0, data_size * 2);
489 489
        } else {
490 490
            if (s->bits == 16)
491
                vmdaudio_decode_audio(s, data, buf, 1);
491
                vmdaudio_decode_audio(s, data, buf, data_size, 1);
492 492
            else {
493 493
                /* copy the data but convert it to signed */
494
                for (i = 0; i < s->block_align; i++){
494
                for (i = 0; i < data_size; i++){
495 495
                    *data++ = buf[i] + 0x80;
496 496
                    *data++ = buf[i] + 0x80;
497 497
                }
498 498
            }
499 499
        }
500 500
    } else {
501
        bytes_decoded = s->block_align * 2;
501
        bytes_decoded = data_size * 2;
502 502

  
503 503
        /* mono handling */
504 504
        if (silence) {
505
            memset(data, 0, s->block_align * 2);
505
            memset(data, 0, data_size * 2);
506 506
        } else {
507 507
            if (s->bits == 16) {
508
                vmdaudio_decode_audio(s, data, buf, 0);
508
                vmdaudio_decode_audio(s, data, buf, data_size, 0);
509 509
            } else {
510 510
                /* copy the data but convert it to signed */
511
                for (i = 0; i < s->block_align; i++){
511
                for (i = 0; i < data_size; i++){
512 512
                    *data++ = buf[i] + 0x80;
513 513
                    *data++ = buf[i] + 0x80;
514 514
                }
......
516 516
        }
517 517
    }
518 518

  
519
    return s->block_align * 2;
519
    return data_size * 2;
520 520
}
521 521

  
522 522
static int vmdaudio_decode_frame(AVCodecContext *avctx,
......
534 534

  
535 535
    if (buf[6] == 1) {
536 536
        /* the chunk contains audio */
537
        *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
537
        *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16);
538 538
    } else if (buf[6] == 2) {
539
        /* the chunk may contain audio */
540
        p += 4;
541
        *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
542
        output_samples += (s->block_align * s->bits / 8);
539
        /* initial chunk, may contain audio and silence */
540
        uint32_t flags = AV_RB32(p);
541
        int raw_block_size = s->block_align * s->bits / 8;
542
        int silent_chunks;
543
        if(flags == 0xFFFFFFFF)
544
            silent_chunks = 32;
545
        else
546
            silent_chunks = av_log2(flags + 1);
547
        if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2)
548
            return -1;
549
        *data_size = 0;
550
        memset(output_samples, 0, raw_block_size * silent_chunks);
551
        output_samples += raw_block_size * silent_chunks;
552
        *data_size = raw_block_size * silent_chunks;
553
        *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20);
543 554
    } else if (buf[6] == 3) {
544 555
        /* silent chunk */
545
        *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
556
        *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0);
546 557
    }
547 558

  
548 559
    return buf_size;
libavformat/sierravmd.c
193 193
            case 1: /* Audio Chunk */
194 194
                if (!st) break;
195 195
                /* first audio chunk contains several audio buffers */
196
                if(current_audio_pts){
197 196
                    vmd->frame_table[total_frames].frame_offset = current_offset;
198 197
                    vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
199 198
                    vmd->frame_table[total_frames].frame_size = size;
......
201 200
                    vmd->frame_table[total_frames].pts = current_audio_pts;
202 201
                    total_frames++;
203 202
                    current_audio_pts += pts_inc;
204
                }else{
205
                    uint32_t flags;
206
                    int k;
207
                    int noff;
208
                    int64_t pos;
209

  
210
                    pos = url_ftell(pb);
211
                    url_fseek(pb, current_offset, SEEK_SET);
212
                    flags = get_le32(pb);
213
                    noff = 4;
214
                    url_fseek(pb, pos, SEEK_SET);
215
                    av_log(s, AV_LOG_DEBUG, "Sound mapping = %08X (%i bufs)\n", flags, sound_buffers);
216
                    for(k = 0; k < sound_buffers - 1; k++){
217
                        if(flags & 1) { /* silent block */
218
                            vmd->frame_table[total_frames].frame_size = 0;
219
                        }else{
220
                            vmd->frame_table[total_frames].frame_size = st->codec->block_align + (st->codec->block_align & 1);
221
                        }
222
                        noff += vmd->frame_table[total_frames].frame_size;
223
                        vmd->frame_table[total_frames].frame_offset = current_offset + noff;
224
                        vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
225
                        memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
226
                        vmd->frame_table[total_frames].pts = current_audio_pts;
227
                        total_frames++;
228
                        current_audio_pts += pts_inc;
229
                        flags >>= 1;
230
                    }
231
                }
232 203
                break;
233 204
            case 2: /* Video Chunk */
234 205
                vmd->frame_table[total_frames].frame_offset = current_offset;

Also available in: Unified diff