#include"node.h" #include #include #include"img.h" #include #include struct CHiEncodeOpusNode { CHiPubNode pubn; size_t pcmSamples, pcmCapacity; int16_t *pcmbuf; size_t timestamp; OpusEncoder *enc; }; static int encodeopus_perform(CHiPubNode *pubn) { struct CHiEncodeOpusNode *n = (struct CHiEncodeOpusNode*) pubn; CHiImage *newpcm = CHi_Crawl(&pubn->sinks[0])->data.sample; if(n->pcmSamples + newpcm->width > n->pcmCapacity) { n->pcmbuf = realloc(n->pcmbuf, sizeof(*n->pcmbuf) * (n->pcmCapacity = ((n->pcmSamples + newpcm->width + 1023) & ~1023))); } memcpy(&n->pcmbuf[n->pcmSamples], newpcm->data16, sizeof(*n->pcmbuf) * newpcm->width); n->pcmSamples += newpcm->width; CHiBSFrames *frames = malloc(sizeof(*frames)); frames->count = 0; size_t samp; for(samp = 0; samp + 960 <= n->pcmSamples; samp += 960) { frames = realloc(frames, sizeof(*frames) + sizeof(*frames->data) * (frames->count + 1)); frames->data[frames->count].timestamp = n->timestamp; frames->data[frames->count].ptr = malloc(1276); frames->data[frames->count].sz = opus_encode(n->enc, &n->pcmbuf[samp], 960, frames->data[frames->count].ptr, 1276); if(frames->data[frames->count].sz < 0) puts("OPUS ERR"); frames->count++; n->timestamp += 20; } memmove(n->pcmbuf, n->pcmbuf + samp, sizeof(*n->pcmbuf) * (n->pcmSamples - samp)); n->pcmSamples -= samp; pubn->sources[0].type = CUTIHI_VAL_OPUSBS; pubn->sources[0].data.bitstream = frames; return 1; } CUTIVIS CHiPubNode *CHi_EncodeOpus() { struct CHiEncodeOpusNode *ret = calloc(1, sizeof(*ret)); ret->pubn.type = CUTIHI_T('CEnc','Opus'); ret->pubn.Start = CHi_EncodeOpus_Start; ret->pubn.Perform = &encodeopus_perform; ret->pubn.Stop = CHi_EncodeOpus_Stop; ret->pubn.clean = 0; ret->pubn.sinks = calloc(sizeof(*ret->pubn.sinks), ret->pubn.sinkCount = 1); ret->pubn.sources = calloc(sizeof(*ret->pubn.sources), ret->pubn.sourceCount = 1); return &ret->pubn; } CUTIVIS int CHi_EncodeOpus_Start(CHiPubNode *pubn) { struct CHiEncodeOpusNode *n = (struct CHiEncodeOpusNode*) pubn; int error; n->enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &error); n->pcmSamples = 0; n->pcmCapacity = 1024; n->pcmbuf = malloc(sizeof(*n->pcmbuf) * n->pcmCapacity); n->timestamp = 0; return 1; } CUTIVIS int CHi_EncodeOpus_Stop(CHiPubNode *pubn) { struct CHiEncodeOpusNode *n = (struct CHiEncodeOpusNode*) pubn; opus_encoder_destroy(n->enc); free(n->pcmbuf); return 1; }