ExoPlayer 使用以及指定解码

原创
2022/09/18 15:46
阅读数 135

一、常见的方法

(1)seek相关

seekToNext() 下一首,

seekToPrevious() 上一首

seekForward() 前进

seekBack () 后退

seek(windowIndex,offset) 某一首的某一位置

seekable

(2) 切歌回调

onMediaItemTransition。(切歌时优先以此表准确)

onPositionDiscontinuity

切歌时不会返回STATE_END回调,这个只有链表播放结束才会有

 

(2) ExoPlayer 数据源概念

ExoPlayer 细分了数据源,容易造成混淆

DataSource - > MediaSource -> ExoPlayer 

 

二、指定解码器

 

案例:

有一种情况,某种情况下,我们可能需要创建2-3个视频解码器同时播放各自的视频,比如监控软件9宫格中播放不同角落的视频。

由于很多硬件厂商处于成本的考虑,购买廉价的硬件,导致默认的解码器只能最大支持2个Codec实例,因此,显然需要使用其他非默认的解码器来处理相关问题。

下面是解码器相关能力以及最大支持的实例数。

    public final void dumpMediaCodecsInfo() {
        if(!BuildConfig.DEBUG){
            return;
        }
        int CodecCount = 0;
        try {
            CodecCount = MediaCodecList.getCodecCount();
        }catch (Exception e) {
            Log.e(TAG, "##### Failed to get codec count!");
            e.printStackTrace();
            return;
        }

        for (int i = 0; i < CodecCount; ++i) {
            MediaCodecInfo info = null;
            try {
                info = MediaCodecList.getCodecInfoAt(i);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Cannot retrieve decoder codec info", e);
            }
            if (info == null) {
                continue;
            }

            String codecInfo = "MediaCodec, name="+info.getName()+", [";

            for (String mimeType : info.getSupportedTypes()) {
                codecInfo += mimeType + ",";
                MediaCodecInfo.CodecCapabilities capabilities;
                try {
                    capabilities = info.getCapabilitiesForType(mimeType);
                } catch (IllegalArgumentException e) {
                    Log.e(TAG, "Cannot retrieve decoder capabilities", e);
                    continue;
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    codecInfo += " max inst: "+capabilities.getMaxSupportedInstances()+",";
                }else{
                    codecInfo += " max inst: UNKOWN";
                }

                String strColorFormatList = "";
                for (int colorFormat : capabilities.colorFormats) {
                    strColorFormatList += " 0x" + Integer.toHexString(colorFormat);
                }
                codecInfo += strColorFormatList + "] [";
            }

            Log.w(TAG, codecInfo);
        }


    }

 

 

ExoPlayer 底层使用MediaCodec框架实现,视频和音频的解码器是分离的,实际上,MediaCodec未必是软解码,但是设备厂商会注册一个默认的解码器,通过MediaCodec.createDecoderByType(type)。

如果想指定解码器,可以使用

MediaCodec.createByCodecName("c2.android.avc.decoder")

MediaCodec.createByCodecName("OMX.google.h264.decoder")

在Android中OMX.google.和c2.android.开头的解码器是Android内置的软解码器

 

解码器错误分析

(1)

System.err: android.media.MediaCodec$CodecException: Failed to initialize OMX.qcom.video.encoder.avc, error 0xfffffff4

错误原因:创建MediaCodec实例超限;

 

解码器实例超限制还有下面情况

09-20 16:53:30.579 E/VOMX    ( 3328): [omx_videodec_component_Constructor]OMX can't get decoder driver instance
09-20 16:53:30.579 E//vendor/bin/hw/android.hardware.media.omx@1.0-service( 3328): Failed to allocate omx component 'OMX.NVT.Video.Decoder.avc'  err=InsufficientResources(0x80001000)
09-20 16:53:30.579 W/ACodec  (30121): Allocating component 'OMX.NVT.Video.Decoder.avc' failed, try next one.
09-20 16:53:30.579 E/ACodec  (30121): Unable to instantiate a decoder for type 'video/avc' with err 0xfffffff4.
09-20 16:53:30.580 E/ACodec  (30121): signalError(omxError 0xfffffff4, internalError -12)
09-20 16:53:30.580 E/MediaCodec(30121): Codec reported err 0xfffffff4, actionCode 0, while in state 1
09-20 16:53:30.580 E/MediaCodec(30121): CodecBase::kWhatError ---- start  notifyFunc:0  mDecoderHandle:0x0 ....
09-20 16:53:30.583 E/ResourceManagerService( 3322): getLowestPriorityBiggestClient_l: lowest priority 0 vs caller priority 0
09-20 16:53:30.587 I/speech_DBUserOperLogDao( 3610): Success to insert data
09-20 16:53:30.588 W/MediaCodec-JNI(30121): try to release MediaCodec from JMediaCodec::~JMediaCodec()...
09-20 16:53:30.588 W/MediaCodec-JNI(30121): done releasing MediaCodec from JMediaCodec::~JMediaCodec().
09-20 16:53:30.588 E/app catched error(30121): android.media.MediaCodec$CodecException: Failed to initialize video/avc, error 0xfffffff4

 

(2)

ACodec: [OMX.allwinner.video.encoder.avc] ERROR(0x80001009)

 

错误原因:

1. 塞了错误的数据

2. 入队Frame数据时用了flag(BUFFER_FLAG_CODEC_CONFIG),但是入队的数据中没带sps,pps。或者相反,没用这个flag,数据中带了sps,pps。

(3)

Failed to initialize video/avc, error 0xfffffffe
错误原因:MediaCodec.createByCodecName 只能传详细的编解码器名称(如:OMX.qcom.video.encoder.avc);不能传类型如:video/avc;

 

(4)

ACodec: [OMX.rk.video_encoder.avc] stopping checking profiles after 32: 8/1
OMX.rk.video_encoder.avc] configureCodec returning error -1010
android.media.MediaCodec$CodecException: Error 0xfffffc0e
错误原因:

创建编码器时,不支持hightProfile属性;
 

 

 

 

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部