生活随笔
收集整理的這篇文章主要介紹了
yuv编码成h264格式写成文件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
yuv編碼成h264格式寫成文件
(使用ffmpeg 編碼yuv420p編碼成h264格式)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>#include <libavcodec/avcodec.h>
#include <libavutil/time.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>static int encode(AVCodecContext
* enc_ctx
, AVFrame
* frame
, AVPacket
* pkt
, FILE
* outfile
)
{int ret
;ret
= avcodec_send_frame(enc_ctx
, frame
);if(ret
< 0){fprintf(stderr, "avcodec_send_frame() failed!\n");return -1;}while (ret
>= 0){ret
= avcodec_receive_packet(enc_ctx
, pkt
);if(ret
== AVERROR(EAGAIN
) || ret
== AVERROR_EOF
){return 0;}else if(ret
< 0){fprintf(stderr, "avcodec_receive_packet() failed!\n");return -1;}fwrite(pkt
->data
, 1, pkt
->size
, outfile
);}}int main()
{printf("Hello video encoder!\n");char* in_yuv_file
= "test_yuv420p_1280x720.yuv";char* out_h264_file
= "test_420p_1280x720.h264";FILE
* infile
= NULL;FILE
* outfile
= NULL;const char* codec_name
= "libx264";const AVCodec
* codec
= NULL;AVCodecContext
* codec_ctx
= NULL;AVFrame
* frame
= NULL;AVPacket
* pkt
= NULL;int ret
= 0;codec
= avcodec_find_encoder_by_name(codec_name
);if(!codec
){fprintf(stderr, "avcodec_find_encoder_by_name() failed!\n");return 0;}codec_ctx
= avcodec_alloc_context3(codec
);if(!codec_ctx
){fprintf(stderr, "avcodec_alloc_context3() failed!\n");return 0;}codec_ctx
->width
= 1280;codec_ctx
->height
= 720;AVRational time_base
= {1, 25};AVRational framerate
= {25, 1};codec_ctx
->time_base
= time_base
;codec_ctx
->framerate
= framerate
;codec_ctx
->gop_size
= 25;codec_ctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;if(codec
->id
== AV_CODEC_ID_H264
){ret
= av_opt_set(codec_ctx
->priv_data
, "profile", "main", 0);if(ret
!= 0){sprintf(stderr,"av_opt_set() profile = main failed!\n");}ret
= av_opt_set(codec_ctx
->priv_data
, "preset", "medium", 0);if(ret
!= 0){sprintf(stderr, "av_opt_set() preset = medium failed!\n");}ret
= av_opt_set(codec_ctx
->priv_data
, "tune", "zerolatency", 0);if(ret
!= 0){sprintf(stderr, "av_opt_set() tune = zerolatency failed!\n");}}codec_ctx
->bit_rate
= 3000000;ret
= avcodec_open2(codec_ctx
, codec
, NULL);if(ret
< 0){fprintf(stderr, "avcodec_open2() failed!\n");return 0;}infile
= fopen(in_yuv_file
, "rb");if(!infile
){fprintf(stderr, "fopen() in_yuv_file failed!\n");return 0;}outfile
= fopen(out_h264_file
, "wb");if(!outfile
){fprintf(stderr, "fopen() out_h264_file failed!\n");return 0;}pkt
= av_packet_alloc();if(!pkt
){fprintf(stderr, "av_packet_alloc() failed!\n");return 0;}frame
= av_frame_alloc();if(!frame
){fprintf(stderr, "av_frame_alloc() failed!\n");return 0;}frame
->width
= codec_ctx
->width
;frame
->height
= codec_ctx
->height
;frame
->format
= codec_ctx
->pix_fmt
;int frame_bytes
= av_image_get_buffer_size(frame
->format
, frame
->width
,frame
->height
, 1);printf("frame_bytes = %d\n", frame_bytes
);uint8_t
* yuv_buf
= (uint8_t
*)malloc(frame_bytes
);if(!yuv_buf
){printf("yuv_buf malloc() failed!\n");return 0;}int64_t pts
= 0;while (1){memset(yuv_buf
, 0, frame_bytes
);size_t read_bytes
= fread(yuv_buf
, 1, frame_bytes
, infile
);if(read_bytes
<= 0){fprintf(stderr, "fread end!\n");break;}int fill_size
= av_image_fill_arrays(frame
->data
, frame
->linesize
, yuv_buf
,frame
->format
, frame
->width
, frame
->height
, 1);if(fill_size
!= frame_bytes
){fprintf(stderr, "av_image_fill_arrays failed!\n");break;}pts
+= 40;frame
->pts
= pts
;ret
= encode(codec_ctx
, frame
, pkt
, outfile
);if(ret
< 0){fprintf(stderr, "encode failed!\n");break;}}encode(codec_ctx
, NULL, pkt
, outfile
);fclose(infile
);fclose(outfile
);if(yuv_buf
){free(yuv_buf
);}av_frame_free(&frame
);av_packet_free(&pkt
);avcodec_free_context(&codec_ctx
);printf("video encoder end!\n");return 0;
}
總結
以上是生活随笔為你收集整理的yuv编码成h264格式写成文件的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。