• [ffmpeg] 解码


    #include
    #include 
    #include 
    using namespace std;
    extern "C"
    {
    #include 
    #include 
    }
    
    #pragma comment(lib, "avcodec.lib")
    #pragma comment(lib, "avutil.lib")
    
    int main(int argc, char* argv[])
    {
    	// 分割 h264 存入 AVPacket
    	string filename = "test.h264";
    	ifstream ifs(filename, ios::binary);
    	if (!ifs) return -1;
    	unsigned char inbuf[4096] = { 0 };
    
    	AVCodecID codec_id = AV_CODEC_ID_H264;
    
    	// 1. 找解码器
    	auto codec = avcodec_find_decoder(codec_id);
    	// 2. 创建上下文
    	auto c = avcodec_alloc_context3(codec);
    	// 3. 打开上下文
    	avcodec_open2(c, NULL, NULL);
    
    	// 分割上下文
    	auto parser = av_parser_init(codec_id);
    
    	auto pkt = av_packet_alloc();
    	auto frame = av_frame_alloc();
    	while (!ifs.eof())
    	{
    		ifs.read((char*)inbuf, sizeof(inbuf));
    		int data_size = ifs.gcount(); // 读取的字节数
    		if (data_size <= 0) break;
    		// 通过 0001截断
    		auto data = inbuf;
    		while (data_size > 0)
    		{
    			// 通过 0001 截取输出到 AVPacket 返回帧大小
    			int 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)
    			{
    				//cout << pkt->size << " " << flush;
    				// 发送 packet 到解码线程
    				ret = avcodec_send_packet(c, pkt);
    				if (ret < 0)
    				{
    					break;
    				}
    				// 获取多帧解码数据
    				while (ret >= 0)
    				{
    					// 每次会调用 av_frame_unref
    					ret = avcodec_receive_frame(c, frame);
    					if (ret < 0)
    						break;
    					cout << frame->format << " " << flush;
    				}
    			}
    		}
    	}
    	av_packet_free(&pkt);
    
    	// 取出缓存数据
    	int ret = avcodec_send_packet(c, NULL);
    	while (ret >= 0)
    	{
    		ret = avcodec_receive_frame(c, frame);
    		if (ret < 0)
    			break;
    		cout << frame->format << "-" << flush;
    	}
    
    	av_parser_close(parser);
    	avcodec_free_context(&c);
    	av_frame_free(&frame);
    	av_packet_free(&pkt);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
  • 相关阅读:
    【Java Web】论坛帖子添加评论
    C语言校园家教管理系统
    python struct模块 处理字节流
    java面试题-并发编程相关面试题
    java对象半初始化问题是怎么回事
    html大学生网站开发实践作业:传统文化网页设计题材【绒花6页】HTML+CSS+JavaScript
    不擅于社交的原因?如何提高社交能力?
    实例分割Yolact边缘端部署 (三) 从onnx到caffemodel
    Java之TreeSet和TreeMap
    LSH-局部敏感哈希
  • 原文地址:https://blog.csdn.net/dss875914213/article/details/136334402