FFmpeg version: Ffmpeg-3.4-win32-dev
SDL Version: sdl2-2.0.7
Reference article:
Thor's various related articles ...
FFmpeg Learning (iii)--FFMPEG+SDL2 implement simple player
Related project files ffmpeg+sdl2 play local AVI file
Hope to have a certain reference to help it ...
Ffmpeg_playtest.cpp: Defines the entry point of the console application. #include "stdafx.h" #ifdef __cplusplus extern "C" {#endif #include "include/libavcodec/avcodec.h" #include "includ E/libswscale/swscale.h "#include" include/libavutil/imgutils.h "#include" sdl2-2.0.7/include/sdl.h "#include < stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #ifdef __cplusplus} #endif #pra GMA Comment (lib, "Lib/avcodec.lib") #pragma comment (lib, "Lib/avutil.lib") #pragma comment (lib, "Lib/swscale.lib") # pragma comment (lib, "Sdl2-2.0.7/lib/x86/sdl2.lib") #define inbuf_size 4096 int showframe (struct swscontext *pswscontext , sdl_renderer* Prenderer, sdl_texture* psdltexture, avcodeccontext* pcodeccontext, avframe* pSrcFrame, AVFrame*
Pdestframe);
static void Decode (Avcodeccontext *dec_ctx, Avframe *frame, Avpacket *pkt, Avframe *pdestframe) {char buf[1024];
int ret;
ret = Avcodec_send_packet (Dec_ctx, PKT); if (Ret < 0) {fprintf (stderr, "Error SenDing a packet for decoding\n ");
Exit (1);
} while (ret >= 0) {ret = Avcodec_receive_frame (dec_ctx, frame);
if (ret = = Averror (eagain) | | ret = = averror_eof) return;
else if (Ret < 0) {fprintf (stderr, "Error during decoding\n");
Exit (1);
} printf ("Saving frame%3d\n", dec_ctx->frame_number);
Fflush (stdout);
}} int _tmain (int argc, _tchar* argv[]) {file* pFile = NULL;
Const char* chfilename = NULL;
Chfilename = "./test.avi";
Chfilename = "./bigbuckbunny_480x272.h264";
Fopen_s (&pfile, Chfilename, "RB");
if (!pfile) {fprintf (stderr, "Could not open%s\n", chfilename);
Exit (1);
} const AVCODEC *PCODEC = NULL;
avcodecparsercontext* pparserctx = NULL;
avcodeccontext* pcodecctx = NULL;
avframe* Pfram = NULL;
uint8_t inbuf[inbuf_size + av_input_buffer_padding_size] = {0}; uint8_t *PDATa = NULL;
size_t data_size = 0;
int iRet = 0;
Avpacket *ppkt = NULL;
Avcodec_register_all ();
PPKT = Av_packet_alloc ();
if (!PPKT) {printf ("Av_packet_alloc failed.\n");
Exit (1);
} memset (Inbuf + inbuf_size, 0, av_input_buffer_padding_size);
Find the video decoder//pcodec = Avcodec_find_decoder (AV_CODEC_ID_MPEG4);
Pcodec = Avcodec_find_decoder (av_codec_id_h264);
if (!pcodec) {fprintf (stderr, "Codec not found.\n");
Exit (1);
} Pparserctx = Av_parser_init (pcodec->id);
if (Pparserctx = = NULL) {fprintf (stderr, "parser not found.\n");
Exit (1);
} Pcodecctx = Avcodec_alloc_context3 (PCODEC);
if (Pcodecctx = = NULL) {fprintf (stderr, "Could not allocate video Contex \ n");
Exit (1);
} if (Avcodec_open2 (Pcodecctx, Pcodec, NULL) < 0) {fprintf (stderr, "could not open codec\n");
Exit (1); } PFram = Av_frame_alloc ();
if (Pfram = = NULL) {fprintf (stderr, "Could not allocate video frame\n");
Exit (1); }//sdl Initialize if (Sdl_init (Sdl_init_video | Sdl_init_audio |
Sdl_init_timer) {printf ("Could not initialize SDL--%s\n", Sdl_geterror ());
Exit (1);
} sdl_window* pscreen = NULL;
sdl_renderer* psdlrenderer = NULL;
sdl_texture* psdltexture = NULL;
Sdl_event sdlevent;
struct Swscontext *img_convert_ctx = NULL;
avframe* PFRAMEYUV = NULL;
uint8_t* out_buffer = NULL;
while (!feof (PFile)) {data_size = Fread (inbuf, 1, inbuf_size, pFile);
if (!data_size) {printf ("read file failed.\n");
Break
} pData = Inbuf; while (Data_size > 0) {iRet = Av_parser_parse2 (Pparserctx, Pcodecctx, &ppkt->data, &PPK
T->size, PData, Data_size, Av_nopts_value, Av_nopts_value, 0); if (IRet < 0) {fprintf (stderr, "Error while parsing\n");
Exit (1);
} PData + = IRet;
Data_size-= IRet;
if (ppkt->size) {printf ("[packet] size =%6d\n", ppkt->size);
Switch (pparserctx->pict_type) {case av_picture_type_i:printf ("type:i\t"); Case av_picture_type_p:printf ("type:p\t");
Break Case av_picture_type_b:printf ("type:b\t");
Break default:printf ("type:other\t");
Break }//--------------------------------------------DECODE------------------------------int
Ret
ret = Avcodec_send_packet (Pcodecctx, PPKT);
if (Ret < 0) {fprintf (stderr, "Error sending a packet for decoding\n");
Exit (1);
} while (ret >= 0) {ret = Avcodec_receive_frame (Pcodecctx, Pfram); if (ret = = Averror (eagain) | | ret = = averror_eof) {//fprintf (stderr, "(ret = = Averror (eagain) | |
ret = = averror_eof\n ");
Break } else if (Ret < 0) {fprintf (stderr, "Error during Dec
Oding\n ");
Exit (1);
}//Due to the need to parse a frame successfully first to obtain the width and high information of the image, these initialized operations can only be placed here for if (PFRAMEYUV = = NULL) {PFRAMEYUV = Av_frame_alloc (); Store converted Avframe Out_buffer = new Uint8_t[av_image_get_buffer_size (av_pix_fmt_yuv420p, PCODECCTX-&G
T;width, Pcodecctx->height, 1)]; Av_image_fill_arrays (Pframeyuv->data, Pframeyuv->linesize, Out_buffer, av_pix_fmt_yuv420p, Pcodecctx->width, Pcodecctx->height, 1); } if (Pscreen = = NULL) {//sdl init----------------------- ------------------Pscreen = Sdl_createwindow ("RTSP Client Demo", Sdl_
windowpos_undefined, sdl_windowpos_undefined, Pcodecctx->width, Pcodecctx->height, Sdl_window_resizable |
SDL_WINDOW_OPENGL); if (Pscreen = = NULL) {printf ("Sdl:could not set video mode-exit.\n"
);
Exit (1);
} psdlrenderer = Sdl_createrenderer (Pscreen,-1, 0);
Psdltexture = Sdl_createtexture (Psdlrenderer, SDL_PIXELFORMAT_IYUV, Sdl_textUreaccess_streaming, Pcodecctx->width, pcodecctx->height); } showframe (Img_convert_ctx, Psdlrenderer, Psdltexture, Pcodecctx, Pfram, Pframey UV); Displays a frame of printf ("Saving frame%3d, Width =%d, height =%d\n", Pcodecctx->frame_number, Pcodecctx->
; width, pcodecctx->height);
Fflush (stdout);
}//-------------------------------------END Decode-----------------------------------}
else {//printf ("ppkt->size = 0\n");
} av_packet_unref (PPKT);
Sdl_pollevent (&sdlevent);
Switch (sdlevent.type) {case sdl_quit:sdl_quit ();
Exit (0);
Break
Default:break; }}} decode (Pcodecctx, Pfram, NULL, NULL);
if (pFile) {fclose (pFile);
PFile = NULL;
} if (psdltexture) {sdl_destroytexture (psdltexture);
Psdltexture = NULL;
} if (Psdlrenderer) {sdl_destroyrenderer (psdlrenderer);
Psdlrenderer = NULL;
} av_parser_close (PPARSERCTX);
Avcodec_free_context (&PCODECCTX);
Av_frame_free (&pfram);
if (Out_buffer) {delete[] out_buffer;
Out_buffer = NULL;
} if (PFRAMEYUV) {av_frame_free (&PFRAMEYUV);
} av_packet_unref (PPKT);
return 0; } int showframe (struct swscontext *pswscontext, sdl_renderer* prenderer, sdl_texture* psdltexture, AVCodecContext* PCode
Ccontext, avframe* psrcframe, avframe* pdestframe) {if (!prenderer | |!psdltexture | |!pcodeccontext | |!pSrcFrame)
{printf ("Show frame failed, param is null.\n");
return-1; }//pixel format conversion prame converted to pframe Yuv Pswscontext = Sws_getcontext (PCOdeccontext->width, Pcodeccontext->height, PCODECCONTEXT->PIX_FMT, Pcodeccontext->widt
H, Pcodeccontext->height, av_pix_fmt_yuv420p, sws_bicubic, NULL, NULL,
NULL); Sws_scale (Pswscontext, (const uint8_t* const*) Psrcframe->data, psrcframe->linesize, 0, Psrcframe->height,
Pdestframe->data, pdestframe->linesize);
Sws_freecontext (Pswscontext);
SDL display----------------------------sdl_rect sdlrect;
sdlrect.x = 0;
Sdlrect.y = 0;
SDLRECT.W = pcodeccontext->width;
SdlRect.h = pcodeccontext->height;
Sdl_updatetexture (Psdltexture, &sdlrect, pdestframe->data[0], pdestframe->linesize[0]);
Sdl_renderclear (Prenderer);
Sdl_rendercopy (Prenderer, Psdltexture, &sdlrect, &sdlrect);
Sdl_renderpresent (Prenderer);
Delay 20ms Sdl_delay (20);
return 0; }