Use ffmpge for video compression (from image to h264 Video Stream)

Source: Internet
Author: User

I believe FFMPEG will not be unfamiliar with video or image processing, and many related code can be found online. However, due to different versions, the code that is often found can be used only by self-modification. I hope to do my best to release the development kit and self-written code, if you want to directly run the code for reference, you can download the FFMPEG Development Kit I released for configuration (the tutorial URL for configuration is as follows: Click to open the link ), then refer to the codec code I wrote for program development.

The following is a self-encapsulated FFMPEG video compression code. If you have better suggestions, please let me know and repost the code to indicate the source.

First, we design a class related to video compression, which is defined as follows:

Class ffmpeg_encoder {public: avframe * m_prgbframe; // frame object avframe * m_pyuvframe; // frame object avcodec * pcodech264; // encoder avcodeccontext * C; // encoder Data Structure object uint8_t * yuv_buff; // uint8_t * rgb_buff; // swscontext * scxt In the RGB image data area; // encode the video data cache int outbuf_size; // encode the output data de-size int ndatalen; // The length of the RGB image data area int width; // The output video width int height; // output video height public: void ffmpeg_encoder_init (); // initialize void ffmpeg_encoder_setpara (codecid mycodeid, int vwidth, int vheight); // set the parameter. The first parameter is the encoder, the second parameter is the width of the compressed video, and the third video is its height void ffmpeg_encoder_encode (File * file, uint8_t * data ); // encode and write data to the file void ffmpeg_encoder_close (); // close };
Define the four functions declared in the class

Void ffmpeg_encoder: encode () {av_register_all (); avcodec_register_all (); m_prgbframe = new avframe [1]; // values of RGB frame data are m_pyuvframe = new avframe [1]; // YUV frame data value c = NULL; // decoder pointer object Value}
Void ffmpeg_encoder: ffmpeg_encoder_setpara (codecid mycodeid, int vwidth, int vheight) {pcodech264 = avcodec_find_encoder (mycodeid); // find the h264 encoder if (! Pcodech264) {fprintf (stderr, "h264 codec not found \ n"); exit (1) ;}width = vwidth; Height = vheight; C = avcodec_alloc_context3 (pcodech264 ); // The function is used to allocate an avcodeccontext and set the default value. If a failure occurs, null is returned, and av_free () can be used to release C-> bit_rate = 400000; // you can set the sampling parameter, that is, bit rate C-> width = vwidth; // you can specify the width of the encoded video C-> Height = vheight. // you can specify the height of the encoded video C-> time_base.den = 2; // set the frame rate. Num indicates the numerator and den indicates the denominator. If it is 1/25, it indicates 25 frames/SC-> time_base.num = 1; C-> gop_size = 10; // set the GOP size. This value indicates that an I frame C-> max_ B _frames = 1 will be inserted every 10 frames; // you can specify the maximum number of B frames, this value indicates the number of bytes frames allowed to be inserted between two non-B frames C-> pix_fmt = pix_fmt_yuv420p; // sets the pixel format av_opt_set (c-> priv_data, "tune", "zerolatency", 0); // sets the latency of the encoder to solve the problem where the previous dozens of frames do not produce data. If (avcodec_open2 (C, pcodech264, null) <0) return; // enable the encoder ndatalen = vwidth * vheight * 3; // calculate the length of the RGB data area of the image yuv_buff = new uint8_t [ndatalen/2]; // initialize the data area and prepare the filling cache rgb_buff = new uint8_t [ndatalen] For the YUV image frame; // initialize the data area to prepare the filling cache outbuf_size = 100000 for the RGB image frame; /// initialization code output data area outbuf = new uint8_t [outbuf_size]; scxt = sws_getcontext (c-> width, C-> height, pix_fmt_bgr24, C-> width, c-> height, pix_fmt_yuv420p, sws_point, null, null); // initialize the format conversion function}
Void ffmpeg_encoder: ffmpeg_encoder_encode (File * file, uint8_t * Data) {memcpy (rgb_buff, Data, ndatalen ); // copy image data to the RGB image frame cache. Prepare to process avpicture_fill (avpicture *) m_prgbframe, (uint8_t *) rgb_buff, pix_fmt_rgb24, width, height ); // fill rgb_buff with struct (avpicture *) m_pyuvframe, (uint8_t *) yuv_buff, struct, width, height); // fill yuv_buff with m_pyuvframesws_scale (scxt, XT, m_prgbframe-> data, m_prgbframe-> linesize, 0, C-> height, m_pyuvframe-> data, m_pyuvframe-> linesize ); // Convert RGB to yuvint myoutputlen = avcodec_encode_video (C, outbuf, outbuf_size, m_pyuvframe); fwrite (outbuf, 1, myoutputlen, file );}
Void ffmpeg_encoder: trim () {Delete [] m_prgbframe; Delete [] m_pyuvframe; Delete [] rgb_buff; Delete [] yuv_buff; Delete [] outbuf; sws_freecontext (scxt ); avcodec_close (c); // disable the encoder av_free (c );}
In the end, we only need to call these functions in the main function. Because I directly use openccv to open the image and obtain the image data area for convenience, therefore, if you want to directly run the project that is later than you, you still need to configure opencv on your own. However, this is really bad on the Internet, and you can configure it as you like. If you do not want to use opencv to open the image, I have also indicated the location to be modified in the code. You can find a way to obtain the image data area and put it into the video compression function.

Void main () {ffmpeg_encoder ffmpegobj; ffmpegobj. ffmpeg_encoder_init (); // initialize the encoder ffmpegobj. ffmpeg_encoder_setpara (codec_id_h264, 800,600); // sets the encoder parameter // image encoding file * f = NULL; char * filename = "mydata. h264 "; fopen_s (& F, filename," WB "); // enable the file storage encoding to complete data iplimage * IMG = NULL; // opencv Image Data Structure pointer iplimage * resizeimg = NULL; // size int picturecount = 1; while (picturecount! = 9) {/** this section uses opencv to read the image object and obtain the image data area, you can also use other methods to obtain the image data zone **/Char chpicname [100]; sprintf (chpicname, "testpicture \ horsew.d.jpg", picturecount ); // obtain the image path // sprintf (chpicname, "1.jpg", picturecount); // obtain the image path IMG = cvloadimage (chpicname, 1 ); // open the image // because the opencv image data area is arranged in BGR, you must convert the data into normal RGB data for further compression, otherwise, the pressed video color will be incorrect. uchar * Data = (uchar *) (IMG-> imagedata); uchar mid = 0; For (int row = 0; row  height; row ++) for (INT Cols = 0; Cols  width; Cols ++) {mid = data [row * IMG-> widthstep/sizeof (uchar) + Cols * IMG-> nchannels + 0]; // G data [row * IMG-> widthstep/sizeof (uchar) + Cols * IMG-> nchannels + 0] = data [row * IMG-> widthstep/sizeof (uchar) + Cols * IMG-> nchannels + 2]; data [row * IMG-> widthstep/sizeof (uchar) + Cols * IMG-> nchannels + 2] = mid ;} resizeimg = cvcreateimage (cvsize (800,600), 8, 3); cvresize (IMG, resizeimg, cv_inter_linear ); // adjust the image size. ** this part uses opencv to read the image object and obtain the image data area. You can also use other methods to obtain the image data area. **/ffmpegobj. ffmpeg_encoder_encode (F, (uchar *) resizeimg-> imagedata); // encode cvreleaseimage (& IMG); // release the image data structure pointer to the image content cvreleaseimage (& resizeimg ); picturecount ++;} fclose (f); ffmpegobj. ffmpeg_encoder_close ();}
OK, the blog that uses FFMPEG for video compression has come to an end, and the download of the entire project will be released later. However, you still need to manually configure it.






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.