ffmepg_sdk yuvコーデック

6449 ワード

yuvファイルにh 264を符号化し、復号化した後、使用する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
"); 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
"); exit(1); } f_in = fopen(inputfilename,"rb+"); if (!f_in){ fprintf(stderr, "could not open %s
", inputfilename); exit(1); } f_out = fopen(outputfilename, "wb+"); if (!f_out){ fprintf(stderr, "could not open %s
", 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
",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
"); exit(1); } f_in = fopen(inputfilename,"rb+"); if (!f_in){ fprintf(stderr, "could not open %s
", inputfilename); exit(1); } f_out = fopen(outputfilename, "wb+"); if (!f_out){ fprintf(stderr, "could not open %s
", 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
",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; }