zoukankan      html  css  js  c++  java
  • silk mpu

    #include "mpu.h"
    #include "mbuf.h"
    #include "media_buffer.h"
    #include "my_errno.h"
    #include "mem.h"
    #include "silk.h"
    #include "interface/SKP_Silk_SDK_API.h"
    
    struct silk_codec {
        void* obj;
        SKP_SILK_SDK_DecControlStruct control;
        uint64_t seq[2], pts;
    
        audio_format* fmt_out;
        intptr_t mbuf_handle;
        uint32_t bytes;
    };
    
    static void* silk_open(fourcc** in, fourcc** out)
    {
        SKP_int32 size;
        SKP_int n = SKP_Silk_SDK_Get_Decoder_Size(&size);
        if (n != 0) {
            errno = EFAULT;
            return NULL;
        }
    
        struct silk_codec* codec = (struct silk_codec *) my_malloc(size + sizeof(struct silk_codec));
        if (codec == NULL) {
            errno = ENOMEM;
            return NULL;
        }
        codec->obj = (void *) (codec + 1);
    
        n = SKP_Silk_SDK_InitDecoder(codec->obj);
        if (n != 0) {
            my_free(codec);
            errno = EFAULT;
            return NULL;
        }
    
        codec->seq[0] = codec->seq[1] = codec->pts = 0;
        codec->fmt_out = to_audio_format(out);
        codec->control.API_sampleRate = codec->fmt_out->pcm->samrate;
        fraction frac = pcm_bytes_from_ms(codec->fmt_out->pcm, 1);
        codec->bytes = silk_mpf * frac.num / frac.den;
        codec->mbuf_handle = mbuf_hget(sizeof(media_buffer) + codec->bytes, 8, 1);
        return codec;
    }
    
    static struct my_buffer* pcm_buffer_alloc(struct my_buffer* mbuf,
                                              uint32_t ms, media_buffer* stream, struct silk_codec* codec)
    {
        if (mbuf == NULL) {
            if (__builtin_expect(codec->mbuf_handle == -1, 0)) {
                uint32_t bytes = sizeof(media_buffer) + codec->bytes;
                codec->mbuf_handle = mbuf_hget(bytes, 8, 1);
                if (codec->mbuf_handle == -1) {
                    mbuf = mbuf_alloc_2(bytes);
                }
            } else {
                mbuf = mbuf_alloc_1(codec->mbuf_handle);
            }
    
            if (mbuf == NULL) {
                return NULL;
            }
            mbuf->length = codec->bytes;
            mbuf->ptr[1] = mbuf->ptr[0] + sizeof(media_buffer);
        }
    
        media_buffer* media = (media_buffer *) mbuf->ptr[0];
        memset(media->vp, 0, sizeof(media->vp));
        media->frametype = 0;
        media->angle = 0;
        media->fragment[0] = 0;
        media->fragment[1] = 1;
        media->pptr_cc = &codec->fmt_out->cc;
        media->pts = stream->pts + ms;
        media->iden = stream->iden;
        media->seq = codec->seq[0]++;
        media->vp[0].ptr = mbuf->ptr[1];
        media->vp[0].stride = (uint32_t) mbuf->length;
        media->vp[0].height = 1;
        return mbuf;
    }
    
    static uint32_t silk_muted(struct my_buffer* mbuf, uint32_t bytes)
    {
        uintptr_t nb = mbuf->length;
        mbuf->length = bytes;
        uint32_t muted = silk_frame_muted(mbuf);
        mbuf->length = nb;
        return muted;
    }
    
    static int32_t conceal_lost(media_buffer* stream, struct silk_codec* codec, struct list_head* head)
    {
        int32_t nr = (int32_t) (stream->seq - codec->seq[1]);
        if (codec->seq[1] == 0 || __builtin_expect(nr <= 0 || nr > 24, 1)) {
            return 0;
        }
    
        SKP_int16 nr_samples;
        uint64_t pts = stream->pts;
        stream->pts = codec->pts;
        uint32_t ms = 0, bytes = 0;
    
        for (int32_t i = 0; i < nr; ++i) {
            struct my_buffer* buffer = pcm_buffer_alloc(NULL, ms, stream, codec);
            if (buffer == NULL) {
                break;
            }
    
            SKP_Silk_SDK_Decode(codec->obj, &codec->control, 1,
                                NULL, 0, (SKP_int16 *) buffer->ptr[1], &nr_samples);
            my_assert(nr_samples * 2 == buffer->length);
            bytes += buffer->length;
            list_add_tail(&buffer->head, head);
            ms += silk_mpf;
        }
    
        stream->pts = pts;
        return bytes;
    }
    
    static int32_t silk_write(void* handle, struct my_buffer* mbuf, struct list_head* head, int32_t* delay)
    {
        (void) delay;
        if (__builtin_expect(mbuf == NULL, 0)) {
            return 0;
        }
    
        struct silk_codec* codec = (struct silk_codec *) handle;
        media_buffer* stream = (media_buffer *) mbuf->ptr[0];
        uint32_t ms = 0;
        SKP_int16 nr_samples;
        int32_t bytes = conceal_lost(stream, codec, head);
    
        while (mbuf->length > 0) {
            struct my_buffer* buffer = NULL;
            uint32_t muted = silk_muted(mbuf, silk_frame_leading);
    
            uint16_t len = silk_read_frame_bytes(mbuf->ptr[1]);
            mbuf->ptr[1] += silk_frame_leading;
            if (muted) {
                buffer = codec->fmt_out->ops->muted_frame_get(codec->fmt_out, silk_mpf);
                if (__builtin_expect(buffer != NULL, 1)) {
                    my_assert(buffer->length == codec->bytes);
                    bytes += buffer->length;
    
                    buffer = pcm_buffer_alloc(buffer, ms, stream, codec);
                    list_add_tail(&buffer->head, head);
                }
            } else {
                buffer = pcm_buffer_alloc(buffer, ms, stream, codec);
                if (__builtin_expect(buffer != NULL, 1)) {
                    SKP_Silk_SDK_Decode(codec->obj, &codec->control, 0,
                                        (const SKP_uint8 *) mbuf->ptr[1], (const SKP_int) len,
                                        (SKP_int16 *) buffer->ptr[1], &nr_samples);
                    bytes += nr_samples * 2;
                    list_add_tail(&buffer->head, head);
                }
            }
    
            mbuf->ptr[1] += len;
            mbuf->length -= (len + silk_frame_leading);
            ms += silk_mpf;
        }
    
        codec->seq[1] = stream->seq + 1;
        codec->pts = stream->pts + ms;
        my_assert(mbuf->length == 0);
        mbuf->mop->free(mbuf);
        return bytes;
    }
    
    static void silk_close(void* handle)
    {
        struct silk_codec* codec = (struct silk_codec *) handle;
        if (codec->mbuf_handle != -1) {
            mbuf_reap(codec->mbuf_handle);
        }
        my_free(codec);
    }
    
    static mpu_operation silk_ops = {
        silk_open,
        silk_write,
        silk_close
    };
    
    media_process_unit silk_dec_16k16b1 = {
        &silk_16k16b1.cc,
        &pcm_16k16b1.cc,
        &silk_ops,
        1,
        mpu_decoder,
        "silk_dec_16k16b1"
    };
    
    media_process_unit silk_dec_8k16b1 = {
        &silk_8k16b1.cc,
        &pcm_8k16b1.cc,
        &silk_ops,
        1,
        mpu_decoder,
        "silk_dec_8k16b1"
    };
    
  • 相关阅读:
    160309_Qt Essentials
    160309_Qt Reference Documentation
    160308_Signals & Slots
    160308_Helloworld_Gui Application
    网络爬虫(14)-动态页面爬取
    数据分析(6)-Pandas日期数据处理
    mysql基础(2)-excel功能在excel中如何实现?
    数据分析(5)-数据可视化常用图表类型和使用场景
    财经数据(6)-Python多进程爬虫东方财富个股盘口异动数据
    财经数据(5)-开盘啦股票标签数据爬虫
  • 原文地址:https://www.cnblogs.com/zylthinking/p/5975756.html
Copyright © 2011-2022 走看看