#define _CRT_SECURE_NO_WARNINGS
#include
extern "C" {
#include
#include
#include
#include
}
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"swscale.lib")
int main()
{
FILE* fp1 = fopen("yuv420_y.y", "wb+");
FILE* fp2 = fopen("yuv420_u.y", "wb+");
FILE* fp3 = fopen("yuv420_v.y", "wb+");
printf("%s\n", avcodec_configuration());//测试DLL
av_register_all();//注册DLL
/*avformat_network_init();//网络*/
AVFormatContext* pFormat = NULL;//设备上下文
const char* path = "11.mp4";
/*const char* path = "http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5000000010000030951/index.m3u8?channel-";
AVDictionary* OPT=NULL;
av_dict_set(&OPT,"rtsp_transport","tcp",0)//设置网络信息;
av_dict_set(&OPT, "max_delay", "550", 0);*/
int ret = avformat_open_input(&pFormat,path,NULL, NULL);//打开网络视频文件
if (ret)
{
printf("avformat_open_input failed\n");
return -1;
}
printf("avformat_open_input success\n");
ret = avformat_find_stream_info(pFormat,NULL);//寻找流信息 h264 h w
if (ret<0)
{
printf("avformat_find_stream_info failed\n");
return -1;
}
printf("avformat_find_stream_info success\n");
int time = pFormat->duration;//获取时长,单位us;
int mbittime = (time / 1000000) / 60;//得到多少分钟
int mmintime = (time / 1000000) % 60;//得到多少秒
printf("mbittime=%d分,mmintime=%d秒\n", mbittime, mmintime);
av_dump_format(pFormat,NULL,path,0);//显示文件信息
//寻找流
int VideoStream = -1, AudioStream = -1;
VideoStream = av_find_best_stream(pFormat,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,NULL);
AudioStream = av_find_best_stream(pFormat, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, NULL);
AVCodec *vCodec = avcodec_find_decoder(pFormat->streams[VideoStream]->codec->codec_id);
if (!vCodec)
{
printf("avcodec_find_decoder failed\n");
return -1;
}
printf("avcodec_find_decoder success\n");
//打开解码器
ret = avcodec_open2(pFormat->streams[VideoStream]->codec, vCodec,NULL);
if (ret)
{
printf("avcodec_open2 failed\n");
return -1;
}
printf("avcodec_open2 success\n");
//开始解码视频
//申请原始空间 =>>创建帧空间
AVFrame* frame = av_frame_alloc();
AVFrame* frameYUV = av_frame_alloc();
int width = pFormat->streams[VideoStream]->codec->width;
int height = pFormat->streams[VideoStream]->codec->height;
int fmt = pFormat->streams[VideoStream]->codec->pix_fmt;
//分配空间,进行图像转换
int nSize = avpicture_get_size(AV_PIX_FMT_YUV420P,width,height);
uint8_t* buff = NULL;
buff = (uint8_t*)av_malloc(nSize);
//一帧图像
avpicture_fill((AVPicture*)frameYUV, buff, AV_PIX_FMT_YUV420P, width, height);
AVPacket* packet = (AVPacket*)av_malloc(sizeof(AVPacket));
//转换上下文
//sws_getCachedContext//单线程
SwsContext* swsCtx = NULL;
swsCtx = sws_getContext(width, height,(AVPixelFormat)fmt,
width, height, AV_PIX_FMT_YUV420P,SWS_BICUBIC,NULL,NULL,NULL);
//读帧
int go = 0;
int FrameCount = 0;
while (av_read_frame(pFormat, packet) >= 0)
{
//判断stream_index
if (packet->stream_index == AVMEDIA_TYPE_VIDEO)
{
ret = avcodec_decode_video2(pFormat->streams[VideoStream]->codec,frame,&go,packet);
if (ret <0)
{
printf("avcodec_decode_video2 failed\n");
return -1;
}
if (go)
{
sws_scale(swsCtx,(const uint8_t**)frame->data,frame->linesize,0,
height,frameYUV->data,frameYUV->linesize);
fwrite(frameYUV->data[0], 1, width * height, fp1);
fwrite(frameYUV->data[1], 1, width * height / 4, fp2);
fwrite(frameYUV->data[2], 1, width * height / 4, fp3);
FrameCount++;
printf("frame index:%d\n", FrameCount);
}
}
av_free_packet(packet);
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
sws_freeContext(swsCtx);
av_frame_free(&frame);
av_frame_free(&frameYUV);
avformat_close_input(&pFormat);
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)