ffmpeg的h264转yuv实例测试代码

#include 
#include 
#define INBUF_SIZE 4096*8

extern "C"{
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
}

typedef struct{
	AVCodec			*pCodec;			
	AVCodecContext	*pCodecContext;			
	AVCodecParserContext *pCodecParserCtx;	
	AVFrame			*frame;					
	AVPacket		pkt;					
} CodecCtx;

typedef struct{
	FILE *pFin;
	FILE *pFout;
	char *pNameIn;
	char *pNameOut;
} IOParam;

int Open_deocder(CodecCtx &ctx) {
	avcodec_register_all();
	av_init_packet(&(ctx.pkt));
	ctx.pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
	if (!ctx.pCodec)	return -1;

	ctx.pCodecContext = avcodec_alloc_context3(ctx.pCodec);
	if (!ctx.pCodecContext)	return -2;

	if (ctx.pCodec->capabilities & AV_CODEC_CAP_TRUNCATED)
		ctx.pCodecContext->flags |= AV_CODEC_FLAG_TRUNCATED;
	ctx.pCodecParserCtx = av_parser_init(AV_CODEC_ID_H264);
	if (!ctx.pCodecParserCtx)	return -3;

	if (avcodec_open2(ctx.pCodecContext, ctx.pCodec, NULL) < 0)
		return -4;

	ctx.frame = av_frame_alloc();
	if (!ctx.frame)	return -5;
	return 0;
}

int Open_files(IOParam &IOParam){
	IOParam.pFin = fopen(IOParam.pNameIn, "rb");
	if (!IOParam.pFin)	return -1;
	IOParam.pFout = fopen(IOParam.pNameOut, "wb");
	if (!IOParam.pFout)	return -2;
	return 0;
}

void Close_decoder(CodecCtx &ctx) {
	avcodec_close(ctx.pCodecContext);
	av_free(ctx.pCodecContext);
	av_frame_free(&(ctx.frame));
}

void Close_files(IOParam &IOParam){
	fclose(IOParam.pFin);
	fclose(IOParam.pFout);
}

void write_out_yuv_frame(const CodecCtx &ctx, IOParam &in_out){
	uint8_t **pBuf	= ctx.frame->data;
	int*	pStride = ctx.frame->linesize;
	for (int color_idx = 0; color_idx < 3; color_idx++){
		int	nWidth	= color_idx == 0 ? ctx.frame->width : ctx.frame->width / 2;
		int	nHeight = color_idx == 0 ? ctx.frame->height : ctx.frame->height / 2;
		for(int idx=0;idx < nHeight; idx++){
			fwrite(pBuf[color_idx],1, nWidth, in_out.pFout);
			pBuf[color_idx] += pStride[color_idx];
		}
		fflush(in_out.pFout);
	}
}

void errReport(char *info, int val){
	fprintf(stderr, "ERR: %s code=%d\n",info, val);
	getch();
	exit(0);
}

