花满楼原创


AVPacket,是压缩数据的结构体(解码前或编码后的结构体)。

本文介绍FFmepg中常见结构AVPacekt,尽量用具体值来理解。

整个用于调试的代码可以这样写:

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

void show_frame(const char* filepath) {
    av_register_all();
    av_log_set_level(AV_LOG_DEBUG);
    AVFormatContext* formatContext = avformat_alloc_context();
    int status = 0;
    int success = 0;
    int videostreamidx = -1;
    AVCodecContext* codecContext = NULL;
    status = avformat_open_input(&formatContext, filepath, NULL, NULL);
    if (status == 0) {
        status = avformat_find_stream_info(formatContext, NULL);
        if (status >= 0) {
            for (int i = 0; i < formatContext->nb_streams; i ++) {
                if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
                    videostreamidx = i;
                    break;
                }
            }
            if (videostreamidx > -1) {
                AVStream* avstream = formatContext->streams[videostreamidx];
                codecContext = avstream->codec;
                AVCodec* codec = avcodec_find_decoder(codecContext->codec_id);
                if (codec) {
                    status = avcodec_open2(codecContext, codec, NULL);
                    if (status == 0) {
                        success = 1;
                    }
                }
            }
        }
        else {
            av_log(NULL, AV_LOG_DEBUG, "avformat_find_stream_info error\n");
        }

        if (success) {
            av_dump_format(formatContext, 0, filepath, 0);
            int gotframe = 0;
            AVFrame* frame = av_frame_alloc();
            int decodelen = 0;
            int limitcount = 10;
            int pcindex = 0;
            while (pcindex < limitcount) {
                AVPacket packet;
                av_init_packet( &packet );
                status = av_read_frame(formatContext, &packet);
                if (status < 0) {
                    if (status == AVERROR_EOF) {
                        av_log(NULL, AV_LOG_DEBUG, "read end for file\n");
                    }
                    else {
                        av_log(NULL, AV_LOG_DEBUG, "av_read_frame error\n");
                    }
                    av_packet_unref(&packet);
                    break;
                }
                else {
                    if (packet.stream_index == videostreamidx) {
                        decodelen = avcodec_decode_video2(codecContext, frame, &gotframe, &packet);
                        if (decodelen > 0 && gotframe) {
                            av_log(NULL, AV_LOG_DEBUG, "got one avframe, pcindex=%d\n", pcindex);
                        }
                    }
                }
                av_packet_unref(&packet);
                pcindex ++;
            }
            av_frame_free(&frame);
        }
        avformat_close_input(&formatContext);
    }
    avformat_free_context(formatContext);
}

int main(int argc, char *argv[])
{
    show_frame("moments.mp4");
    return 0;
}

av_read_frame函数可以取得一个AVPacket,所以在调用这个函数的地方下个断点,看一下AVPacet长什么样子。

编译脚本还是沿用之前介绍的makefile或直接用gcc来编译。

在没有调用av_read_frame前,AVPacket中的变量值:

调用av_read_frame后,AVPacket中的变量:

再一次av_read_frame后:

av_read_frame后,AVPacket也可能没有数据:

AVPacket是压缩数据,一个AVPacket,对于视频最多一帧(NALU),但对于音频就可能多帧。

AVPacket中的变量含义:

pts/dts,显示/解码时间戵,以packet所在的流的time_base为单位。
stream_index,所在流的索引。
data,avpacket拥有的数据。
size,avpacket的数据长度。
duration,avpacket的时长,同样以time_base为单位。

AVPacket结构,在libavcodec/avcodec.h中定义。

最新文章

  1. 微信5.4安卓版重回ios风格 导航菜单都放底栏位置
  2. asp.net在线预览txt文件(简单实现)
  3. [CareerCup] 9.2 Robot Moving 机器人移动
  4. PowerDesigner15在win7-64位系统下对MySQL反向工程
  5. python抓取网页例子
  6. iOS中AutoLayer自动布局流程及相关方法【转】
  7. Python进阶之返回函数
  8. SQLSERVER常用脚本整理
  9. ODPS 下一个map / reduce 准备
  10. Cracking the Coding Interview 题目分析笔记—— Array and String
  11. PAT1052:Linked List Sorting
  12. 在windows系统下安装linux虚拟机(VMware)
  13. tomcat日志格式中的含义
  14. zabbix监控tomcat(使用jmx监控,但不使用系统自带模版)
  15. 细说shiro之自定义filter
  16. 第二章 函数和window对象
  17. bzoj3976
  18. googletest--Test Fixture
  19. Git 及 GitHub 使用
  20. SSH版最大会话连接数

热门文章

  1. 温故而知新 Volley源码解读与思考
  2. 基于场景解析RecyclerView的回收复用机制原理
  3. 最全的命令行(gradle)打包安卓apk
  4. JDBC连接池-C池3P0连接
  5. Java常用API
  6. [板子]segTree
  7. gbdt的面试要点总结-上篇
  8. display:table 表格布局
  9. 【WEB API项目实战干货系列】- WEB API入门(一)
  10. Centos6上进行Mysql5.6安装和主从复制部署