static int opus_multistream_packet_validate(const unsigned char *data, opus_int32 len, int nb_streams, opus_int32 Fs) { int s; int count; unsigned char toc; opus_int16 size[48]; int samples=0; opus_int32 packet_offset; for (s=0;s<nb_streams;s++) { int tmp_samples; if (len<=0) return OPUS_INVALID_PACKET; count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL, size, NULL, &packet_offset); if (count<0) return count; tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs); if (s!=0 && samples != tmp_samples) return OPUS_INVALID_PACKET; samples = tmp_samples; data += packet_offset; len -= packet_offset; } return samples; }
virtual bool Transcode(const void * fromPtr, unsigned & fromLen, void * toPtr, unsigned & toLen, unsigned & flags) { opus_int32 result = opus_encode(m_encoder, (const opus_int16 *)fromPtr, fromLen/m_channels/2, (unsigned char *)toPtr, toLen); if (result < 0) { PTRACE(1, MY_CODEC_LOG, "Encoder error " << result << ' ' << opus_strerror(result)); return false; } toLen = result; fromLen = opus_packet_get_nb_samples((const unsigned char *)toPtr, toLen, m_sampleRate)*m_channels*2; return true; }
/** * Output debug information regarding the state of a single Opus packet */ void DebugFrameInfoInternal(const uint8* PacketData, uint32 PacketLength, uint32 SampleRate, bool bEncode) { int32 NumFrames = opus_packet_get_nb_frames(PacketData, PacketLength); if (NumFrames == OPUS_BAD_ARG || NumFrames == OPUS_INVALID_PACKET) { UE_LOG(LogVoice, Warning, TEXT("opus_packet_get_nb_frames: Invalid voice packet data!")); } int32 NumSamples = opus_packet_get_nb_samples(PacketData, PacketLength, SampleRate); if (NumSamples == OPUS_BAD_ARG || NumSamples == OPUS_INVALID_PACKET) { UE_LOG(LogVoice, Warning, TEXT("opus_packet_get_nb_samples: Invalid voice packet data!")); } int32 NumSamplesPerFrame = opus_packet_get_samples_per_frame(PacketData, SampleRate); int32 Bandwidth = opus_packet_get_bandwidth(PacketData); const TCHAR* BandwidthStr = NULL; switch (Bandwidth) { case OPUS_BANDWIDTH_NARROWBAND: // Narrowband (4kHz bandpass) BandwidthStr = TEXT("NB"); break; case OPUS_BANDWIDTH_MEDIUMBAND: // Mediumband (6kHz bandpass) BandwidthStr = TEXT("MB"); break; case OPUS_BANDWIDTH_WIDEBAND: // Wideband (8kHz bandpass) BandwidthStr = TEXT("WB"); break; case OPUS_BANDWIDTH_SUPERWIDEBAND: // Superwideband (12kHz bandpass) BandwidthStr = TEXT("SWB"); break; case OPUS_BANDWIDTH_FULLBAND: // Fullband (20kHz bandpass) BandwidthStr = TEXT("FB"); break; case OPUS_INVALID_PACKET: default: BandwidthStr = TEXT("Invalid"); break; } /* * 0 * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ * | config |s| c | * +-+-+-+-+-+-+-+-+ */ uint8 TOC; // (max 48 x 2.5ms frames in a packet = 120ms) const uint8* frames[48]; int16 size[48]; int32 payload_offset = 0; int32 NumFramesParsed = opus_packet_parse(PacketData, PacketLength, &TOC, frames, size, &payload_offset); // Frame Encoding see http://tools.ietf.org/html/rfc6716#section-3.1 int32 TOCEncoding = (TOC & 0xf8) >> 3; // Number of channels bool TOCStereo = (TOC & 0x4) != 0 ? true : false; // Number of frames and their configuration // 0: 1 frame in the packet // 1: 2 frames in the packet, each with equal compressed size // 2: 2 frames in the packet, with different compressed sizes // 3: an arbitrary number of frames in the packet int32 TOCMode = TOC & 0x3; if (bEncode) { UE_LOG(LogVoiceEncode, Verbose, TEXT("PacketLength: %d NumFrames: %d NumSamples: %d Bandwidth: %s Encoding: %d Stereo: %d FrameDesc: %d"), PacketLength, NumFrames, NumSamples, BandwidthStr, TOCEncoding, TOCStereo, TOCMode); } else { UE_LOG(LogVoiceDecode, Verbose, TEXT("PacketLength: %d NumFrames: %d NumSamples: %d Bandwidth: %s Encoding: %d Stereo: %d FrameDesc: %d"), PacketLength, NumFrames, NumSamples, BandwidthStr, TOCEncoding, TOCStereo, TOCMode); } }