Files
workinf_Blender_Wasm/tools/web/patches/libsndfile-vorbis-bitrate.patch
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

143 lines
4.3 KiB
Diff

--- a/include/sndfile.h
+++ b/include/sndfile.h
@@ -229,6 +229,9 @@
SFC_GET_BITRATE_MODE = 0x1304,
SFC_SET_BITRATE_MODE = 0x1305,
+ /* WebEngine extension: int target bits/s, native Vorbis managed encoding. */
+ SFC_WEB_SET_VORBIS_BITRATE = 0x7B01,
+
/* Cart Chunk support */
SFC_SET_CART_INFO = 0x1400,
SFC_GET_CART_INFO = 0x1401,
--- a/src/ogg_vorbis.c
+++ b/src/ogg_vorbis.c
@@ -137,6 +137,9 @@
vorbis_block vblock ;
/* Encoding quality in range [0.0, 1.0]. */
double quality ;
+ /* WebEngine: zero keeps upstream VBR quality mode. */
+ int nominal_bitrate ;
+ int header_ready ;
/* Offset of the first samples' granule position. */
uint64_t pcm_start ;
/* Last valid samples' granule position. */
@@ -313,20 +316,22 @@
VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
int k, ret ;
+ if (vdata->header_ready)
+ return 0 ;
+
vorbis_info_init (&vdata->vinfo) ;
- /* The style of encoding should be selectable here, VBR quality mode. */
- ret = vorbis_encode_init_vbr (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, vdata->quality) ;
-
-#if 0
- ret = vorbis_encode_init (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1) ; /* average bitrate mode */
- ret = ( vorbis_encode_setup_managed (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1)
- || vorbis_encode_ctl (&vdata->vinfo, OV_ECTL_RATEMANAGE_AVG, NULL)
- || vorbis_encode_setup_init (&vdata->vinfo)
- ) ;
-#endif
+ /* Select libvorbis' original managed average bitrate encoder when requested.
+ ** No bitrate-to-quality approximation: the native codec owns rate control. */
+ if (vdata->nominal_bitrate > 0)
+ ret = vorbis_encode_init (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate,
+ -1, vdata->nominal_bitrate, -1) ;
+ else
+ ret = vorbis_encode_init_vbr (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, vdata->quality) ;
if (ret)
+ { vorbis_info_clear (&vdata->vinfo) ;
return SFE_BAD_OPEN_FORMAT ;
+ } ;
vdata->gp = 0 ;
@@ -395,6 +400,7 @@
} ;
}
+ vdata->header_ready = SF_TRUE ;
return 0 ;
} /* vorbis_write_header */
@@ -402,6 +408,7 @@
vorbis_close (SF_PRIVATE *psf)
{ OGG_PRIVATE* odata = psf->container_data ;
VORBIS_PRIVATE *vdata = psf->codec_data ;
+ int error = 0 ;
if (odata == NULL || vdata == NULL)
return 0 ;
@@ -411,8 +418,10 @@
if (psf->file.mode == SFM_WRITE)
{
- if (psf->write_current <= 0)
- vorbis_write_header (psf, 0) ;
+ /* A rejected rate/rate-channel combination must never drain an
+ ** uninitialized encoder or leak its native allocations on close. */
+ if (! vdata->header_ready && (error = vorbis_write_header (psf, 0)))
+ goto cleanup ;
vorbis_analysis_wrote (&vdata->vdsp, 0) ;
while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
@@ -441,6 +450,7 @@
}
}
+cleanup:
/* ogg_page and ogg_packet structs always point to storage in
libvorbis. They are never freed or manipulated directly */
@@ -449,7 +459,7 @@
vorbis_comment_clear (&vdata->vcomment) ;
vorbis_info_clear (&vdata->vinfo) ;
- return 0 ;
+ return error ;
} /* vorbis_close */
int
@@ -515,12 +525,36 @@
VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
switch (command)
- { case SFC_SET_COMPRESSION_LEVEL :
+ { case SFC_WEB_SET_VORBIS_BITRATE :
+ { vorbis_info candidate ;
+ int bitrate, result ;
+ if (psf->file.mode != SFM_WRITE || psf->have_written || vdata->header_ready ||
+ data == NULL || datasize != sizeof (int))
+ return SF_FALSE ;
+ bitrate = *((int *) data) ;
+ if (bitrate <= 0)
+ return SF_FALSE ;
+
+ /* Ask the same encoder to accept the complete rate/channel tuple
+ ** before retaining it. A failed command leaves settings unchanged. */
+ vorbis_info_init (&candidate) ;
+ result = vorbis_encode_init (&candidate, psf->sf.channels, psf->sf.samplerate,
+ -1, bitrate, -1) ;
+ vorbis_info_clear (&candidate) ;
+ if (result)
+ return SF_FALSE ;
+ vdata->nominal_bitrate = bitrate ;
+ return SF_TRUE ;
+ } ;
+
+ case SFC_SET_COMPRESSION_LEVEL :
if (data == NULL || datasize != sizeof (double))
return SF_FALSE ;
- if (psf->have_written)
+ if (psf->file.mode != SFM_WRITE || psf->have_written || vdata->header_ready)
return SF_FALSE ;
+
+ vdata->nominal_bitrate = 0 ;
vdata->quality = 1.0 - *((double *) data) ;