2020-08-18
2020-08-18 本文已影响0人
shaozq
#include <stdio.h>
#include "pch.h"
#define _CRT_SECURE_NO_WARNINGS
#define __STDC_CONSTANT_MACROS
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libswscale/swscale.h"
};
int main(int argc, char* argv[])
{
AVFormatContext* pAVFormatContext;
AVCodecContext* pAVCodecContext;
AVCodec* pAVCodec;
AVPacket* pAVPacket;
AVFrame* pAvFrame;
AVFrame* pFrameYUV;
int videoindex = -1;
uint8_t *out_buffer;
int frame_cnt = 0;
int got_pic, ret;
struct SwsContext *img_convert_ctx;
char filepath[] = "cuc_ieschool.flv";
FILE* file_yuv = fopen("shao_test.yuv", "wb+");
av_register_all();
avformat_network_init();
pAVFormatContext = avformat_alloc_context();
if (avformat_open_input(&pAVFormatContext, filepath, NULL, NULL) != 0) {
printf("Couldn't open input stream.\n");
return -1;
}
if (avformat_find_stream_info(pAVFormatContext, NULL) < 0) {
printf("Couldn't find stream information.\n");
return -1;
}
printf("video duration: %d", pAVFormatContext->duration);
printf("video formatName: %s", pAVFormatContext->iformat->name);
for (int i = 0; i < pAVFormatContext->nb_streams;i ++) {
if (pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoindex = i;
break;
}
}
if (videoindex == -1) {
printf("Didn't find a video stream.\n");
return -1;
}
pAVCodecContext = pAVFormatContext->streams[videoindex]->codec;
pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id);
printf("video width=%d , height = %d\n", pAVCodecContext->width,pAVCodecContext->height);
if (pAVCodec == NULL) {
printf("cannot find codec");
return -1;
}
if (avcodec_open2(pAVCodecContext,pAVCodec,NULL) < 0) {
printf("can not open file \n");
return -1;
}
av_dump_format(pAVFormatContext, 0, filepath, 0);
pAvFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
pAVPacket = reinterpret_cast<AVPacket*> (av_malloc(sizeof(AVPacket)));
out_buffer = (uint8_t*)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pAVCodecContext->width, pAVCodecContext->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pAVCodecContext->width, pAVCodecContext->height);
img_convert_ctx = sws_getContext(pAVCodecContext->width, pAVCodecContext->height, pAVCodecContext->pix_fmt,
pAVCodecContext->width, pAVCodecContext->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
int yuv_size = pAVCodecContext->width * pAVCodecContext->height;
while (av_read_frame(pAVFormatContext, pAVPacket) >= 0) {
if (pAVPacket->stream_index == videoindex) {
/*
* 在此处添加输出H264码流的代码
* 取自于packet,使用fwrite()
*/
ret = avcodec_decode_video2(pAVCodecContext, pAvFrame, &got_pic, pAVPacket);
if (ret < 0) {
printf("Decode Error.\n");
return -1;
}
if (got_pic) {
sws_scale(img_convert_ctx, (const uint8_t* const*)pAvFrame->data, pAvFrame->linesize, 0, pAVCodecContext->height,
pFrameYUV->data, pFrameYUV->linesize);
printf("Decoded frame index: %d\n", frame_cnt);
fwrite(pFrameYUV->data[0], 1, yuv_size, file_yuv);
fwrite(pFrameYUV->data[1], 1, yuv_size / 4, file_yuv);
fwrite(pFrameYUV->data[2], 1, yuv_size / 4, file_yuv);
/*
* 在此处添加输出YUV的代码
* 取自于pFrameYUV,使用fwrite()
*/
frame_cnt++;
}
}
av_free_packet(pAVPacket);
}
//FIX: Flush Frames remained in Codec
while (1) {
ret = avcodec_decode_video2(pAVCodecContext, pAvFrame, &got_pic, pAVPacket);
if (ret < 0)
break;
if (got_pic) {
fwrite(pAvFrame->data[0], 1, yuv_size, file_yuv);
fwrite(pAvFrame->data[1], 1, yuv_size / 4, file_yuv);
fwrite(pAvFrame->data[2], 1, yuv_size / 4, file_yuv);
printf("decode frame cuss %d\n", pAVPacket->dts);
}
av_free_packet(pAVPacket);
}
av_frame_free(&pAvFrame);
avcodec_close(pAVCodecContext);
avformat_close_input(&pAVFormatContext);
return 0;
}