ffmpeg decoding process is the simplest and has the most complete comments

The first step is to define some variables that will be used next

There is a detailed explanation in the code, so I won’t describe it one by one.

#define INBUF_SIZE 4096
//输入文件路径和输出文件路径
    const char* filename, * outfilename;
    //编解码器结构体
    const AVCodec* codec;
    // 解析器上下文 这个东西是为了把你文件中的数据打包到我下面的AVPacket中去 必须要通过这个分成一包一包的 然后才能解压缩
    AVCodecParserContext* parser;
    //编解码器上下文 保存编解码器的一些相关信息
    AVCodecContext* c = NULL;
    //文件指针
    FILE* f;
    //解码后的数据放这里
    AVFrame* frame;
    //缓冲区 AV_INPUT_BUFFER_PADDING_SIZE为内存对齐需要多加的东西
    uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
    //临时的变量 主要是为了等会文件操作更加方便
    uint8_t* data;
    size_t   data_size;
    //验错处理
    int ret;
    //未解码的数据放这里
    AVPacket* pkt;

The second step is to allocate memory space to each variable and then find the encoderdecoder analyzer and open the codec and analyzer

    //输入文件路径和输出文件路径
    const char* filename, * outfilename;
    //编解码器结构体
    const AVCodec* codec;
    // 解析器上下文 这个东西是为了把你文件中的数据打包到我下面的AVPacket中去 必须要通过这个分成一包一包的 然后才能解压缩
    AVCodecParserContext* parser;
    //编解码器上下文 保存编解码器的一些相关信息
    AVCodecContext* c = NULL;
    //文件指针
    FILE* f;
    //解码后的数据放这里
    AVFrame* frame;
    //缓冲区 AV_INPUT_BUFFER_PADDING_SIZE为内存对齐需要多加的东西
    uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
    //临时的变量 主要是为了等会文件操作更加方便
    uint8_t* data;
    size_t   data_size;
    //验错处理
    int ret;
    //未解码的数据放这里
    AVPacket* pkt;
    filename = argv[1];
    outfilename = argv[2];
    //给pkt申请内存空间 用来存放未解码的数据
    pkt = av_packet_alloc();
    //把缓冲区后内存对齐的部分设置为0 以防以后出问题
    memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    //通过ID拿到对应的编解码器 这里是拿到h.264的编解码器
    codec = avcodec_find_decoder(AV_CODEC_ID_H264);
    //通过编解码器的ID来拿到对应的分析器 分析器是为了从文件流中读取packet
    parser = av_parser_init(codec->id);
    //给编解码器上下文分配内存空间
    c = avcodec_alloc_context3(codec);
    //打开编解码器 打开后一直存在 后续不需要指定
    avcodec_open2(c, codec, NULL);
    //打开文件
    f = fopen(filename, "rb");
    //给解码后的帧分配内存空间
    frame = av_frame_alloc();
    //读取文件
    while (!feof(f)) {
        data_size = fread(inbuf, 1, INBUF_SIZE, f);
        if (!data_size)
            break;
        //临时指针data指向inbuf
        data = inbuf;
        while (data_size > 0) {
            //把这个缓冲区内的数据打包成Packet放入pkt中
            ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
                data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
            data += ret;
            data_size -= ret;
            //读到一个包 解析一个包
            if (pkt->size)
                decode(c, frame, pkt, outfilename);
        }
    }
    //最后再解码一次 因为最后一帧还没有解析
    decode(c, frame, NULL, outfilename);
    //释放内存空间
    fclose(f);
    av_parser_close(parser);
    avcodec_free_context(&c);
    av_frame_free(&frame);
    av_packet_free(&pkt);

The third step is the decode function, which actually calls the decoder to decode.

static void decode(AVCodecContext* dec_ctx, AVFrame* frame, AVPacket* pkt,
    const char* filename)
{
    //缓冲区
    char buf[1024];
    //验错
    int ret;
    //把packet发到编解码器解析 之前已经打开了 所以现在直接发就是了
    ret = avcodec_send_packet(dec_ctx, pkt);
    while (ret >= 0) {
        //从解码器哪里拿到解码后的数据 并放入frame中
        ret = avcodec_receive_frame(dec_ctx, frame);
        //如果读到结尾了 那就停止
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            return;
        //下面两步就是把对应的数据写入文件 跟编解码没关系
        snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
        pgm_save(frame->data[0], frame->linesize[0],
            frame->width, frame->height, buf);
    }
}

About pgm_save function

static void pgm_save(unsigned char* buf, int wrap, int xsize, int ysize,
    char* filename)
{
    FILE* f;
    int i;
 
    f = fopen(filename, "w");
    fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
    for (i = 0; i < ysize; i++)
        fwrite(buf + i * wrap, 1, xsize, f);
    fclose(f);
}

Original text ffmpeg decoding process is the simplest and most complete with comments

★The business card at the end of the article allows you to receive free audio and video development learning materials, including (FFmpeg, webRTC, rtmp, hls, rtsp, ffplay, srs) and audio and video learning roadmap, etc.

See below! ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

 

Guess you like

Origin blog.csdn.net/yinshipin007/article/details/134752600