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;
}