ffmpeg-3.1.5视频解码代码

本文介绍利用ffmpeg-3.1.5编写最简单的视频解码的代码。

对于使用ffmpeg进行解码的代码在网上已经有很多,例如最经典的雷博的代码:http://blog.csdn.net/leixiaohua1020/article/details/47068015

由于新版本的ffmpeg中的函数和旧版本的函数有较大区别,因此本文列出了利用最新版的ffmpeg编写视频解码的代码。

本代码只能解码视频,音频部分还没有加入代码中。

本代码实现的功能是将封装好的视频解码为YUV格式的视频。

#include <stdio.h>
extern "C"
{
#include "include\libavcodec\avcodec.h"
#include "include\libavformat\avformat.h"
#include "include\libavutil\imgutils.h"
};

#define __STDC_CONSTANT_MACROS

int _tmain(int argc, _TCHAR* argv[])
{
	//printf("%s", avcodec_configuration());
	AVFormatContext *formatctx;
	AVCodec *codec;
	AVCodecContext *codecctx = NULL;
	AVFrame *frame;
	AVFrame *frameYUV;
	AVPacket avpkt;
	AVPacket *pavpkt = &avpkt;

	//init
	av_register_all();
	avformat_network_init();
	formatctx = avformat_alloc_context();

	//输入文件路径
	char *fileName = "Titanic.ts";
	if (avformat_open_input(&formatctx,fileName,NULL,NULL)!=0)
	{
		printf("could not open input stream.\n");
		return -1;
	}
	if (avformat_find_stream_info(formatctx, NULL) < 0)
	{
		printf("could not find stream information.\n");
		return -1;
	}

	//output file
	FILE *outputfile = nullptr;
	char *outputfilename = "output.yuv";
	fopen_s(&outputfile, outputfilename, "wb");
	

	//find videoindex
	int videoindex = av_find_best_stream(formatctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
	if (videoindex < 0)
	{
		printf("could not find a video stream.\n");
		return -1;
	}

	//find the decoder
	codecctx = avcodec_alloc_context3(NULL);
	if (codecctx == NULL)
	{
		printf("could not allocate AVCodecContext.\n");
		return -1;
	}
	avcodec_parameters_to_context(codecctx, formatctx->streams[videoindex]->codecpar);
	codec = avcodec_find_decoder(codecctx->codec_id);
	if (codec == NULL)
	{
		printf("codec not found.\n");
		return -1;
	}

	//open the decoder
	if (avcodec_open2(codecctx, codec, NULL) < 0)
	{
		printf("could not open codec.\n");
		return -1;
	}

	//output information
	printf("---------------- File Information --------------\n");
	av_dump_format(formatctx, videoindex, fileName, 0);
	printf("------------------------------------------------\n");

	//pre decode
	av_init_packet(&avpkt);
	frame = av_frame_alloc();
	frameYUV = av_frame_alloc();
	int video_dst_bufsize = av_image_alloc((uint8_t**)frameYUV->data, frameYUV->linesize, codecctx->width, codecctx->height, codecctx->pix_fmt, 1);
	printf("decode video file %s to %s\n", fileName, outputfile);

	//decode
	int frame_count = 0;
	while (av_read_frame(formatctx,pavpkt)>=0)
	{
		if (pavpkt->stream_index == videoindex)
		{
			if (avcodec_send_packet(codecctx, pavpkt) != 0){
				printf("input AVPacket to decoder failed!\n");
				return -1;
			}
			while (0 == avcodec_receive_frame(codecctx, frame)){
				av_image_copy((uint8_t **)frameYUV->data,frameYUV->linesize,(const uint8_t **)frame->data,frame->linesize,codecctx->pix_fmt,codecctx->width,codecctx->height);
				fwrite(frameYUV->data[0], 1, video_dst_bufsize, outputfile);
				printf("decoded frame index: %d\n", frame_count);
				frame_count++;
			}
		}
		av_packet_unref(pavpkt);
	}
	
	fclose(outputfile);
	av_frame_free(&frame);
	av_frame_free(&frameYUV);
	avcodec_close(codecctx);
	avformat_close_input(&formatctx);

	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值