ffmepg_sdk yuv编解码

对yuv文件编码h264,在解码回来,使用的FFmpeg-full-SDK-3.2

 

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"

void video_encode(const char * inputfilename , const char *outputfilename)
{
	AVCodec *codec;
	AVCodecContext *c= NULL;
	int out_size, in_size, size,outbuf_size;
	FILE *f_out,*f_in;
	AVFrame *picture;
	uint8_t *outbuf, *picture_buf;
	int frame = 0;
	codec = avcodec_find_encoder(CODEC_ID_H264);
	if (!codec){
		fprintf(stderr, "codec not found\n");
		exit(1);
	}
	c = avcodec_alloc_context();
	picture= avcodec_alloc_frame();
	/* put sample parameters */
	c->bit_rate = 400000;
	/* resolution must be a multiple of two */
	c->width = 352;
	c->height = 288;
	/* frames per second */
	c->time_base.den = 25; 
	c->time_base.num = 1;
	/* emit one intra frame every ten frames */
	c->gop_size = 10;
	c->max_b_frames=1;
	c->pix_fmt = PIX_FMT_YUV420P;
	 /* open it */
	if (avcodec_open(c, codec) < 0){
		fprintf(stderr, "could not open codec\n");
		exit(1);
	}
	f_in = fopen(inputfilename,"rb+");
	if (!f_in){
		fprintf(stderr, "could not open %s\n", inputfilename);
		exit(1);	
	}
	f_out = fopen(outputfilename, "wb+");
	if (!f_out){
		fprintf(stderr, "could not open %s\n", outputfilename);
		exit(1);
	}
	/* alloc image and output buffer */
	outbuf_size = 100000;
	outbuf = (uint8_t *)malloc(outbuf_size);
	size = c->width * c->height;
	picture_buf = (uint8_t *)malloc((size * 3) / 2);/* size for YUV 420 */

	picture->data[0] = picture_buf;
	picture->data[1] = picture->data[0] + size;
	picture->data[2] = picture->data[1] + size / 4;
	picture->linesize[0] = c->width;
	picture->linesize[1] = c->width / 2;
	picture->linesize[2] = c->width / 2;
	for (;;){
		in_size = fread(picture_buf,sizeof(char),size * 3/2,f_in); 
		picture->data[0] = picture_buf;
		out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
		fwrite(outbuf, 1, out_size, f_out);
		if (in_size == 0)break;
		frame ++;
	}
	printf("frame=%d\n",frame);
	fclose(f_in);
	f_in = NULL;
	fclose(f_out);
	f_out = NULL;
	free(picture_buf);
	picture_buf = NULL;
	free(outbuf);
	outbuf = NULL;
	avcodec_close(c);
	av_free(c);
	c = NULL;
	av_free(picture);
	picture = NULL; 
}

int findStartCode (unsigned char *in_buf, int zeros_in_startcode)
{
	int info;
	int i;

	info = 1;
	for (i = 0; i < zeros_in_startcode; i++)
		if(in_buf[i] != 0)
			info = 0;

	if(in_buf[i] != 1)
		info = 0;
	return info;
}

int getNextNal(FILE* f_in, unsigned char* in_buf)
{
	int pos = 0;
	int startCodeFound = 0;
	int info2 = 0;
	int info3 = 0;
	while(!feof(f_in) && (in_buf[pos++]=fgetc(f_in))==0);

	while (!startCodeFound)
	{
		if (feof (f_in))
		{
			//			return -1;
			return pos-1;
		}
		in_buf[pos++] = fgetc (f_in);
		info3 = findStartCode(&in_buf[pos-4], 3);
		if(info3 != 1)
			info2 = findStartCode(&in_buf[pos-3], 2);
		startCodeFound = (info2 == 1 || info3 == 1);
	}
	fseek (f_in, -4, SEEK_CUR);
	return pos - 4;
}

void video_decode(const char * inputfilename , const char *outputfilename)
{
	FILE * f_in,*f_out;
	AVCodec *codec;
	AVCodecContext *c;
	AVFrame *picture;
	int nWrite; 
	int i,p; 
	int nalLen; 
	unsigned char* in_buf; 
	int got_picture, out_size;
	int frame = 0;
	codec = avcodec_find_decoder(CODEC_ID_H264); 
	c = avcodec_alloc_context(); 
	picture = avcodec_alloc_frame(); 
	if (avcodec_open(c, codec) < 0){
		fprintf(stderr, "could not open codec\n");
		exit(1);
	}
	f_in = fopen(inputfilename,"rb+");
	if (!f_in){
		fprintf(stderr, "could not open %s\n", inputfilename);
		exit(1);	
	}
	f_out = fopen(outputfilename, "wb+");
	if (!f_out){
		fprintf(stderr, "could not open %s\n", outputfilename);
		exit(1);
	}

	in_buf = (unsigned char*)calloc ( 100000, sizeof(char));

	while(!feof(f_in)) { 
		nalLen = getNextNal(f_in, in_buf); 
		out_size= avcodec_decode_video(c, picture, &got_picture, in_buf, nalLen); 
		if(out_size>0) 
		{ 
			for(i=0; i<c->height; i++)
				fwrite(picture->data[0] + i * picture->linesize[0], 1, c->width, f_out);
			for(i=0; i<c->height/2; i++)
				fwrite(picture->data[1] + i * picture->linesize[1], 1, c->width/2, f_out);
			for(i=0; i<c->height/2; i++)
				fwrite(picture->data[2] + i * picture->linesize[2], 1, c->width/2, f_out);			
			frame++;
		} 
	} 
	printf("frame=%d\n",frame);
	fclose(f_in); 
	fclose(f_out);
	avcodec_close(c); 
	av_free(c); 
	c = NULL; 
	av_free(picture); 
	picture = NULL; 
	free(in_buf); 
	in_buf = NULL; 

}

int main()
{
	avcodec_init(); 
	avcodec_register_all();

	//video_encode("video/14-31-01.yuv" ,"video/14-31-01_yuv_encode.264");
	//video_decode("video/14-31-01_yuv_encode.264" ,"video/14-31-01_h264_decode.yuv");

	//video_encode("video/22.yuv" ,"video/22_yuv_encode.264");
	//video_decode("video/22_yuv_encode.264" ,"video/22_h264_decode.yuv");


	//video_encode("video/flower_cif.yuv" ,"video/flower_cif_yuv_encode.264");
	//video_decode("video/flower_cif_yuv_encode.264" ,"video/flower_cif_h264_decode.yuv");

	return EXIT_SUCCESS;
}

你可能感兴趣的:(sdk)