开发环境
操作系统:win10
IDE:vs2019
第三方库:ffmpeg5.1
#include <stdio.h>
#include <stdlib.h>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavutil/ffversion.h"
#include "libswresample/swresample.h"
#include "libswscale/swscale.h"
#include "libpostproc/postprocess.h"
}
int purecodec(int argc, char* argv[])
{
const AVCodec* pCodec;
AVCodecContext* pCodecCtx = NULL;
AVCodecParserContext* pCodecParserCtx = NULL;
FILE* fp_in;
FILE* fp_out;
AVFrame* pFrame;
const int in_buffer_size = 4096;
uint8_t in_buffer[in_buffer_size + 10] = { 0 };
uint8_t* cur_ptr;
int cur_size;
AVPacket* packet;
int ret, got_picture;
int y_size;
AVCodecID codec_id = AV_CODEC_ID_H264;
char filepath_in[] = "encode.h264";
char filepath_out[] = "bigbuckbunny_480x272.yuv";
pCodec = avcodec_find_decoder(codec_id);
if (!pCodec) {
printf("Codec not found\n");
return -1;
}
pCodecCtx = avcodec_alloc_context3(pCodec);
if (!pCodecCtx) {
printf("Could not allocate video codec context\n");
return -1;
}
pCodecParserCtx = av_parser_init(codec_id);
if (!pCodecParserCtx) {
printf("Could not allocate video parser context\n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
printf("Could not open codec\n");
return -1;
}
//Input File
fopen_s(&fp_in, filepath_in, "rb");
if (!fp_in) {
printf("Could not open input stream\n");
return -1;
}
//Output File
fopen_s(&fp_out, filepath_out, "wb");
if (!fp_out) {
printf("Could not open output YUV file\n");
return -1;
}
pFrame = av_frame_alloc();
packet = av_packet_alloc();
while (1)
{
cur_size = fread(in_buffer, 1, in_buffer_size, fp_in);
if (cur_size == 0)
break;
cur_ptr = in_buffer;
while (cur_size > 0) {
int len = av_parser_parse2(
pCodecParserCtx, pCodecCtx,
&packet->data, &packet->size,
cur_ptr, cur_size,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
cur_ptr += len;
cur_size -= len;
if (packet->size == 0)
continue;
//Some Info from AVCodecParserContext
printf("[Packet]Size:%6d\t", packet->size);
switch (pCodecParserCtx->pict_type) {
case AV_PICTURE_TYPE_I: printf("Type:I\t"); break;
case AV_PICTURE_TYPE_P: printf("Type:P\t"); break;
case AV_PICTURE_TYPE_B: printf("Type:B\t"); break;
default: printf("Type:Other\t"); break;
}
printf("Number:%4d\n", pCodecParserCtx->output_picture_number);
if (avcodec_send_packet(pCodecCtx, packet) == 0) {
while (avcodec_receive_frame(pCodecCtx, pFrame) == 0) {
int w = pFrame->width;
int h = pFrame->height;
fwrite(pFrame->data[0], 1, w * h, fp_out);//y
fwrite(pFrame->data[1], 1, w * h / 4, fp_out);//u
fwrite(pFrame->data[2], 1, w * h / 4, fp_out);//v
}
}
}
}
fclose(fp_in);
fclose(fp_out);
av_parser_close(pCodecParserCtx);
av_packet_free(&packet);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
av_free(pCodecCtx);
return 0;
}