最简单ffmpeg解码

1、概述

用ffmpeg解码的例子,把解码数据保存为yuv文件。

2、代码

/* 
 *最简单的FFmpeg的解码器
 *
 *缪国凯 Mickel
 *821486004@qq.com
 *
 *本程序实现了视频解码保存为yuv,写yuv是用文件方式写的,没用到muxer
 */

#include "stdafx.h"


#ifdef	__cplusplus
extern "C"
{
#endif
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
//#include "libavfilter/avfiltergraph.h"
//#include "libavfilter/avcodec.h"
//#include "libavfilter/buffersink.h"
//#include "libavfilter/buffersrc.h"
//#include "libavutil/avutil.h"
//#include "libavutil/opt.h"
//#include "libavutil/pixdesc.h"

#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
//#pragma comment(lib, "avdevice.lib")
//#pragma comment(lib, "avfilter.lib")
//#pragma comment(lib, "postproc.lib")
//#pragma comment(lib, "swresample.lib")
//#pragma comment(lib, "swscale.lib")
#ifdef __cplusplus
};
#endif

AVFormatContext *ifmt_ctx = NULL;

#include <stdio.h>

int openinputfile(const char* filename)
{
	int ret = 0;
	//open the input
	if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0)
	{
		printf("can not open input");
		return ret;
	}
	if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)))
	{
		printf("can not find input stream info");
		return ret;
	}

	//open the decoder
	for (int i = 0; i < ifmt_ctx->nb_streams; i++)
	{
		if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
		{
			ret = avcodec_open2(ifmt_ctx->streams[i]->codec, 
				avcodec_find_decoder(ifmt_ctx->streams[i]->codec->codec_id), NULL);

			if (ret < 0)
			{
				printf("can not open decoder");
				return ret;
			}

		}
	}

	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	if (argc < 2)
	{
		return -1;
	}
	AVPacket pkt_in, pkt_out;
	AVFrame *frame = NULL;
	unsigned int stream_index;
	av_register_all();

	if (openinputfile(argv[1]) < 0)
	{
		printf("failed to open input file");
		goto end;
	}

	FILE *p = NULL;
	p = fopen("test.yuv", "a+b");

	while(1)
	{
		if (av_read_frame(ifmt_ctx, &pkt_in) < 0)
		{
			break;
		}
		pkt_out.data = NULL;
		pkt_out.size = 0;
		av_init_packet(&pkt_out);
		stream_index = pkt_in.stream_index;
		frame = av_frame_alloc();
		int got_frame = -1;
		int ret = -1;

		if (ifmt_ctx->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
		{
			ret = avcodec_decode_video2(ifmt_ctx->streams[stream_index]->codec, frame, &got_frame, &pkt_in);

			if (ret < 0)
			{
				av_frame_free(&frame);
				printf("decoding video stream failed\n");
				break;
			}

			if (got_frame)
			{
				if (NULL != p)
				{
					int j;
					int height = ifmt_ctx->streams[stream_index]->codec->height;
					int width = ifmt_ctx->streams[stream_index]->codec->width;
					for(j=0; j<height; j++)
						fwrite(frame->data[0] + j * frame->linesize[0], 1, width, p);  
					for(j=0; j<height/2; j++)  
						fwrite(frame->data[1] + j * frame->linesize[1], 1, width/2, p);  
					for(j=0; j<height/2; j++)  
						fwrite(frame->data[2] + j * frame->linesize[2], 1, width/2, p);
				}
			}
		}
	}
	fclose(p);
end:
	avformat_close_input(&ifmt_ctx);

	getchar();
	return 0;
}

3、工程下载地址

http://download.csdn.net/detail/dancing_night/8822057

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dancing_night

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

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

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

打赏作者

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

抵扣说明:

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

余额充值