美文网首页
ijkPlayer.6

ijkPlayer.6

作者: 搁浅的三刀流zoro | 来源:发表于2019-12-30 15:28 被阅读0次
    ijkplayer简要启动流程.png

    经过上面流程,ijkplayer已经完成初始化流程,接下来是线程处理
    先来看看stream_open,其做了大致如下工作->初始化VideoState,创建音视频PacketQueue&FrameQueue用来准备处理数据,初始化video_refresh_thread&read_thread,初始化解码器

    static VideoState *stream_open(FFPlayer *ffp, const char *filename, AVInputFormat *iformat)
    {
        assert(!ffp->is);
        //ffplay context
        VideoState *is;
        //分配内存 
        is = av_mallocz(sizeof(VideoState));
        if (!is)
            return NULL;
        //复制filename值
        is->filename = av_strdup(filename);
        if (!is->filename)
            goto fail;
        is->iformat = iformat;
        //设置video位置
        is->ytop    = 0;
        is->xleft   = 0;
    #if defined(__ANDROID__)
        if (ffp->soundtouch_enable) {
            is->handle = ijk_soundtouch_create();
        }
    #endif
    
        /* start video display */
        //创建视频解码后队列
        //&is->pictq  帧队列
        //&is->videoq 视频数据队列
        if (frame_queue_init(&is->pictq, &is->videoq, ffp->pictq_size, 1) < 0)
            goto fail;
        //创建字幕解码后队列
        if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
            goto fail;
        //创建视音频码后队列
        if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
            goto fail;
    
        //创建视频 音频 字幕 解码前队列
        if (packet_queue_init(&is->videoq) < 0 ||
            packet_queue_init(&is->audioq) < 0 ||
            packet_queue_init(&is->subtitleq) < 0)
            goto fail;
    
        //SDL_CreateCond  -->continue_read_thread
        if (!(is->continue_read_thread = SDL_CreateCond())) {
            av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
            goto fail;
        }
        //视频精确定位线程
        if (!(is->video_accurate_seek_cond = SDL_CreateCond())) {
            av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
            ffp->enable_accurate_seek = 0;
        }
        //音频精确定位线程
        if (!(is->audio_accurate_seek_cond = SDL_CreateCond())) {
            av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
            ffp->enable_accurate_seek = 0;
        }
    
        //初始化时钟 serial 是queue_serial 队列序列号 
        init_clock(&is->vidclk, &is->videoq.serial);
        init_clock(&is->audclk, &is->audioq.serial);
        init_clock(&is->extclk, &is->extclk.serial);
    
        
        is->audio_clock_serial = -1;
        //设置音量
        if (ffp->startup_volume < 0)
            av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", ffp->startup_volume);
        if (ffp->startup_volume > 100)
            av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", ffp->startup_volume);
        ffp->startup_volume = av_clip(ffp->startup_volume, 0, 100);
        ffp->startup_volume = av_clip(SDL_MIX_MAXVOLUME * ffp->startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
        is->audio_volume = ffp->startup_volume;
        is->muted = 0;
        is->av_sync_type = ffp->av_sync_type;
    
        //播放互斥锁
        is->play_mutex = SDL_CreateMutex();
        //精确定位互斥锁
        is->accurate_seek_mutex = SDL_CreateMutex();
        ffp->is = is;
        is->pause_req = !ffp->start_on_prepared;
        //视频刷新线程
        is->video_refresh_tid = SDL_CreateThreadEx(&is->_video_refresh_tid, video_refresh_thread, ffp, "ff_vout");
        if (!is->video_refresh_tid) {
            av_freep(&ffp->is);
            return NULL;
        }
    
        is->initialized_decoder = 0;
        //读线程
        is->read_tid = SDL_CreateThreadEx(&is->_read_tid, read_thread, ffp, "ff_read");
        if (!is->read_tid) {
            av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
            goto fail;
        }
    
        if (ffp->async_init_decoder && !ffp->video_disable && ffp->video_mime_type && strlen(ffp->video_mime_type) > 0
                        && ffp->mediacodec_default_name && strlen(ffp->mediacodec_default_name) > 0) {
            if (ffp->mediacodec_all_videos || ffp->mediacodec_avc || ffp->mediacodec_hevc || ffp->mediacodec_mpeg2) {
                //初始化解码器
                decoder_init(&is->viddec, NULL, &is->videoq, is->continue_read_thread);
                ffp->node_vdec = ffpipeline_init_video_decoder(ffp->pipeline, ffp);
            }
        }
        is->initialized_decoder = 1;
    
        return is;
    fail:
        is->initialized_decoder = 1;
        is->abort_request = true;
        if (is->video_refresh_tid)
            SDL_WaitThread(is->video_refresh_tid, NULL);
        stream_close(ffp);
        return NULL;
    }
    
    stream_open.png

    相关文章

      网友评论

          本文标题:ijkPlayer.6

          本文链接:https://www.haomeiwen.com/subject/ttqlyctx.html