h264转yuv

开发环境

操作系统: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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

都市无名者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值