Closes H1 from the pre-ship review (the known-limit doc note added inc0d55ba). The previous workaround was "first play-through truncates the last ~16 frames; replay is fine because flush_buffers clears libavcodec." That trade-off was OK for shipping but the proper fix is to drain the reorder buffer before propagating EOS to ExoPlayer. Media3's SimpleDecoder short-circuits the end-of-stream input buffer and never invokes the subclass's decode(), so there's no hook to send avcodec_send_packet(NULL). Every override worth overriding (decode loop, queue methods, flush) is final on SimpleDecoder. So we vendor a copy as FfmpegSimpleDecoder (Apache 2.0 attribution at the top of the file) with one structural change: an EOS-drain state. On EOS input, signalEndOfInput() flushes libavcodec's reorder queue, then drainAtEndOfStream() is called on successive output buffers until it reports DRAIN_DONE — at which point the loop attaches BUFFER_FLAG_END_OF_STREAM and resumes normal teardown. Everything else mirrors SimpleDecoder verbatim so upstream improvements are cheap to pull forward. - FfmpegSimpleDecoder.java: vendored base class. - ffmpegVideoSignalEos JNI: sends avcodec_send_packet(NULL). - FfmpegVideoDecoder: extends the new base; signalEndOfInput forwards to the JNI; drainAtEndOfStream re-uses the existing ffmpegVideoReceiveFrame so per-frame PTS recovery and the pending_frame path fromc0d55bacontinue to work during drain.
17 KiB
17 KiB