1

我正在尝试编写一个 POC 来编码和解码往返 vorbis 的音频“往返”。

编码函数被传递了 88200 个字节(22050 个介于 -1.f 和 1.f 之间的浮点样本)。这些被一次复制到vorbis_analysis_buffer最多 1024 个样本。

根据libvorbis API 概述,并参考源中 /src 和 /examples 目录中的示例和测试文件,vorbis_analysis_wrote应将0作为值传递,以告知块写入器没有更多数据到来。这会导致段错误,我无法弄清楚为什么

顺便说一句,如果我只是省略对 的 0 值调用vorbis_analysis_wrote,则在输入缓冲区时不会输出任何数据(vorbis_analysis_blockout每次传递都返回 0)。

 int writeStreamToFile(vorbis_dsp_state *d, vorbis_block *b, ogg_stream_state *s, int samplecount, float *pcmbuffer, char *filename) {

    int i, ii, e = 0;
    int last = 0;
    int t = 0;
    FILE *f;
    char tmpfile[15] = "/tmp/vbsXXXXXX\0";
    ogg_packet op;
    int size_vorbis = L_VORBISBUFFERSIZE * L_RESOLUTION_BYTES;
    int size_data = samplecount * L_RESOLUTION_BYTES;

    mkstemp(tmpfile);

    f = fopen(tmpfile, "w");

    while (!last) {

        int size_units = 0;
        int size = size_data - t;

        if (size >= size_vorbis) {
            size = size_vorbis;
        } else {
            last = 1;
        }

        size_units = (int)(size / L_RESOLUTION_BYTES);

        float **encoding_buffer = vorbis_analysis_buffer(d, size_units);

        fprintf(stderr, "read iter %d pos %d size %d (%d units) / %d, starting at %p\n", i, t, size, size_units, size_data, pcmbuffer + (int)(t / L_RESOLUTION_BYTES));
        memcpy(encoding_buffer[0], pcmbuffer + (int)(t / L_RESOLUTION_BYTES), (size_t)size);

        if ((e = vorbis_analysis_wrote(d, size_units))) {
            return -1;
        }
        if (last) {
            float *src = pcmbuffer + ((t + size) / L_RESOLUTION_BYTES) - L_RESOLUTION_BYTES;
            float *dst = *encoding_buffer + (size / L_RESOLUTION_BYTES) - L_RESOLUTION_BYTES;
            fprintf(stderr, "last copied byte is src: %f at %p, dst: %f at %p\n", *src, src, *dst, dst);
            vorbis_analysis_wrote(d, 0);  
        } 

        // remove this when debugging is over
        if (memcmp(encoding_buffer[0], pcmbuffer + (int)(t / L_RESOLUTION_BYTES), (size_t)size)) {
            return -1;      
        }

        while (vorbis_analysis_blockout(d, b) == 1) {

            if ((e = vorbis_analysis(b, NULL))) {
                return -1;
            }

            if ((e = vorbis_bitrate_addblock(b))) {
                return -1;
            }

            vorbis_bitrate_flushpacket(d, &op); 
            fprintf(stderr, "Packet #%i (%p) got %li bytes\n", ii, op.packet, op.bytes);
            fwrite(op.packet, sizeof(char), op.bytes, f);
            ii++;
        }

        t += size;
        i++;
    }

    fclose(f);

    strcpy(filename, tmpfile);

    return t;
 }

运行结果:

 (gdb) r
 Starting program: /home/lash/programming/projects/p2pconference/bin/vorbisroundtrip 
 ogg stream output 7912 bytes in headerdata
 Created 22050 samples of 4 bytes, last sample is -0.248100 at 0x619888
 read iter 0 pos 0 size 4096 (1024 units) / 88200, starting at 0x604010
 read iter 1 pos 4096 size 4096 (1024 units) / 88200, starting at 0x605010
 read iter 2 pos 8192 size 4096 (1024 units) / 88200, starting at 0x606010
 read iter 3 pos 12288 size 4096 (1024 units) / 88200, starting at 0x607010
 read iter 4 pos 16384 size 4096 (1024 units) / 88200, starting at 0x608010
 read iter 5 pos 20480 size 4096 (1024 units) / 88200, starting at 0x609010
 read iter 6 pos 24576 size 4096 (1024 units) / 88200, starting at 0x60a010
 read iter 7 pos 28672 size 4096 (1024 units) / 88200, starting at 0x60b010
 read iter 8 pos 32768 size 4096 (1024 units) / 88200, starting at 0x60c010
 read iter 9 pos 36864 size 4096 (1024 units) / 88200, starting at 0x60d010
 read iter 10 pos 40960 size 4096 (1024 units) / 88200, starting at 0x60e010
 read iter 11 pos 45056 size 4096 (1024 units) / 88200, starting at 0x60f010
 read iter 12 pos 49152 size 4096 (1024 units) / 88200, starting at 0x610010
 read iter 13 pos 53248 size 4096 (1024 units) / 88200, starting at 0x611010
 read iter 14 pos 57344 size 4096 (1024 units) / 88200, starting at 0x612010
 read iter 15 pos 61440 size 4096 (1024 units) / 88200, starting at 0x613010
 read iter 16 pos 65536 size 4096 (1024 units) / 88200, starting at 0x614010
 read iter 17 pos 69632 size 4096 (1024 units) / 88200, starting at 0x615010
 read iter 18 pos 73728 size 4096 (1024 units) / 88200, starting at 0x616010
 read iter 19 pos 77824 size 4096 (1024 units) / 88200, starting at 0x617010
 read iter 20 pos 81920 size 4096 (1024 units) / 88200, starting at 0x618010
 read iter 21 pos 86016 size 2184 (546 units) / 88200, starting at 0x619010
 last copied byte is src: -0.248100 at 0x619888, dst: -0.248100 at 0x688d18

 Program received signal SIGSEGV, Segmentation fault.
 0x00007ffff78ad228 in vorbis_lpc_from_data () from /usr/lib/x86_64-linux-gnu/libvorbis.so.0

