FFmpeg decoding H264 and Swscale scaling

Source: Internet
Author: User

Original http://blog.csdn.net/gubenpeiyuan/article/details/19548019 ThemeFFmpegThis article outlines:

This paper introduces the famous open source audio and video codec library ffmpeg how to decode H264 stream, and elaborates its h264 stream input process, decoding principle and decoding process in detail. At the same time, most of the application environment, the original stream video size display is not the best way, so developers need not only to decode the video stream, and need to scale the image to display under the different forms.

In summary, this paper introduces FFmpeg decoding H264, and illustrates how to use Swscale to scale the video stream.

Article uses the development environment Ubuntu12.04. e-mail: [email protected]. Reprint please specify the source csdn--the coupon.

FFmpeg Introduction:

FFmpeg is an open source, free cross-platform video and audio streaming solution that belongs to free software, with a LGPL or GPL license (depending on the component you choose). It provides a complete solution for recording, converting, and streaming audio and video. It contains a very advanced audio/video codec library Libavcodec, in order to ensure high portability and codec quality, Libavcodec Many codec are developed from scratch.

Start decoding

Well, not much to say. Go directly to the engineering and code bar. (Note that when linking projects, reference libraries have a connection order because they have interdependencies and if missing will not be compiled.) )

Libraries that need to be connected: vs code is as follows

