linux 平台最简FFMPEG 程序

    最近在学习FFMPEG,看了很多的例子都是在Windows下的,这里提供一个linux下的一个简单程序,由雷神的工程修改而来。

#include <stdio.h>
#define __STDC_CONSTANT_MACROS
#include "avformat.h"
#include "avcodec.h"
#include "swscale.h"

int main(int argc, char* argv[])
{
	AVFormatContext	*pFormatCtx;
	int				i, videoindex;
	AVCodecContext	*pCodecCtx;
	AVCodec			*pCodec;
	AVFrame	*pFrame,*pFrameYUV;
	uint8_t *out_buffer;
	AVPacket *packet;
	int y_size;
	int ret, got_picture;
	struct SwsContext *img_convert_ctx;
	//输入文件路径
	char filepath[]="../testfile/school.flv";

	int frame_cnt;
    
	av_register_all();                       /* 注册复用器 编码器 */
	avformat_network_init();                 /* 打开网络流 */
	pFormatCtx = avformat_alloc_context();   /* 分配内存 */

	if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){     		
        printf("Couldn't open input stream.\n");
		return -1;
	}
	if(avformat_find_stream_info(pFormatCtx,NULL)<0){    /* 读取一部分视音频数据并且获得一些相关的信息 */
		printf("Couldn't find stream information.\n");
		return -1;
	}
	videoindex=-1;
	for(i=0; i<pFormatCtx->nb_streams; i++) 
		if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
			videoindex=i;
			break;
		}
	if(videoindex==-1){
		printf("Didn't find a video stream.\n");
		return -1;
	}

	pCodecCtx=pFormatCtx->streams[videoindex]->codec;
	pCodec=avcodec_find_decoder(pCodecCtx->codec_id); /* 查找FFmpeg的解码器 */
	if(pCodec==NULL){
		printf("Codec not found.\n");
		return -1;
	}
	if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){    /* 初始化一个视音频编解码器的AVCodecContext  */
		printf("Could not open codec.\n");
		return -1;
	}

    /* printf information of the input video */
    printf("AVFormatContext AVInputFormat name = %s  \n",pFormatCtx->iformat->name);
    printf("Number of elements in AVFormatContext.streams = %d  \n",pFormatCtx->nb_streams);
    printf("Duration of the stream, in AV_TIME_BASE fractional = %d  \n",pFormatCtx->duration);
    printf("Total stream bitrate in   %d  bit/s \n",pFormatCtx->bit_rate);

    printf("picture width   =  %d \n",pCodecCtx->width);
    printf("picture height  =  %d \n",pCodecCtx->height);
    


	pFrame=av_frame_alloc();        /* 分配一个 AVFrame 的内存*/
	pFrameYUV=av_frame_alloc();
	out_buffer=(uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)); /*内存分配函数 */
	avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); /* 为已经分配的空间的结构体AVPicture挂上一段用于保存数据的空间 */
	packet=(AVPacket *)av_malloc(sizeof(AVPacket));

	printf("--------------- File Information ----------------\n");
	av_dump_format(pFormatCtx,0,filepath,0);
	printf("-------------------------------------------------\n");
    
	img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 
		pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);   /* 初始化SwsContext的函数 */

	frame_cnt=0;

    //FILE* h264_fd = fopen("test.h264", wb+);
	while(av_read_frame(pFormatCtx, packet)>=0){
		if(packet->stream_index==videoindex){
            
           // fwrite(packet->data,packet->size, 1 h264_fd);
			ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);  /* 解码一帧视频数据 */
			if(ret < 0){
				printf("Decode Error.\n");
				return -1;
			}
			if(got_picture){
				sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, 
					pFrameYUV->data, pFrameYUV->linesize);                       /* 转换像素的函数 */
				//printf("Decoded frame index: %d\n",frame_cnt);
				frame_cnt++;

			}
		}
		av_free_packet(packet);
	}

    //fclose(h264_fd);
	sws_freeContext(img_convert_ctx);

	av_frame_free(&pFrameYUV);
	av_frame_free(&pFrame);
	avcodec_close(pCodecCtx);
	avformat_close_input(&pFormatCtx);

	return 0;
}

    Makefile 文件如下,头文件和库文件的目录会因为安装目录的不同而不同。

OUT_APP		 = test
INCLUDE_PATH = /usr/local/include/
INCLUDE = -I$(INCLUDE_PATH)libavutil/ -I$(INCLUDE_PATH)libavdevice/ \
			-I$(INCLUDE_PATH)libavcodec/ -I$(INCLUDE_PATH)libswresample \
			-I$(INCLUDE_PATH)libavfilter/ -I$(INCLUDE_PATH)libavformat \
			-I$(INCLUDE_PATH)libswscale/

FFMPEG_LIBS = -lavformat -lavutil -lavdevice -lavcodec -lswresample -lavfilter -lswscale
SDL_LIBS	= 
LIBS		= $(FFMPEG_LIBS)$(SDL_LIBS)

COMPILE_OPTS = $(INCLUDE)
C 			 = c
OBJ 		 = o
C_COMPILER   = cc
C_FLAGS 	 = $(COMPILE_OPTS) $(CPPFLAGS) $(CFLAGS)

LINK 		 = cc -o 
LINK_OPTS    = -lz -lm  -lpthread
LINK_OBJ	 = echo_information.o 

.$(C).$(OBJ):
	$(C_COMPILER) -c $(C_FLAGS) $<


$(OUT_APP): $(LINK_OBJ)
	$(LINK)$@  $(LINK_OBJ)  $(LIBS) $(LINK_OPTS)

clean:
		-rm -rf *.$(OBJ) $(OUT_APP) core *.core *~ include/*~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

li_wen01

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

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

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

打赏作者

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

抵扣说明:

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

余额充值