Embedded Linux------ffmpeg porting decoding H264 (am335x decoding H264 to yuv420 and displaying via SDL)

Source: Internet
Author: User

/* Compile command: Arm-linux-gcc-o show2642 264showyuv2.c-i/usr/local/ffmpeg_arm/include/-l/usr/local/ffmpeg_arm/lib/- lswresample-lavformat-lavutil-lavcodec-lswscale-lx264 libsdl.a*/#include "stdio.h" #include "stdlib.h" #include "Lib Avformat/avformat.h "#include" libavdevice/avdevice.h "#include" libswresample/swresample.h "#include" libavutil/ Opt.h "#include" libavutil/channel_layout.h "#include" libavutil/parseutils.h "#include" libavutil/samplefmt.h "# Include "Libavutil/fifo.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" #include "libavutil/ Mathematics.h "#include" libavutil/pixdesc.h "#include" libavutil/avstring.h "#include" libavutil/imgutils.h "# Include "Libavutil/timestamp.h" #include "libavutil/bprint.h" #include "libavutil/time.h" #include "libavutil/ Threadmessage.h "#include"/usr/local/ffmpeg_arm/include/sdl/sdl.h "#include" libavfilter/avcodec.h "#include" Libavcodec/avcodec.h "#if have_sys_resource_h#include <sys/time.h> #include <sys/types.h> #include < Sys/resource.h> #elif have_getprocesstimes#include <windows.h> #endif # if Have_getprocessmemoryinfo#include < windows.h> #include <psapi.h> #endif # if Have_sys_select_h#include <sys/select.h> #endif # if Have_ Termios_h#include <fcntl.h> #include <sys/ioctl.h> #include <sys/time.h> #include <termios.h> #elif have_kbhit#include <conio.h> #endif # if Have_pthreads#include <pthread.h> #endif # include <time.h > #include "libavutil/avassert.h" #define Max_len 1024 * 50////This method participates in the sample of the Examiner network static void Pgm_save (unsigned char *buf, int WR    AP, int xsize, int ysize, file *f) {//File *f;   int i;   f = fopen (filename, "w");    fprintf (F, "p5\n%d%d\n%d\n", Xsize, ysize, 255);  for (i = 0; i < ysize; i++) fwrite (buf + i * wrap, 1, xsize, f); Fclose (f);}        int main () {//below initializes the H264 decoding Library//avcodec_init ();        int w = 720;        int h = 576,retu; Sdl_rect Rect;av_register_all (); Avframe *pframe_ = null;/* find the video enCoder */avcodec *videocodec = Avcodec_find_decoder (codec_id_h264);//Get 264 decoder class if (!VIDEOCODEC) {printf ("Avcodec_find _decoder error\n "); return-1;} Avcodecparsercontext *avparsercontext = Av_parser_init (codec_id_h264);//Get Parse frame class. Used primarily for the rear frame header to find if (!avparsercontext) {printf ("Av_parser_init error\n"); return-1;}  Avcodeccontext *codec_ = Avcodec_alloc_context3 (VIDEOCODEC);//Decode Session layer if (!CODEC_) {printf ("Avcodec_alloc_context3 Error\n "); return-1;} The following number of parameters should be determined by the detailed business decision Codec_->time_base.num = 1;codec_->frame_number = 1; One video frame per package Codec_->codec_type = Avmedia_type_video;codec_->bit_rate = 0;codec_->time_base.den = 25;//Frame rate codec_ ->width = 720;//Video Width codec_->height = 576;//video High if (Avcodec_open2 (codec_, Videocodec, NULL) >= 0)//Open Decoder {pframe_ = Avcodec_alloc_frame ();//Allocate video frame After successfully opening the decoder, you can allocate frame memory at this time, of course, you can also allocate, release each time later, in this province kung Fu, just start assigning once if (!pframe_) {f printf (stderr, "Could not allocate video frame\n"); exit (1);}} else{printf ("Avcodec_open2 error\n"); return-1;} Avpacket packet = {0};int dwbufsize = 10;int framefinished = dwbufsize;//This is a random fill number, nothing effect Av_init_packet (&packet);p acket.data = NULL;// This fills in a pointer to the full H264 data frame packet.size = 0;//This fills in the size of the H264 data frame file *myh264 = fopen ("1.264", "RB");//decoded file 264if (myH264 = = NULL) { perror ("Cant open file\n"); return-1;} File *yuvfile = fopen ("MY264.YUV", "WB");//YUV file saved after successful decoding, able to open with YUV tool Browse if (Yuvfile = = NULL) {perror ("Cant open YUV file\n" ); return-1;} int readfilelen = 1;char readbuf[max_len];unsigned char *parsebuf = malloc (20*max_len);//This place wasted an afternoon of my time, when I was using stack memory. That is unsigned char Parsebuf[20*max_len]. Result execution program has been error, here need to use heap memory ability normal decoding int parsebuflen = 0;int Framecount = 0;printf ("begin...\n");p rintf ("Readbuf address is%x\n",    READBUF);/////////////////////////sdl init////////////////////////////////////////SDL_Surface* hello = NULL;    sdl_surface* screen = NULL;      Start SDL//Sdl_init (sdl_init_everything);    Sdl_init (Sdl_init_video);    Set up Screens screen = Sdl_setvideomode (1024x768, 768, +, sdl_swsurface); Sdl_overlay* overlay = Sdl_createyuvoverlay (W, H, sdl_yv12_overlay, screen);    Sdl_locksurface (screen); Sdl_lockyuvoverlay (overlay);//////////////////////////////////////////////////////////////////////while ( Readfilelen > 0)//start decoding work {//printf ("begin...\n"); Readfilelen = Fread (readbuf, 1, sizeof (READBUF), myH264);// First read the data from the file if (Readfilelen <= 0) {printf ("read over\n"); Else{int Handlelen = 0;int Handlefilelen = readfilelen;while (Handlefilelen > 0) {int nlength = AV_PARSER_PARSE2 (avParse  Rcontext, Codec_, &parsebuf, &parsebuflen, Readbuf + handlelen, Handlefilelen, 0, 0, 0);//Find 264 frame header Handlefilelen-= Nlength;handlelen + = nlength;if (parsebuflen <= 0)//when Parsebuflen is greater than 0 o'clock, the description finds the frame header {continue;} Packet.size = parsebuflen;//will find the frame length fed into Packet.data = parsebuf;//will find the frame memory to feed if (framecount&gt break;//printf ("Parsebuf address is%x\n", parsebuf) and while (Packet.size > 0) {//below starts the true decoding int decodelen = AVCODEC_ Decode_video2 (Codec_, Pframe_, &AMP;FRAMEFInished, &packet); if (Decodelen < 0) Break;packet.size-= Decodelen;packet.data + = decodelen;if (frameFinished > 0)//successful decoding {int picsize = Codec_->height * Codec_->width;//int newSize = picsize * 1.5;//request memory//unsigned Char *buf = malloc (newSize); int height = pframe_->height;int width = pframe_->width;//printf ("OK, get data\n");//printf (" Frame height is%d\n ", height);//printf (" Frame width is%d\n ", width); Framecount + +;p rintf (" Frame count is%d\n ", Framecou                                                NT); Pgm_save (Pframe_->data[0], pframe_->linesize[0],//save y codec_->width, Codec_->height, yuvfile); Pgm_save (pframe_->data[1], pframe_->linesize[1],//save U codec_->width/2, CODEC_-&GT;HEIGHT/2, Yuvfi Le);p gm_save (pframe_->data[2], pframe_->linesize[2],//save v Codec_->width/2, CODEC_-&GT;HEIGHT/2, y                                                Uvfile); With YUV data. The conversion method that can be provided later with FFmpeg. Turn it into RGB data, make a display orHis image-processing work////sdl int i;  for (i=0;i<576;i++) {//fwrite (buf                                                     + i * wrap, 1, xsize, f);                                                                               memcpy (overlay->pixels[0]+i*720, pframe_->data[0]+i*pframe_->linesize[0], 720);                                                } for (i=0;i<288;i++)     {memcpy (overlay->pixels[2]+i*360, pframe_->data[1]+i*pframe_->linesize[1], 360);                                                                      memcpy (overlay->pixels[1]+i*360, pframe_->data[2]+i*pframe_->linesize[2], 360); }sdl_unlockyuvoverlay (overlay); Sdl_unlocksurface (screen); rect.w = W;rect.h = H;rect.x = Rect.y = 0;           Sdl_displayyuvoverlay (overlay, &rect);                 Sdl//sdl_delay (40);}    Elseprintf ("Failed to decodec\n");}}}    Release of work Avcodec_close (CODEC_), Av_free (CODEC_); Av_free_packet (&packet); Av_frame_free (&pframe_);        SDL sdl_freeyuvoverlay (overlay);    Sdl_freesurface (screen); Quit SDL sdl_quit (); fclose (yuvfile); fclose (myH264);}



Embedded Linux------ffmpeg porting decoding H264 (am335x decoding H264 to yuv420 and displaying via SDL)

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.