mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-24 02:09:03 +03:00
avcodec/opus/enc_psy: don't make the last frame silent at EOF
816d74e0bbmade frames without psy analysis at EOF silent. The frame that follows the last input frame to flush its MDCT overlap is always such a frame, so the last CELT_OVERLAP samples of the stream were lost whenever it was needed, i.e. when the length of the stream is a multiple of frame_size or less than CELT_OVERLAP samples short of one. It was also coded as a one byte packet, which the MPEG-TS muxer rejects. Encode it like any other frame instead. Its psy analysis data is zeroed, which leaves it with the default frame parameters. Fixes: #24196 (cherry picked from commit2e0a770b8e)
This commit is contained in:
@@ -300,15 +300,6 @@ void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index)
|
||||
for (i = 0; i < steps_per_frame; i++)
|
||||
silence &= s->steps[index * steps_per_frame + i]->silence;
|
||||
|
||||
/* If we reach EOF with fewer collected psy steps than this packet wants
|
||||
* to encode, the slots beyond buffered_steps were zeroed by the previous
|
||||
* postencode_update and contain no valid analysis data. Encoding garbage
|
||||
* with the full rate budget can overrun the range coder buffer (rng_bytes
|
||||
* exceeds the per-frame size passed to ff_opus_rc_enc_end), so force a
|
||||
* silent packet instead. */
|
||||
if (s->eof && step_offset >= s->buffered_steps)
|
||||
silence = 1;
|
||||
|
||||
f->silence = silence;
|
||||
if (f->silence) {
|
||||
/* Explicitly signal silence in a 2 byte frame, like libopus does.
|
||||
@@ -556,7 +547,9 @@ void ff_opus_psy_postencode_update(OpusPsyContext *s, CeltFrame *f)
|
||||
s->avg_is_band /= (s->p.frames + 1);
|
||||
|
||||
s->steps_to_process = 0;
|
||||
s->buffered_steps -= steps_out;
|
||||
/* At EOF, one more frame than there are psy steps is encoded to flush
|
||||
* the last frame's MDCT overlap */
|
||||
s->buffered_steps = FFMAX(s->buffered_steps - steps_out, 0);
|
||||
s->total_packets_out += s->p.frames;
|
||||
s->inflection_points_count = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user