旧代码
- 旧代码使用了很多过时的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 文件