内存映射和堆栈转储:

 (gdb) bt
 #0  0x00007ffff78ad228 in vorbis_lpc_from_data () from /usr/lib/x86_64-linux-gnu/libvorbis.so.0
 #1  0x00007ffff78aaa60 in vorbis_analysis_wrote () from /usr/lib/x86_64-linux-gnu/libvorbis.so.0
 #2  0x00000000004019b5 in writeStreamToFile (d=0x603840 <vdsp_e>, b=0x603380 <vblk_e>, s=0x6031a0 <os_e>, samplecount=22050, pcmbuffer=0x604010, 
     filename=0x7fffffffdf60 "0 @") at ./tests/vorbisroundtrip.c:131
 #3  0x0000000000401ee3 in main (argc=1, argv=0x7fffffffe068) at ./tests/vorbisroundtrip.c:243

 (gdb) info proc map
 process 28458
 Mapped address spaces:

           Start Addr           End Addr       Size     Offset objfile
             0x400000           0x403000     0x3000        0x0 /home/lash/programming/projects/p2pconference/bin/vorbisroundtrip
             0x602000           0x603000     0x1000     0x2000 /home/lash/programming/projects/p2pconference/bin/vorbisroundtrip
             0x603000           0x604000     0x1000     0x3000 /home/lash/programming/projects/p2pconference/bin/vorbisroundtrip
             0x604000           0x69d000    0x99000        0x0 [heap]
       0x7ffff0000000     0x7ffff0021000    0x21000        0x0 
       0x7ffff0021000     0x7ffff4000000  0x3fdf000        0x0 
       0x7ffff7027000     0x7ffff71e6000   0x1bf000        0x0 /lib/x86_64-linux-gnu/libc-2.23.so
       0x7ffff71e6000     0x7ffff73e6000   0x200000   0x1bf000 /lib/x86_64-linux-gnu/libc-2.23.so
       0x7ffff73e6000     0x7ffff73ea000     0x4000   0x1bf000 /lib/x86_64-linux-gnu/libc-2.23.so
       0x7ffff73ea000     0x7ffff73ec000     0x2000   0x1c3000 /lib/x86_64-linux-gnu/libc-2.23.so
       0x7ffff73ec000     0x7ffff73f0000     0x4000        0x0 
       0x7ffff73f0000     0x7ffff73f7000     0x7000        0x0 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.2
       0x7ffff73f7000     0x7ffff75f7000   0x200000     0x7000 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.2
       0x7ffff75f7000     0x7ffff75f8000     0x1000     0x7000 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.2
       0x7ffff75f8000     0x7ffff75f9000     0x1000     0x8000 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.2
       0x7ffff75f9000     0x7ffff7686000    0x8d000        0x0 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.11
       0x7ffff7686000     0x7ffff7885000   0x1ff000    0x8d000 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.11
       0x7ffff7885000     0x7ffff78a1000    0x1c000    0x8c000 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.11
       0x7ffff78a1000     0x7ffff78a2000     0x1000    0xa8000 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.11
       0x7ffff78a2000     0x7ffff78cc000    0x2a000        0x0 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.8
       0x7ffff78cc000     0x7ffff7acc000   0x200000    0x2a000 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.8
       0x7ffff7acc000     0x7ffff7acd000     0x1000    0x2a000 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.8
       0x7ffff7acd000     0x7ffff7ace000     0x1000    0x2b000 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.8
       0x7ffff7ace000     0x7ffff7bd6000   0x108000        0x0 /lib/x86_64-linux-gnu/libm-2.23.so
       0x7ffff7bd6000     0x7ffff7dd5000   0x1ff000   0x108000 /lib/x86_64-linux-gnu/libm-2.23.so
       0x7ffff7dd5000     0x7ffff7dd6000     0x1000   0x107000 /lib/x86_64-linux-gnu/libm-2.23.so
       0x7ffff7dd6000     0x7ffff7dd7000     0x1000   0x108000 /lib/x86_64-linux-gnu/libm-2.23.so
       0x7ffff7dd7000     0x7ffff7dfd000    0x26000        0x0 /lib/x86_64-linux-gnu/ld-2.23.so
       0x7ffff7fb5000     0x7ffff7fba000     0x5000        0x0 
       0x7ffff7ff6000     0x7ffff7ff8000     0x2000        0x0 
       0x7ffff7ff8000     0x7ffff7ffa000     0x2000        0x0 [vvar]
       0x7ffff7ffa000     0x7ffff7ffc000     0x2000        0x0 [vdso]
       0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x25000 /lib/x86_64-linux-gnu/ld-2.23.so
       0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x26000 /lib/x86_64-linux-gnu/ld-2.23.so
       0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0 
       0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
   0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]

可以在此处查看完整的进行中的源代码。音频数据在这里(原始 pcm)

使用:

  • libvorbis 1.3.5
  • gcc 5.4.0
  • linux 4.4.0-45-通用

ldd:

linux-vdso.so.1 =>  (0x00007ffe7afa9000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f30a9c70000)
libvorbis.so.0 => /home/lash/src/libvorbis-1.3.5/build/lib/libvorbis.so.0 (0x00007f30a9a37000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f30a978d000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f30a9584000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f30a91bb000)
/lib64/ld-linux-x86-64.so.2 (0x0000560df33a6000)
4

0 回答 0