The simplest FFmpeg-based encoder-pure version (without libavformat ),

Source: Internet
Author: User

The simplest FFmpeg-based encoder-pure version (without libavformat ),

========================================================== ==================

List of the simplest FFmpeg-Based Video Encoder articles:

The simplest Video Encoder Based on FFMPEG (YUV encoding: H.264)

The simplest Video Encoder Based on FFmpeg-new version (YUV encoding is HEVC (H.265 ))

The simplest FFmpeg-based encoder-pure version (excluding libavformat)

========================================================== ==================


This article records a more "pure" FFmpeg-based video encoder. Previously recorded a video encoder based on FFmpeg:

The simplest FFmpeg-based video encoder-new version (YUV encoding is HEVC (H.265)

The video encoder calls the libavformat and libavcodec libraries in FFmpeg to complete video encoding. But this is not a pure encoder. Libavformat in the above two libraries completes Encapsulation Format processing, while libavcodec completes encoding. In theory, it is enough to use libavcodec instead of libavformat. The encoder recorded in this article is such a "pure" encoder. It only calls libavcodec to encode the YUV data into a compressed video stream in H.264/HEVC format.


Flowchart

Shows how to encode a video using only libavcodec (without libavformat.


The functions of key functions in the flowchart are listed as follows:

Avcodec_register_all (): registers all codecs.
Avcodec_find_encoder (): Find the encoder.
Avcodec_alloc_context3 (): allocates memory for AVCodecContext.
Avcodec_open2 (): Enable the encoder.
Avcodec_encode_video2 (): encode a frame of data.

The following lists the structures used to store data:
AVFrame: stores unencoded pixel data.
AVPacket: stores compressed and encoded data of one frame.

Comparison

Simply record the difference between the "pure version" video encoder that uses only libavcodec and the video encoder that uses libavcodec + libavformat.

PS: libavcodec + libavformat encoder reference article "the simplest FFmpeg-based video encoder-new version (YUV encoding is HEVC (H.265)"

(1) The following functions related to libavformat do not exist in the "pure" video encoder.
Av_register_all (): registers all the codecs, multiplexing, demultiplexing, and other components. Avcodec_register_all () is called to register all decoder-related components.
Avformat_alloc_context (): creates an AVFormatContext struct.
Avformat_alloc_output_context2 (): initializes an output stream.
Avio_open (): Open the output file.
Avformat_new_stream (): creates an AVStream struct. Avcodec_alloc_context3 () is called in avformat_new_stream () to create the AVCodecContext struct.
Avformat_write_header (): Write the file header.
Av_write_frame (): Specifies the encoded file frame.
Av_write_trailer (): End of the file.
(2) added the following functions:
Avcodec_register_all (): registers only the components related to the decoder.

Avcodec_alloc_context3 (): creates an AVCodecContext struct.

It can be seen that, compared with the "complete" encoder, this pure encoder function is simpler to call, with fewer functions and more lightweight ".


Source code

/*** The simplest Video Encoder Based on FFmpeg (pure version) * Simplest FFmpeg Video Encoder Pure ** Lei Xiaohua * leixiaohua1020@126.com * China Media University/Digital TV Technology * Communication University of China/Digital TV Technology * http://blog.csdn.net/leixiaohua1020 ** YUV pixel data encoding for video streams (H264, MPEG2, VP8, etc ). * It only uses libavcodec (instead of libavformat ). * Is the simplest tutorial on FFmpeg video encoding. * By studying this example, you can understand the FFmpeg encoding process. * This software encode YUV420P data to video bitstream * (Such as H. 264, H.265, VP8, MPEG2 etc ). * It only uses libavcodec to encode video (without libavformat) * It's the simplest video encoding software based on FFmpeg. * Suitable for beginner of FFmpeg */# include <stdio. h> extern "C" {# include "libavutil \ opt. h "# include" libavcodec \ avcodec. h "# include" libavutil \ imgutils. h "}; // test different codec # Define TEST_H264 0 # define TEST_HEVC 1int main (int argc, char * argv []) {AVCodec * pCodec; AVCodecContext * pCodecCtx = NULL; int I, ret, x, y, got_output; FILE * fp_in; FILE * fp_out; AVFrame * pFrame; AVPacket pkt; int y_size; int framecnt = 0; char filename_in [] = ".. /ds_480x272.yuv "; # if TEST_HEVCAVCodecID codec_id = AV_CODEC_ID_HEVC; char filename_out [] =" ds. hevc "; # elseAVCodecID codec_id = AV_CODEC_ID_H264; char file Name_out [] = "ds. h264"; # endifint in_w = 480, in_h = 272; int framenum = 100; avcodec_register_all (); pCodec = avcodec_find_encoder (codec_id); if (! PCodec) {printf ("Codec not found \ n"); return-1;} pCodecCtx = avcodec_alloc_context3 (pCodec); if (! PCodecCtx) {printf ("cocould not allocate video codec context \ n"); return-1;} pCodecCtx-> bit_rate = 400000; pCodecCtx-> width = in_w; pCodecCtx-> height = in_h; pCodecCtx-> time_base.num = 1; pCodecCtx-> time_base.den = 25; pCodecCtx-> gop_size = 10; pCodecCtx-> max_ B _frames = 1; pCodecCtx-> pix_fmt = AV_PIX_FMT_YUV420P; if (codec_id = AV_CODEC_ID_H264) av_opt_set (pCodecCtx-> priv_data, "preset", "slow", 0) I F (avcodec_open2 (pCodecCtx, pCodec, NULL) <0) {printf ("cocould not open codec \ n"); return-1;} pFrame = av_frame_alloc (); if (! PFrame) {printf ("cocould not allocate video frame \ n"); return-1;} pFrame-> format = pCodecCtx-> pix_fmt; pFrame-> width = pCodecCtx-> width; pFrame-> height = pCodecCtx-> height; ret = av_image_alloc (pFrame-> data, pFrame-> linesize, pCodecCtx-> width, pCodecCtx-> height, pCodecCtx-> pix_fmt, 16); if (ret <0) {printf ("cocould not allocate raw picture buffer \ n"); return-1 ;} // Input raw datafp_in = fopen (file Name_in, "rb"); if (! Fp_in) {printf ("cocould not open % s \ n", filename_in); return-1 ;}// Output bitstreamfp_out = fopen (filename_out, "wb"); if (! Fp_out) {printf ("cocould not open % s \ n", filename_out); return-1;} y_size = pCodecCtx-> width * pCodecCtx-> height; // Encode for (I = 0; I <framenum; I ++) {av_init_packet (& pkt); pkt. data = NULL; // packet data will be allocated by the encoder pkt. size = 0; // Read raw YUV dataif (fread (pFrame-> data [0], 1, y_size, fp_in) <0 | // Yfread (pFrame-> data [1], 1, y_size/4, fp_in) <0 | // U fread (pFrame-> data [2], 1, y_size /4, fp_in) <0) {// Vreturn-1;} else if (feof (fp_in) {break;} pFrame-> pts = I; /* encode the image */ret = avcodec_encode_video2 (pCodecCtx, & pkt, pFrame, & got_output); if (ret <0) {printf ("Error encoding frame \ n "); return-1;} if (got_output) {printf ("Succeed to encode frame: % 5d \ tsize: % 5d \ n", framecnt, pkt. size); framecnt ++; fwrite (pkt. data, 1, pkt. size, fp_out); av_free_packet (& pkt) ;}// Flush E Ncoder for (got_output = 1; got_output; I ++) {ret = avcodec_encode_video2 (pCodecCtx, & pkt, NULL, & got_output); if (ret <0) {printf ("Error encoding frame \ n"); return-1 ;}if (got_output) {printf ("Flush Encoder: Succeed to encode 1 frame! \ Tsize: % 5d \ n ", pkt. size); fwrite (pkt. data, 1, pkt. size, fp_out); av_free_packet (& pkt) ;}} fclose (fp_out); avcodec_close (pCodecCtx); av_free (pCodecCtx); av_freep (& pFrame-> data [0]); av_frame_free (& pFrame); return 0 ;}


Running result

Determine the encoder to be used by setting the macro defined at the beginning of the program.

//test different codec#define TEST_H264  0#define TEST_HEVC  1

When TEST_H264 is set to 1, encode the H.264 File "ds. h264 ".
When TEST_HEVC is set to 1, the HEVC file "ds. hevc" is decoded ".
The input file is "ds_480x272.yuv ".

The program runs as follows.


Shows the input YUV file.


Shows the output HEVC file.


Download

The Simplest ffmpeg encoder pure project is added to the simplest ffmpeg video encoder project as a sub-project. The new simplest ffmpeg video encoder information is as follows.


Simplest ffmpeg video encoder

SourceForge home: https://sourceforge.net/projects/simplestffmpegvideoencoder/
Http://download.csdn.net/detail/leixiaohua1020/8322003 (CSDN)


This program implements YUV pixel data encoding as video streams (H.265, H264, MPEG2, VP8, etc ).

It is the simplest tutorial on FFmpeg video encoding.

It contains the following two sub-projects:

Simplest_ffmpeg_video_encoder: the simplest Video Encoder Based on FFmpeg. Use libavcodec and libavformat to encode and encapsulate videos.
Simplest_ffmpeg_video_encoder_pure: the simplest Video Encoder Based on FFmpeg-pure version. Only videos are encoded using libavcodec, and libavformat is not used.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.