基于Microsoft Visual Studio2019环境编写ffmpeg视频解码代码

旧代码

  • 旧代码使用了很多过时的API,这些API使用后,vs会报编译器警告 (级别 3) C4996的错误
  • 即 函数被声明为已否决 报 C4996的错误
// test_ffmpeg.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define SDL_MAIN_HANDLED
#define __STDC_CONSTANT_MACROS
#pragma warning(disable: 4996)

#include <iostream>
#include <SDL2/SDL.h>

extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
}

int main(int argc,char* argv[])
{
	AVFormatContext *pFormatCtx;
	int i, videoindex;
	AVCodecContext* pCodeCtx;
	AVCodec* pCodec;
	AVFrame* pFrame, *pFrameYUV;
	uint8_t* out_buffer;
	AVPacket* packet;
	//int y_size;
	int ret, got_picture;
	struct SwsContext* img_convert_ctx;
	//输入文件的路径
	char filepath[] = "Titanic.ts";
	int frame_cnt;
	avformat_network_init();
	pFormatCtx = avformat_alloc_context();
	if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0) {
		std::cout << "Couldn't open input stream." << std::endl;
		return -1;
	}
	if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
		std::cout << "Couldn't find stream information." << std::endl;
		return -1;
	}
	videoindex = -1;
	for (i = 0;i < pFormatCtx->nb_streams;i++) {
		if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
			videoindex = i;
			break;
		}
	}
	if (videoindex == -1) {
		std::cout << "Didn't find a video stream." << std::endl;
		return -1;
	}
	pCodeCtx = pFormatCtx->streams[videoindex]->codec;
	pCodec = avcodec_find_decoder(pCodeCtx->codec_id);
	if (pCodec == NULL) {
		std::cout << "Codec not find!" << std::endl;
		return -1;
	}
	if (avcodec_open2(pCodeCtx, pCodec, NULL) < 0) {
		std::cout << "Could not open codec!" << std::endl;
		return -1;
	}
	/*
	此处添加输出视频信息的代码
	取自于pFormatCtx,使用std::cout输出
	*/
	pFrame = av_frame_alloc();
	pFrameYUV = av_frame_alloc();
	out_buffer = (uint8_t*)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodeCtx->width, pCodeCtx->height));
	avpicture_fill((AVPicture*)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodeCtx->width, pCodeCtx->height);
	packet = (AVPacket*)av_malloc(sizeof(AVPacket));
	//Output Info
	std::cout << "--------------------File Information--------------------" << std::endl;
	av_dump_format(pFormatCtx, 0, filepath, 0);
	std::cout << "--------------------------------------------------------" << std::endl;
	img_convert_ctx = sws_getContext(pCodeCtx->width, pCodeCtx->height, pCodeCtx->sw_pix_fmt,
		pCodeCtx->width, pCodeCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
	frame_cnt = 0;
	while (av_read_frame(pFormatCtx,packet)>=0)
	{
		if (packet->stream_index == videoindex) {
			/*
			在此处添加输出H264码流的代码
			取自于packet,使用fwrite()输出
			*/
			ret = avcodec_decode_video2(pCodeCtx, pFrame, &got_picture, packet);
			if (ret < 0) {
				std::cout << "Decode Frror!" << std::endl;
				return -1;
			}
			if (got_picture) {
				sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodeCtx->height,
					pFrameYUV->data, pFrameYUV->linesize);
				std::cout << "Decoded frame index"<< frame_cnt << std::endl;
			/*
			在此处添加输出H264码流的代码
			取自于packet,使用fwrite()输出
			*/
				frame_cnt++;
			}
		}
		av_free_packet(packet);
	}
	sws_freeContext(img_convert_ctx);
	av_frame_free(&pFrameYUV);
	av_frame_free(&pFrame);
	avcodec_close(pCodeCtx);
	avformat_close_input(&pFormatCtx);

	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值