iOS 扩展Ijkplayer解码方式

Ijkplayer框架中,解码方式的选择只有 智能硬解(硬解失败,自动转软解)、软解 两种,功能上讲,两种方式已够用,但偶尔也有需求让扩展成用户自选的三种解码方式:智能、硬解、软解。

下文讲的就是如何在原框架中,扩展出 硬解 的选项,及其失败后对应的消息处理:
1.在 ff_ffplay_options.h 文件下修改“videotoolbox”的最大值,范围由0 ~ 1,扩展到0 ~ 2:
0:软解
1:智能硬解
2:硬解
 { "videotoolbox",                       "VideoToolbox: enable",
        OPTION_OFFSET(videotoolbox),        OPTION_INT(0, 0, 2) },
在工程中创建播放器时,设置options选项,来选择视频的解码方式(默认是软解):
 [options setOptionIntValue:1 forKey:@"videotoolbox" ofCategory:kIJKFFOptionCategoryPlayer];
2.在实现选择解码方式的方法之前,需要先创建一个硬解失败的标志位,通过判断它来决定是否需要发送硬解失败的错误提示:

ff_ffpipeline.h 中,修改结构体:IJKFF_Pipeline * 添加布尔值 * bool video_decoder_from_ios_videotoolbox_failed;

3.修改 ffpipeline_ios.c 中 函数*func_open_video_decoder *的解码选择逻辑:
static IJKFF_Pipenode *func_open_video_decoder(IJKFF_Pipeline *pipeline, FFPlayer *ffp) {
   
    IJKFF_Pipenode* node = NULL;
    IJKFF_Pipeline_Opaque *opaque = pipeline->opaque;
    pipeline->video_decoder_from_ios_videotoolbox_failed = false;
    if (ffp->videotoolbox != 0) {
        node = ffpipenode_create_video_decoder_from_ios_videotoolbox(ffp);
        if (node) {
            ffp->stat.vdec_type = FFP_PROPV_DECODER_VIDEOTOOLBOX;
            opaque->is_videotoolbox_open = true;
        } else if (!node && ffp->videotoolbox == 1){
            node = ffpipenode_create_video_decoder_from_ffplay(ffp);
            ffp->stat.vdec_type = FFP_PROPV_DECODER_AVCODEC;
            opaque->is_videotoolbox_open = false;
        }
    } else {
        node = ffpipenode_create_video_decoder_from_ffplay(ffp);
        ffp->stat.vdec_type = FFP_PROPV_DECODER_AVCODEC;
        opaque->is_videotoolbox_open = false;
    }
    if(!node) {
        ffp->stat.vdec_type = FFP_PROPV_DECODER_UNKNOWN;
        pipeline->video_decoder_from_ios_videotoolbox_failed = true;
    }
    ffp_notify_msg2(ffp, FFP_MSG_VIDEO_DECODER_OPEN, opaque->is_videotoolbox_open);
    return node;
}

4.在 ff_ffplay.c 添加硬解失败消息处理,并阻止后续进程的继续操作:
 if(ffp->pipeline->video_decoder_from_ios_videotoolbox_failed){
        last_error = 19;//这个errorCode自己定义,建议稍大一点,不会和框架的重复
        goto fail;
    }

上段代码建议添加在下面代码的后面:

if (is->video_stream < 0 && is->audio_stream < 0) {
        av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
               is->filename);
        ret = -1;
        goto fail;
    }

5. * goto fail*之后,它会通过 *ffp_notify_msg2(ffp, FFP_MSG_ERROR, last_error); * 将错误消息发送出去,在 *IJKFFMoviePlayerController.m *中的 *- (void)postEvent: (IJKFFMoviePlayerMessage )msg 方法中将其转化成通知
  [[NSNotificationCenter defaultCenter] postNotificationName:IJKMPMoviePlayerPlaybackDidFinishNotification
                object:self
                userInfo:@{
                    IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey: @(IJKMPMovieFinishReasonPlaybackError),
                    @"error": @(avmsg->arg1)}];

6.在工程中接收通知:
-(void)installMovieNotificationObservers {

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayBackDidFinish:)
                                                 name:IJKMPMoviePlayerPlaybackDidFinishNotification
                                               object:_player]; 
}

- (void)moviePlayBackDidFinish:(NSNotification*)notification {

    int reason = [[[notification userInfo] valueForKey:IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
    int errorCode = [[[notification userInfo] valueForKey:@"error"] intValue];
    switch (reason)   {
        case IJKMPMovieFinishReasonPlaybackError:
            if (errorCode == 19) {
                NSLog(@"硬解失败");
            }
            break;
        default:
            break;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 随着互联网技术的飞速发展,移动端播放视频的需求如日中天,由此也催生了一批开源/闭源的播放器,但是无论这个播放器功能...
    金山视频云阅读 46,854评论 28 170
  • 上图摘自 雷霄骅 雷神的博客 是FFmpeg中 ffplay.c的结构流程图 ijkplayer的ff_ffpla...
    Mr_Me阅读 8,835评论 0 4
  • 写在前面 前几篇文章从播放器初始化一直分析到了音频播放,其实从中基本能发现作者写ijkplayer的思路的。所以分...
    尸情化异阅读 17,795评论 9 21
  • 一个夜黑风高的晚上 出现一个 躺在床上的少女 她正做着梦 只见 一个白点 悄无声息地 钻进了她的脑袋 就在这时 眼...
    和煦雪阅读 4,030评论 0 1
  • 用孩子般的童心去善待世界,你会没有烦恼,没有忧愁,有的只是快乐,恬静而悠然,人生才充满想象,变得丰富而纯真。 当我...
    桢桢说阅读 3,056评论 0 0

友情链接更多精彩内容