int main(){
	int ret = 0;
	uint8_t *pDataPtr = NULL;
	int uDataSize = 0;
	int got_picture, len;
	CodecCtx ctx;
	IOParam inputoutput;
	uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
	memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
	inputoutput.pNameIn = "output.h264";
	inputoutput.pNameOut = "output.yuv";
	if ((ret = Open_files(inputoutput)) < 0) 
		errReport("Open_files", ret);

	if ((ret = Open_deocder(ctx)) < 0) 
		errReport("Open_deocder", ret);

	printf("start...");
	while(1){
		uDataSize = fread_s(inbuf,INBUF_SIZE, 1, INBUF_SIZE, inputoutput.pFin);
		if (0 == uDataSize)	break;
		pDataPtr = inbuf;
		printf("\n%d:", uDataSize);
		while(uDataSize > 0){
			len = av_parser_parse2(ctx.pCodecParserCtx, ctx.pCodecContext, 
										&(ctx.pkt.data), &(ctx.pkt.size), 
										pDataPtr, uDataSize, 
										AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
			pDataPtr += len;
			uDataSize -= len;
			if (0 == ctx.pkt.size) 	continue;

			printf("#%d ", ctx.pkt.size);
			if ((ret = avcodec_decode_video2(ctx.pCodecContext, ctx.frame, &got_picture, &(ctx.pkt))) < 0)
				errReport("avcodec_decode_video2", ret);

			if (got_picture)
				write_out_yuv_frame(ctx, inputoutput);
		} //while(uDataSize > 0)
	}//while(1)
	printf("\navcodec_decode --- ok\n");
	Close_files(inputoutput);
	Close_decoder(ctx);
	getch();
	return 1;
}

结果:

start...
32768:#13608 #2874 #3004 #2936 #3056 #2834 #2947
32768:#3244 #2968 #3169 #2907 #2768 #3049 #2806 #2775
32768:#11163 #2199 #2656 #3094 #2748 #2635 #2704 #2514 #3012 #2668 #2343 #2419 #2178
32768:#2275 #2389 #8866 #1925 #2012 #1905 #2052 #1962 #1725 #1834 #1794 #1861 #2335
32768:#1896 #1602 #1536 #1444 #9972 #1218 #1151 #1360 #1262 #1600 #1335 #1274 #1579 #1559 #1928 #2488
32768:#2427 #1943 #2043 #11943 #1903 #2128 #2078 #2232 #2601 #2356
32768:#2450 #2199 #2394 #2386 #2480 #2353 #2713 #2703 #13073
32768:#2419 #2505 #2663 #2779 #2768 #2719 #2764 #2683 #2630 #2682 #2605 #2841
32768:#2775 #2850 #11016 #2287 #2290 #2185 #2309 #2282 #2538 #2497
32768:#2182 #2299 #2613 #2625 #2570 #2568 #2377 #6449 #2081 #2660 #3017 #2966
32768:#2847 #2868 #2600 #2528 #2639 #2381 #2126 #1993 #2004 #2429 #5975 #2424
32768:#2469 #2356 #2243 #2126 #2255 #2306 #2055 #2108 #2247 #2177 #2127 #1978 #2182
32768:#5718 #2514 #2368 #2419 #2708 #2211 #2412 #2239 #2051 #2650 #2483 #2633 #2903
32768:#2840 #2955 #7095 #2550 #3186 #3601 #4648 #4912
32768:#5104 #4509 #4306 #4736 #4201 #3756 #3812 #4556
32768:#4009 #12211 #2685 #2673 #2617 #3052 #2901 #3114
32768:#3404 #3301 #3253 #3252 #3187 #3003 #3159 #3386
32768:#12008 #2805 #3079 #3197 #3205 #3264 #3438 #3550 #3461
32768:#3627 #3374 #3051 #3046 #3568 #3012 #11388 #2462
32768:#2448 #3454 #3822 #3105 #3048 #3115 #2868 #2926 #2956 #2847 #2983
32768:#3165 #3523 #8540 #2347 #2312 #2208 #2235 #2143 #2161 #2040 #1888
32768:#1751 #1584 #1491 #1372 #1344 #1485 #5945 #1395 #2013 #1744 #1685 #1645 #1677 #1668 #1653 #1546 #1595
32768:#1955 #2053 #2062 #1917 #7307 #1926 #2274 #2309 #2560 #2909 #3008 #3094
32768:#3380 #3566 #3714 #4090 #4126 #4283 #4272
32768:#9617 #3941 #3591 #3359 #3126 #2962 #2788 #2790 #2940 #3207
32768:#3072 #2779 #2873 #3136 #3133 #9304 #2647 #2782 #2966
32768:#2929 #3104 #3135 #3210 #3204 #3096 #3418 #3378 #3414 #3331
32768:#3445 #9037 #3093 #2948 #2929 #3082 #2819 #2603 #2729
17267:#2642 #2608 #2875 #2633 #2690 #2728
avcodec_decode --- ok


你可能感兴趣的:(ffmpeg)