Android万能视频播放器02-获取视频AVFrame的帧数据

解码

解码步骤:

步骤一:

AVPacket *avPacket = av_packet_alloc();
queue->getAvpacket(avPacket);
avcodec_send_packet(avCodecContext, avPacket);

步骤二:

AVFrame *avFrame = av_frame_alloc();
avcodec_receive_frame(avCodecContext, avFrame);

将前面得到的AVPacket发送到解码器进行解码:

void *playVideo(void *data){
    JfVideo *video = (JfVideo *)data;

    while (video->playStatus != NULL && !video->playStatus->exit){
        if (video->playStatus->seeking){
            av_usleep(1000 * 100);
            continue;
        }
        if (video->queue->getQueueSize() == 0){//加载状态
            if (!video->playStatus->loading){
                video->playStatus->loading = true;
                video->callJava->onCallLoading(CHILD_THREAD, true);
            }
            av_usleep(1000 * 100);
            continue;
        } else {
            if (video->playStatus->loading){
                video->playStatus->loading = false;
                video->callJava->onCallLoading(CHILD_THREAD, false);
            }
        }

        /*AVPacket *avPacket = av_packet_alloc();
        if (video->queue->getAVPacket(avPacket) == 0){
            //解码渲染
            LOGD("线程中获取视频AVPacket");
        }
        av_packet_free(&avPacket);//AVPacket中的第一个参数,就是引用,减到0才真正释放
        av_free(avPacket);
        avPacket = NULL;*/

        AVPacket *avPacket = av_packet_alloc();
        if (video->queue->getAVPacket(avPacket) != 0){

            av_packet_free(&avPacket);//AVPacket中的第一个参数,就是引用,减到0才真正释放
            av_free(avPacket);
            avPacket = NULL;
            continue;
        }
        
        if (avcodec_send_packet(video->pVCodecCtx,avPacket) != 0){

            av_packet_free(&avPacket);//AVPacket中的第一个参数,就是引用,减到0才真正释放
            av_free(avPacket);
            avPacket = NULL;
            continue;
        }
        AVFrame *avFrame = av_frame_alloc();
        if (avcodec_receive_frame(video->pVCodecCtx,avFrame) != 0){
            av_frame_free(&avFrame);
            av_free(avFrame);
            avFrame = NULL;
            av_packet_free(&avPacket);//AVPacket中的第一个参数,就是引用,减到0才真正释放
            av_free(avPacket);
            avPacket = NULL;
            continue;
        }

        if (LOG_DEBUG){
            LOGD("子线程解码一个AVFrame成功");
        }

        av_frame_free(&avFrame);
        av_free(avFrame);
        avFrame = NULL;
        av_packet_free(&avPacket);//AVPacket中的第一个参数,就是引用,减到0才真正释放
        av_free(avPacket);
        avPacket = NULL;
    }
    pthread_exit(&video->thread_play);
}

释放视频相关的资源文件

释放步骤

1、释放队列

delete(queue);

2、释放解码器上下文

avcodec_close(avCodecContext);
avcodec_free_context(&avCodecContext);

实现

void JfVideo::release() {
    if (queue != NULL){
        delete(queue);
        queue = NULL;
    }

    if (pVCodecCtx != NULL){
        avcodec_close(pVCodecCtx);
        avcodec_free_context(&pVCodecCtx);
        pVCodecCtx = NULL;
    }

    if (playStatus != NULL){
        playStatus = NULL;
    }

    if (callJava != NULL){
        callJava = NULL;
    }
}

void JfFFmpeg::release() 方法中调用!

猜你喜欢

转载自blog.csdn.net/weixin_33851177/article/details/87563841