Android 释放不同分辨率的输出缓冲区

Android 释放不同分辨率的输出缓冲区,android,android-ndk,mp4,android-mediacodec,Android,Android Ndk,Mp4,Android Mediacodec,我正在使用Android NDK MediaCodec API对不同分辨率的MP4流进行解码 我使用内置功能渲染到曲面,调用AMediaCodec\u releaseOutputBuffer,并将render标志设置为true 我发现每次分辨率改变时,旧分辨率的几帧都会输出到新分辨率大小的曲面上。为了提高分辨率,它可能看起来像这样: +------------------+-------------+ | frame of old res | | | displayed

我正在使用Android NDK MediaCodec API对不同分辨率的MP4流进行解码

我使用内置功能渲染到曲面,调用
AMediaCodec\u releaseOutputBuffer
,并将
render
标志设置为true

我发现每次分辨率改变时,旧分辨率的几帧都会输出到新分辨率大小的曲面上。为了提高分辨率,它可能看起来像这样:

+------------------+-------------+
| frame of old res |             |
| displayed too    |             |
| small            |             |
+------------------+             |
|                                |
|      size of new resolution    |
+--------------------------------+
几帧之后,视频看起来又正常了。我怀疑这与输入缓冲区以新分辨率排队时曲面大小的变化有关,而不是与该分辨率的第一个输出缓冲区退出队列时曲面大小的变化有关


以前是否有人遇到过此问题?

此特定解码器是否表示支持

我自己也没有遇到过这个问题(因为我没有尝试过对改变分辨率的流进行解码),但据我所知,这个特性标志被引入来表示对这个用例的正确处理。如果你看到一个带有这个特征标志的解码器的行为,我会认为它是一个bug(或者我还没有正确理解这个特性标志的实际含义)。 我在中发现了以下内容:

对于某些视频格式,也可以在中流时更改图片大小。要对H.264执行此操作,必须将新的序列参数集(SPS)和图片参数集(PPS)值与瞬时解码器刷新(IDR)帧打包在一个缓冲区中,然后将其作为常规输入缓冲区排队。在图片大小更改发生之后,在返回任何具有新大小的帧之前,客户端将从dequeueOutputBuffer()或onOutputBufferAvailable()接收一个信息输出格式更改的返回值

每当我收到一个新的SPS和PPS时,我都会确保不会立即将它们传递给解码器,而是将它们预先发送到下一个I帧


这解决了问题-分辨率更改是无缝的:)

有趣的是,这个问题从未在我的ADT-1设备上出现过,只是在我的新Nexus播放器上出现过。您的解码器是配置为在输出缓冲区上的
元数据
模式下工作还是在常规模式下工作?当分辨率改变时,解码器将尝试清除其队列中的挂起帧。因此,如果分配的缓冲区足够大,可以处理当前的解析,那么应该在框架中获得一个
portsetingschanged
事件。您能否指定您正在使用的是哪个版本的
android
,并在
ACodec
中共享捕获的日志?
自适应播放
的引入是为了支持
DASH
,它可以在某个时间点更改分辨率。通常,解码器将能够通过基于策略发送端口设置更改或更新事件的信号来处理分辨率更改。如果新分辨率小于或等于旧分辨率,则不支持
自适应播放
标志的解码器仍可决定解码流,并发出裁剪窗口更改信号,或者通过更改端口设置请求重新分配。哎哟,是的,我忘了说!