有几点须注意,
- 不要让硬解码器自已绘制表面,也就是AMediaCodec_configure传入的surface应设为空。否则运行时间长了,会出现“weak global reference table overflow”的崩机错误。
- 我之前文章里也说过了,不要静态链编libmediandk.so,老的安卓机上没有这个库,要动态检测加载,详细过程见之后代码。
- AMediaCodec_dequeueInputBuffer不是每一次都返回成功,如果失败了而丢弃h264数据帧,则最终的播放效果就时不时出现花屏,正确处理见之后代码。
- 硬解码器解出的数据默认可能是NV12格式也可能是YV12格式,不同的手机不一样,预先配置解码器的"color-format"为19,也没用。为了与ffmpeg解出的数据一致为YU12格式,统一地我们自已转。
以下是源码,摘选自EuhatRtsp开源软件,经历过长时间拷机运行没问题。其网址是:http://euhat.com/rtsp.html
DecoderHard.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #pragma once #include "DecodeOp.h" class AMediaCodec; class EuhatDecoderHard : public EuhatDecoderBase { int updateSpsAndPps(); int spsChanged_; int ppsChanged_; char *sps_; char *pps_; int width_; int height_; int oriHeight_; int colorFormat_; int stride_; int sliceHeight_; int cropTop_; int cropBottom_; int cropLeft_; int cropRight_; int isCodecInited_; void *surface_; int surfaceChanged_; public: EuhatDecoderHard(); virtual ~EuhatDecoderHard(); virtual int init(EuhatDecoderCallback callback, void *context); virtual int fini(); virtual int updateSps(const char *sps); virtual int updatePps(const char *pps); virtual int updateWH(int width, int height); virtual int updateSurface(void *surface); virtual int decode(char *frame, int frameLen); static int canWork(); AMediaCodec *mediaCodec_; }; |