#pragma comment (lib, "... \\FFMPEG_lib\\avformat.lib ")#pragma comment (lib," ... \\FFMPEG_lib\\avutil.lib ")#pragma comment (lib," ... \\FFMPEG_lib\\swscale.lib ")#pragma comment (lib," ... \\FFMPEG_lib\\avcodec.lib ")#pragma comment (lib," ... \\FFMPEG_lib\\avdevice.lib ")#pragma comment (lib," ... \\FFMPEG_lib\\avfilter.lib ")          
Required Header files:
#include "libavcodec\\avcodec.h"#include "libswscale/swscale.h "
Environment Initialization code: (ref. API-EXAMPLE.C) The FFmpeg version used on Ubuntu is 0.6
Avcodec_init ();First, the main function begins by calling the Avcodec_init () function, which is initialized with Libavcodec, which must be called when we use the Avcodec codec library. Avcodec_register_all ();Register all codecs (codecs), parsers (parsers), and bitstream filters (bitstream filters).    Of course we can also use the individual registration function to register the format we want to support. Avcodec*codec; Avcodeccontext*c= NULL;int frame, size, got_picture, Len; FILE*fin,*fout; Avframe*picture,*dst_picture; uint8_t inbuf[inbuf_size + ff_input_buffer_padding_size],*inbuf_ptr; Char buf[1024];/* Set end of buffer to 0 (this ensures, no overreading happens for damaged MPEG streams) */memset (inbuf + inbuf_size ,0, Ff_input_buffer_padding_size);printf"Video decoding\n");/* Find the MPEG1 Video Decoder */codec = Avcodec_find_decoder (codec_id_h264);if (!codec) {fprintf (stderr, "codec not found\n"); exit (1); c= avcodec_alloc_context (); picture= avcodec_alloc_frame (); span class= "keyword" >if (codec->capabilities&codec_cap_truncated) {c->flags|= codec_flag_truncated; /* we dont send complete frames */}/* for some codecs, such as MSMPEG4 and mpeg4, Width and height must be initialized there because these I NFO is not available in the bitstream *//* open it span class= "variable" >*/if (Avcodec_open (c, codec) < 0) {fprintf ( stderr,  "could not open codec\n"); exit (1);          
Avcodec_init and Avcodec_register_all Initialize the relevant decoder, request the space that the decoding need and so on.

Other decoding needs are Avcontext, Avcodec, and Avframe.

Avcontext is the environment for decoding, which stores information such as length-width, encoder algorithm, bitmap format and so on.

Avcondec is the codec you choose, indexed using enumerations, and used in conjunction with the decoding function after applying space.

Avframe and Avpicture, both store decoded bitmap information.

Decoding:

Avcodec_decode_video requires input parameters, Avcontext,avframe, data header address, and data length. An int pointer is also passed in to record the number of decoded successful frames returned by the decoding.

Len records the number of bytes consumed by this decoding.

Len = Avcodec_decode_video (c, Picture, &got_picture,                                       inbuf_ptr, size);
Note: In the decoding process do not clean up the contxt environment, as well as the decoder, if the necessary byte stream space has the preservation significance, because, 264 transmission process, there are PTS and DTS points, playback time and decoding time if inconsistent, may cause, first to the data needs to be stored after reaching his decoding time.

At the same time, the H264 code stream is divided into IPB frames, only I-frames are more comprehensive image information. If the decoding environment context is emptied after the decode I frame is complete, subsequent decoding will continue to return the error message until the next I-frame appears. The author of the test, hope to see this article of friends in doing decoding will not go this detour.

Since then, the decoding section has been elaborated.

Scaling:

Using FFmpeg for image Data format conversion and image scaling applications, the main use of the Swscale.h file in the three functions, respectively:

struct Swscontext *sws_getcontext (int SRCW,int SrcH,enum avpixelformat srcformat, int dstw, int dsth, enum avpixelformat dstformat, int flags, Swsfilter *srcfilter, Swsfilter *dstfilter, const double *param); int sws_scale (struct swscontext *c, const uint8_t *const srcslice[], const int srcstride[], int srcslicey, int srcsliceh, uint8_t *const dst[], const int dststride[]); void sws_freecontext (struct swscontext *swscontext);     

The sws_getcontext function can be considered an initialization function, and its parameters are defined as:

int Srcw,int SrcH is the height and width of the original image data;

int Dstw,int Dsth is the height and width of the output image data;

Enum Avpixelformat Srcformat is the type of input and output image data; eg:av_pix_fmt_yuv420, pav_pix_fmt_rgb24;

The int flags is the scale algorithm type; eg:sws_bicubic, Sws_bicublin, Sws_point, Sws_sinc;

Swsfilter *srcfilter, Swsfilter *dstfilter,const double *param can be used without tube, all is null;

The sws_scale function is the execution function, and its parameter definitions are:

struct Swscontext *c is the value returned by the Sws_getcontext function;

Const uint8_t *const srcslice[],uint8_t *const dst[] is an array of buffer pointers for each color channel of the input and output image data;

the const int Srcstride[],const int dststride[] is an array of bytes stored per row for each color channel of the input and output image data;

The int srcslicey is a progressive scan starting from the number of columns of the input image data, usually set to 0;

The int SRCSLICEH is the number of rows to be scanned, usually the height of the input image data;

The sws_freecontext function is the End function, and its parameters are the values returned by the Sws_getcontext function;

To do an actual scaling YUV420 function Packaging example is as follows:
int scaleimg (Avcodeccontext*pcodecctx,avframe*src_picture,avframe*dst_picture,int Ndsth,int NDSTW) {int i;int nsrcstride[3];int ndststride[3];int nsrch = pcodecctx->height;int NSRCW = pcodecctx->width;struct swscontext* m_pswscontext;uint8_t*psrcbuff[3] = {src_picture->data[0],src_picture->data[1], src_picture->data[2]};nsrcstride[0] = NSRCW; nsrcstride[1] = nsrcw/2; nsrcstride[2] = nsrcw/2;d st_picture->linesize[0] = ndstw;dst_picture->linesize[1] = NDSTW/2;dst_picture->linesize[2] = NDSTW/2;printf"NSRCW%d\n ", NSRCW); m_pswscontext = Sws_getcontext (NSRCW, Nsrch, PIX_FMT_YUV420P,NDSTW, Ndsth, Pix_fmt_yuv420p,sws_bicubic, NULL, NULL, NULL);if (NULL = = m_pswscontext) {printf ("FFmpeg get Context error!\n");  Exit (-1);} Sws_scale (M_pswscontext, Src_picture->data,src_picture->linesize, 0, pcodecctx->height,dst_picture- >data,dst_picture->linesize); printf ("LINE0:%d line1:%d line2:%d\n", dst_picture->linesize[0],dst_picture-> linesize[1], dst_picture->linesize[2]); Sws_freecontext (m_pswscontext);  return 1;}               
The function is simple, apply the environment initial pointer, after scaling can. Read this article friend, this function can be copied directly using Yo. If in doubt can leave a message or e-mail: [Email protected]

The following is a scaled image:

Space application of the destination bitmap:

Note: The above scaling function will report a segment error if it is used directly and if no decoding is successful or the destination bitmap space is not applied.

Cause: No decoding succeeds, the bitmap source address will be pointing to an empty address, and the destination bitmap address is the same.

How to apply for the destination bitmap:

Dst_picture = Avcodec_alloc_frame (); if (!dst_picture) {return;} *) dst_picture, C->pix_fmt,c->width *, C->height *) <0) {printf ("dst_picture Allocate failed\n "); exit (1);}         
It can be used for scaling after initialization. Memory Dump method for images: the decoding and scaling principles and processes of ffmpeg have been elaborated in detail above, however, in real-world applications, whether from real-time playback or historical playback, we need pixel bitmaps rather than ffmpeg structures. So how do you convert it? The relevant content is described below.

