Ensure extensions work with huge timestamps, fix AC3 and AAC extension's behavior with huge timestamps

This commit is contained in:
Vanilagy
2026-04-27 20:58:05 +02:00
parent 0cc564b47a
commit 0f6c374750
12 changed files with 282 additions and 31 deletions
Binary file not shown.
+4 -3
View File
@@ -7,6 +7,7 @@
*/
#include <emscripten.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "libavcodec/avcodec.h"
@@ -20,7 +21,7 @@ typedef struct {
AVFrame *frame;
float *input_buffer;
int input_buffer_size;
int encoded_pts;
int64_t encoded_pts;
int encoded_duration;
} EncoderContext;
@@ -123,7 +124,7 @@ float *get_encode_input_ptr(EncoderContext *ctx, int size) {
}
EMSCRIPTEN_KEEPALIVE
int send_frame(EncoderContext *ctx, int pts) {
int send_frame(EncoderContext *ctx, int64_t pts) {
int channels = ctx->codec_ctx->ch_layout.nb_channels;
int frame_size = ctx->frame->nb_samples;
@@ -171,7 +172,7 @@ uint8_t *get_encoded_data(EncoderContext *ctx) {
}
EMSCRIPTEN_KEEPALIVE
int get_encoded_pts(EncoderContext *ctx) {
int64_t get_encoded_pts(EncoderContext *ctx) {
return ctx->encoded_pts;
}
+6 -6
View File
@@ -21,12 +21,12 @@ let getEncoderFrameSize: (ctx: number) => number;
let getEncoderExtradata: (ctx: number) => number;
let getEncoderExtradataSize: (ctx: number) => number;
let getEncodeInputPtr: (ctx: number, size: number) => number;
let sendFrameFn: (ctx: number, pts: number) => number;
let sendFrameFn: (ctx: number, pts: bigint) => number;
let receivePacketFn: (ctx: number) => number;
let flushEncoderStartFn: (ctx: number) => void;
let resetEncoderFn: (ctx: number) => void;
let getEncodedData: (ctx: number) => number;
let getEncodedPts: (ctx: number) => number;
let getEncodedPts: (ctx: number) => bigint;
let getEncodedDuration: (ctx: number) => number;
const ensureModule = async () => {
if (!module) {
@@ -43,12 +43,12 @@ const ensureModule = async () => {
getEncoderExtradata = module.cwrap('get_encoder_extradata', 'number', ['number']);
getEncoderExtradataSize = module.cwrap('get_encoder_extradata_size', 'number', ['number']);
getEncodeInputPtr = module.cwrap('get_encode_input_ptr', 'number', ['number', 'number']);
sendFrameFn = module.cwrap('send_frame', 'number', ['number', 'number']);
sendFrameFn = module.cwrap('send_frame', 'number', ['number', 'number']) as unknown as typeof sendFrameFn;
receivePacketFn = module.cwrap('receive_packet', 'number', ['number']);
flushEncoderStartFn = module.cwrap('flush_encoder_start', null, ['number']);
resetEncoderFn = module.cwrap('reset_encoder', null, ['number']);
getEncodedData = module.cwrap('get_encoded_data', 'number', ['number']);
getEncodedPts = module.cwrap('get_encoded_pts', 'number', ['number']);
getEncodedPts = module.cwrap('get_encoded_pts', 'number', ['number']) as unknown as typeof getEncodedPts;
getEncodedDuration = module.cwrap('get_encoded_duration', 'number', ['number']);
}
};
@@ -81,7 +81,7 @@ const drainPackets = (ctx: number) => {
while ((size = receivePacketFn(ctx)) > 0) {
const ptr = getEncodedData(ctx);
const encodedData = module.HEAPU8.slice(ptr, ptr + size).buffer;
const pts = getEncodedPts(ctx);
const pts = Number(getEncodedPts(ctx));
const duration = getEncodedDuration(ctx);
packets.push({ encodedData, pts, duration });
}
@@ -98,7 +98,7 @@ const encode = (ctx: number, audioData: ArrayBuffer, timestamp: number) => {
}
module.HEAPU8.set(audioBytes, inputPtr);
const ret = sendFrameFn(ctx, timestamp);
const ret = sendFrameFn(ctx, BigInt(timestamp));
if (ret < 0) {
throw new Error(`Encode failed with error code ${ret}.`);
}
BIN
View File
Binary file not shown.
+7 -6
View File
@@ -7,6 +7,7 @@
*/
#include <emscripten.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "libavcodec/avcodec.h"
@@ -72,7 +73,7 @@ uint8_t *configure_decode_packet(DecoderContext *ctx, int size) {
}
EMSCRIPTEN_KEEPALIVE
int decode_packet(DecoderContext *ctx, int pts) {
int decode_packet(DecoderContext *ctx, int64_t pts) {
ctx->packet->pts = pts;
int ret = avcodec_send_packet(ctx->codec_ctx, ctx->packet);
av_packet_unref(ctx->packet);
@@ -110,8 +111,8 @@ int get_decoded_sample_count(DecoderContext *ctx) {
}
EMSCRIPTEN_KEEPALIVE
int get_decoded_pts(DecoderContext *ctx) {
return (int)ctx->frame->pts;
int64_t get_decoded_pts(DecoderContext *ctx) {
return ctx->frame->pts;
}
EMSCRIPTEN_KEEPALIVE
@@ -135,7 +136,7 @@ typedef struct {
AVFrame *frame;
float *input_buffer;
int input_buffer_size;
int encoded_pts;
int64_t encoded_pts;
int encoded_duration;
} EncoderContext;
@@ -229,7 +230,7 @@ float *get_encode_input_ptr(EncoderContext *ctx, int size) {
}
EMSCRIPTEN_KEEPALIVE
int encode_frame(EncoderContext *ctx, int pts) {
int encode_frame(EncoderContext *ctx, int64_t pts) {
int channels = ctx->codec_ctx->ch_layout.nb_channels;
int frame_size = ctx->frame->nb_samples;
@@ -270,7 +271,7 @@ uint8_t *get_encoded_data(EncoderContext *ctx) {
}
EMSCRIPTEN_KEEPALIVE
int get_encoded_pts(EncoderContext *ctx) {
int64_t get_encoded_pts(EncoderContext *ctx) {
return ctx->encoded_pts;
}
+12 -12
View File
@@ -18,23 +18,23 @@ let modulePromise: Promise<ExtendedEmscriptenModule> | null = null;
let initDecoderFn: (codecId: number) => number;
let configureDecodePacket: (ctx: number, size: number) => number;
let decodePacket: (ctx: number, pts: number) => number;
let decodePacket: (ctx: number, pts: bigint) => number;
let getDecodedFormat: (ctx: number) => number;
let getDecodedPlanePtr: (ctx: number, plane: number) => number;
let getDecodedChannels: (ctx: number) => number;
let getDecodedSampleRate: (ctx: number) => number;
let getDecodedSampleCount: (ctx: number) => number;
let getDecodedPts: (ctx: number) => number;
let getDecodedPts: (ctx: number) => bigint;
let flushDecoderFn: (ctx: number) => void;
let closeDecoderFn: (ctx: number) => void;
let initEncoderFn: (codecId: number, channels: number, sampleRate: number, bitrate: number) => number;
let getEncoderFrameSize: (ctx: number) => number;
let getEncodeInputPtr: (ctx: number, size: number) => number;
let encodeFrameFn: (ctx: number, pts: number) => number;
let encodeFrameFn: (ctx: number, pts: bigint) => number;
let flushEncoderFn: (ctx: number) => void;
let getEncodedData: (ctx: number) => number;
let getEncodedPts: (ctx: number) => number;
let getEncodedPts: (ctx: number) => bigint;
let getEncodedDuration: (ctx: number) => number;
let closeEncoderFn: (ctx: number) => void;
@@ -53,23 +53,23 @@ const ensureModule = async () => {
initDecoderFn = module.cwrap('init_decoder', 'number', ['number']);
configureDecodePacket = module.cwrap('configure_decode_packet', 'number', ['number', 'number']);
decodePacket = module.cwrap('decode_packet', 'number', ['number', 'number']);
decodePacket = module.cwrap('decode_packet', 'number', ['number', 'number']) as unknown as typeof decodePacket;
getDecodedFormat = module.cwrap('get_decoded_format', 'number', ['number']);
getDecodedPlanePtr = module.cwrap('get_decoded_plane_ptr', 'number', ['number', 'number']);
getDecodedChannels = module.cwrap('get_decoded_channels', 'number', ['number']);
getDecodedSampleRate = module.cwrap('get_decoded_sample_rate', 'number', ['number']);
getDecodedSampleCount = module.cwrap('get_decoded_sample_count', 'number', ['number']);
getDecodedPts = module.cwrap('get_decoded_pts', 'number', ['number']);
getDecodedPts = module.cwrap('get_decoded_pts', 'number', ['number']) as unknown as typeof getDecodedPts;
flushDecoderFn = module.cwrap('flush_decoder', null, ['number']);
closeDecoderFn = module.cwrap('close_decoder', null, ['number']);
initEncoderFn = module.cwrap('init_encoder', 'number', ['number', 'number', 'number', 'number']);
getEncoderFrameSize = module.cwrap('get_encoder_frame_size', 'number', ['number']);
getEncodeInputPtr = module.cwrap('get_encode_input_ptr', 'number', ['number', 'number']);
encodeFrameFn = module.cwrap('encode_frame', 'number', ['number', 'number']);
encodeFrameFn = module.cwrap('encode_frame', 'number', ['number', 'number']) as unknown as typeof encodeFrameFn;
flushEncoderFn = module.cwrap('flush_encoder', null, ['number']);
getEncodedData = module.cwrap('get_encoded_data', 'number', ['number']);
getEncodedPts = module.cwrap('get_encoded_pts', 'number', ['number']);
getEncodedPts = module.cwrap('get_encoded_pts', 'number', ['number']) as unknown as typeof getEncodedPts;
getEncodedDuration = module.cwrap('get_encoded_duration', 'number', ['number']);
closeEncoderFn = module.cwrap('close_encoder', null, ['number']);
}
@@ -108,7 +108,7 @@ const decode = (ctx: number, encodedData: ArrayBuffer, timestamp: number) => {
module.HEAPU8.set(bytes, dataPtr);
const ret = decodePacket(ctx, timestamp);
const ret = decodePacket(ctx, BigInt(timestamp));
if (ret < 0) {
throw new Error(`Decode failed with error code ${ret}.`);
}
@@ -122,7 +122,7 @@ const decode = (ctx: number, encodedData: ArrayBuffer, timestamp: number) => {
const channels = getDecodedChannels(ctx);
const sampleRate = getDecodedSampleRate(ctx);
const sampleCount = getDecodedSampleCount(ctx);
const pts = getDecodedPts(ctx);
const pts = Number(getDecodedPts(ctx));
let pcmData: ArrayBuffer;
if (info.planar) {
@@ -169,14 +169,14 @@ const encode = (ctx: number, audioData: ArrayBuffer, timestamp: number) => {
}
module.HEAPU8.set(audioBytes, inputPtr);
const bytesWritten = encodeFrameFn(ctx, timestamp);
const bytesWritten = encodeFrameFn(ctx, BigInt(timestamp));
if (bytesWritten < 0) {
throw new Error(`Encode failed with error code ${bytesWritten}.`);
}
const ptr = getEncodedData(ctx);
const encodedData = module.HEAPU8.slice(ptr, ptr + bytesWritten).buffer;
const pts = getEncodedPts(ctx);
const pts = Number(getEncodedPts(ctx));
const duration = getEncodedDuration(ctx);
return { encodedData, pts, duration };