IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 修复ijkplayer没有正确处理sps导致的MediaCodec解码失败问题 -> 正文阅读

[移动开发]修复ijkplayer没有正确处理sps导致的MediaCodec解码失败问题

播放HLS时,部分TS分片的sps排列是:
0 0 0 1 9 240 0 0 0 1 103 。。。 0 0 0 1 104。。。
其对应的内容是:

  1. 0 0 0 1 9 240 :表示AUD
  2. 接着的 0 0 0 1 :表示 start code
  3. 接着的103 :表示sps类型
  4. 接着的就是sps的数据
  5. 最后的0 0 0 1 104 :104表示是pps数据
  6. 接着的就是pps的数据

这里针对这种情况做了处理,提取出其中的sps数据给到MediaCodec,避免MediaCodec初始化失败。

需要这种视频链接的,我可以发出来,不过视频链接只有24小时有效。

issues如下:

  1. android k0.8.4 某些手机播放视频有声音,无画面(即透明,非黑屏)?#4177
  2. 请教下Android播放视频只有声音没有画面??#3544

  
ijkmedia/ijkplayer/android/pipeline/ffpipenode_android_mediacodec_vdec.c
@@ -245,24 +245,23 @@ static int recreate_format_l(JNIEnv *env, IJKFF_Pipenode *node)
            SDL_AMediaFormat_setBuffer(opaque->input_aformat, "csd-0", convert_buffer, esds_size);
            free(convert_buffer);
        } else {
            //先只考虑h264的情况,H265这种情况我也没见过
            if(opaque->avctx->codec_id == AV_CODEC_ID_H264  && opaque->avctx->extradata_size > 6){
                //参考 https://blog.csdn.net/chinabinlang/article/details/78181110
                //参考 https://blog.csdn.net/dxpqxb/article/details/7631644
                //这种视频是:AUD+SPS+PPS的情况
           if(opaque->codecpar->codec_id == AV_CODEC_ID_H264  && opaque->codecpar->extradata_size > 6){
                // https://blog.csdn.net/chinabinlang/article/details/78181110
                // https://blog.csdn.net/dxpqxb/article/details/7631644
                // AUD+SPS+PPS的情况
                // 103 代表sps
                // 104 代表pps
                int spsIndex = -1;
                int ppsIndex = -1;
                if(opaque->avctx->extradata[0] == 0 && opaque->avctx->extradata[1] == 0 && opaque->avctx->extradata[2] == 0
                   && opaque->avctx->extradata[3] == 1 && opaque->avctx->extradata[4] == 9 && opaque->avctx->extradata[5] == 240){
                if(opaque->codecpar->extradata[0] == 0 && opaque->codecpar->extradata[1] == 0 && opaque->codecpar->extradata[2] == 0
                   && opaque->codecpar->extradata[3] == 1 && opaque->codecpar->extradata[4] == 9 && opaque->codecpar->extradata[5] == 240){
                    for(int i=6;i<opaque->avctx->extradata_size-4;i++){
                        if(opaque->avctx->extradata[i] == 0 && opaque->avctx->extradata[i+1] == 0 && opaque->avctx->extradata[i+2] == 0
                           && opaque->avctx->extradata[i+3] == 1){
                            if(opaque->avctx->extradata[i+4] == 103){
                        if(opaque->codecpar->extradata[i] == 0 && opaque->codecpar->extradata[i+1] == 0 && opaque->codecpar->extradata[i+2] == 0
                           && opaque->codecpar->extradata[i+3] == 1){
                            if(opaque->codecpar->extradata[i+4] == 103){
                                spsIndex = i;
                                ALOGE("AMediaFormat find sps = %d",spsIndex);
                            }else if(opaque->avctx->extradata[i+4] == 104){
                            }else if(opaque->codecpar->extradata[i+4] == 104){
                                ppsIndex = i;
                                ALOGE("AMediaFormat find pps = %d",ppsIndex);
                            }
@@ -275,11 +274,11 @@ static int recreate_format_l(JNIEnv *env, IJKFF_Pipenode *node)
                    if(ppsIndex > 0 && spsIndex < ppsIndex){
                        length = ppsIndex-spsIndex;
                    }else{
                        length = opaque->avctx->extradata_size-spsIndex;
                        length = opaque->codecpar->extradata_size-spsIndex;
                    }

                    uint8_t *convert_buffer = (uint8_t *)calloc(1, length);
                    memcpy( convert_buffer, opaque->avctx->extradata+spsIndex, length);
                    memcpy( convert_buffer, opaque->codecpar->extradata+spsIndex, length);

                    SDL_AMediaFormat_setBuffer(opaque->input_aformat, "csd-0", convert_buffer, length);
                    free(convert_buffer);

获取MediaCodec的SPS和PPS

一、SPS和PPS文档说明

在这里插入图片描述
二、NALU类型

在这里插入图片描述
三、获取SPS、PPS两种方式?1、同步方式

ByteBuffer spsb = videoEncodec.getOutputFormat().getByteBuffer("csd-0");
byte[] sps = new byte[spsb.remaining()];
spsb.get(sps, 0, sps.length);

ByteBuffer ppsb = videoEncodec.getOutputFormat().getByteBuffer("csd-1");
byte[] pps = new byte[ppsb.remaining()];
ppsb.get(pps, 0, pps.length);


2、异步方式

@Override
public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {
? ? MediaFormat outputFormat = codec.getOutputFormat();
? ? SPS = outputFormat.getByteBuffer("csd-0").array();
? ? PPS = outputFormat.getByteBuffer("csd-1").array();
? ? Log.e(TAG," onOutputFormatChanged ?SPS ?"+ CommonUtils.byteToHex(SPS));
? ? Log.e(TAG," onOutputFormatChanged ?PPS ?"+CommonUtils.byteToHex(PPS));
}

四、对应的sps、pps、I帧、P帧等数据

1、sps、pps
sps:000000016742ffffffc01effffffda05ffffffc145ffffff97ffffff8078402150
pps:0000000168ffffffce3cffffff80
2、I帧
data:0000000165ffffffb80010ffffffa413ffffffffffffffe5ffffffc3ffffffd31239695affffffabffffffb0340a
3、P帧
data:0000000161ffffffe9ffffffab13ffffffcd72ffffffdbffffffe5ffffffe25f5d7e64ffffff9ffffffff33affffffebffffffbd



总结:编码器编出来的数据首帧、sps、pps、I帧、P帧等顺序
?

利用MediaCodec 获取视频的sps pps 和视频数据_we1less的博客-CSDN博客

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:53:18  更:2022-10-08 20:55:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 3:10:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码