As the actual application environment, the pixel bitmap format, the author uses the more commonly used YUV format.

Encode and decode image formats

To continue above, in most of the field environment, in order to save the transmission bandwidth and improve system efficiency, the video raw bitmap format and the decoded display format generally use YUV420.

Among them, YV12 and IYUV are the most common formats.

In short, YUV format is divided into flat format and packaging format. They all have pros and cons. The advantage of this paper is that the YUV planar format, which is three channels using different entry addresses, is a convenient way to copy the image information in the Avframe data structure with the FFmpeg decoding interface.

Yv12:iyuv

Here is a simple narrative: for details, refer to:

http://blog.csdn.net/searchsun/article/details/2443867

How to Dump

Well, after a preliminary understanding of the YUV format, here's how to export this pixel bitmap data. FFmpeg the brightness of the image and the chromatic aberration information in the Avframe data[0], data[1], data[2].

Detailed reference:

Avframe and Avpicture comparison:

http://yul100887.blog.163.com/blog/static/200336135201211143525930/

All operations are carried out for these three pointers, as follows:

pgm_save (Picture->data[0], Picture->linesize[0], //yc->width, C->height, Outfilename);p Gm_save (picture->data[< Span class= "number" >1], Picture->linesize[1],c->width/2, c-> Height/2, outfilename); //upgm_save (Picture->data[2], picture->linesize[ 2],c->width/2, C->height/2, outfilename); Span class= "RegExp" >//v             
void Pgm_save (char *buf,int xsize,int ysize,int i;f=fopen (filename, for(i=1, xsize, f);} Fclose (f);}     
The code separately dumps the YUV three-pixel channel, and the reader can wrap the function according to its own needs. Data[0] is the luminance information entry pointer, which passes through the image length and width, as well as the memory area row width. DATA[1] data[2] similar.

The last note: Linesize is always easy to forget, Livesize[0]=height, LIVESIZE[1]=HEIGHT/2, LIVESIZE[2]=HEIGHT/2,

This article ends here, thanks for reading.

---------------------Leoluopy

Reference article:

Image format conversion and scaling using FFmpeg

http://blog.csdn.net/skys_broyal/article/details/10337147

Avframe and Avpicture comparison:

http://yul100887.blog.163.com/blog/static/200336135201211143525930/

FFmpeg decoding H264 and Swscale scaling

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.