Combine Opus Frames With Libopus Repacketizer

Combining multiple independent Opus audio frames into a single packet reduces network overhead and improves streaming efficiency. This article explains how to use the libopus repacketizer API to merge multiple encoded Opus frames into a single, valid Opus packet without the CPU overhead of decoding and re-encoding.

Understanding the Opus Repacketizer

The Opus repacketizer (opus_repacketizer_*) is a utility within the libopus library designed to manipulate the framing of Opus packets. It allows you to merge multiple small packets into a larger single packet (packet coalescing) or split a multi-frame packet into smaller individual packets. Because this process operates directly on the encoded bitstream, it bypasses the decoder and encoder entirely, preserving original audio quality and requiring minimal CPU usage.

Step-by-Step Implementation

To combine multiple independent Opus frames using the repacketizer, follow these steps:

1. Create and Initialize the Repacketizer

First, allocate memory and initialize the repacketizer state.

OpusRepacketizer *rp = opus_repacketizer_create();
if (rp == NULL) {
    // Handle allocation failure
}

Alternatively, to avoid dynamic memory allocation, you can obtain the state size using opus_repacketizer_get_size() and initialize a pre-allocated buffer with opus_repacketizer_init().

2. Clear the State

Before processing a new set of frames, ensure the repacketizer state is cleared:

opus_repacketizer_init(rp);

3. Add Individual Opus Frames

Append each independent Opus frame to the repacketizer using opus_repacketizer_cat(). You must pass the encoded frame data and its length in bytes.

int err;
for (int i = 0; i < num_frames; i++) {
    err = opus_repacketizer_cat(rp, frame_data[i], frame_len[i]);
    if (err != OPUS_OK) {
        // Handle error (e.g., frames are incompatible, or max limit exceeded)
    }
}

Note: All frames being combined must share identical configurations, including the same bandwidth, channel count, and frame duration.

4. Generate the Combined Packet

Once all frames are successfully added to the repacketizer queue, extract the newly combined packet into your target output buffer using opus_repacketizer_out().

unsigned char out_packet[MAX_PACKET_SIZE];
opus_int32 out_len;

// Output all categorized frames as a single packet
out_len = opus_repacketizer_out(rp, out_packet, sizeof(out_packet));
if (out_len < 0) {
    // Handle output generation error
}

The returned out_len represents the exact size of the newly generated single Opus packet in bytes.

5. Clean Up

Once processing is complete, free the allocated repacketizer state to prevent memory leaks:

opus_repacketizer_destroy(rp);

Key Limitations and Constraints

While the repacketizer is highly efficient, you must adhere to the limits imposed by the Opus specification: