├── README.md ├── FSPlayer ├── Audio.h ├── Video.h ├── main.cpp ├── Audio.cpp ├── Video.cpp ├── FrameQueue.cpp ├── VideoDisplay.cpp ├── VideoDisplay.h ├── FrameQueue.h ├── PacketQueue.h ├── Media.h ├── PacketQueue.cpp ├── FSPlayer.vcxproj.filters ├── Media.cpp └── FSPlayer.vcxproj ├── FSPlayer.sln ├── .gitattributes └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # FSplayer 2 | A simaple video player with FFmpeg and SDL2.0 3 | -------------------------------------------------------------------------------- /FSPlayer/Audio.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/Audio.h -------------------------------------------------------------------------------- /FSPlayer/Video.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/Video.h -------------------------------------------------------------------------------- /FSPlayer/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/main.cpp -------------------------------------------------------------------------------- /FSPlayer/Audio.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/Audio.cpp -------------------------------------------------------------------------------- /FSPlayer/Video.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/Video.cpp -------------------------------------------------------------------------------- /FSPlayer/FrameQueue.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/FrameQueue.cpp -------------------------------------------------------------------------------- /FSPlayer/VideoDisplay.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/VideoDisplay.cpp -------------------------------------------------------------------------------- /FSPlayer/VideoDisplay.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brookicv/FSplayer/HEAD/FSPlayer/VideoDisplay.h -------------------------------------------------------------------------------- /FSPlayer/FrameQueue.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FRAME_QUEUE_H 3 | #define FRAME_QUEUE_H 4 | 5 | #include 6 | #include 7 | 8 | extern "C"{ 9 | 10 | #include 11 | 12 | } 13 | 14 | struct FrameQueue 15 | { 16 | static const int capacity = 30; 17 | 18 | std::queue queue; 19 | 20 | uint32_t nb_frames; 21 | 22 | SDL_mutex* mutex; 23 | SDL_cond * cond; 24 | 25 | FrameQueue(); 26 | bool enQueue(const AVFrame* frame); 27 | bool deQueue(AVFrame **frame); 28 | }; 29 | 30 | 31 | 32 | #endif -------------------------------------------------------------------------------- /FSPlayer/PacketQueue.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PACKET_QUEUE_H 3 | #define PACKET_QUEUE_H 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern "C"{ 11 | 12 | #include 13 | 14 | } 15 | 16 | struct PacketQueue 17 | { 18 | std::queue queue; 19 | 20 | Uint32 nb_packets; 21 | Uint32 size; 22 | SDL_mutex *mutex; 23 | SDL_cond *cond; 24 | 25 | PacketQueue(); 26 | bool enQueue(const AVPacket *packet); 27 | bool deQueue(AVPacket *packet, bool block); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /FSPlayer/Media.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MEDIA_H 3 | #define MEDIA_H 4 | 5 | #include 6 | #include "Audio.h" 7 | #include "Video.h" 8 | 9 | extern "C" { 10 | 11 | #include 12 | 13 | } 14 | 15 | struct VideoState; 16 | 17 | struct MediaState 18 | { 19 | AudioState *audio; 20 | VideoState *video; 21 | AVFormatContext *pFormatCtx; 22 | 23 | char* filename; 24 | //bool quit; 25 | 26 | MediaState(char *filename); 27 | 28 | ~MediaState(); 29 | 30 | bool openInput(); 31 | }; 32 | 33 | int decode_thread(void *data); 34 | 35 | #endif -------------------------------------------------------------------------------- /FSPlayer.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FSPlayer", "FSPlayer\FSPlayer.vcxproj", "{8B63C853-C990-4EB7-B631-D110426772C2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8B63C853-C990-4EB7-B631-D110426772C2}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {8B63C853-C990-4EB7-B631-D110426772C2}.Debug|Win32.Build.0 = Debug|Win32 16 | {8B63C853-C990-4EB7-B631-D110426772C2}.Release|Win32.ActiveCfg = Release|Win32 17 | {8B63C853-C990-4EB7-B631-D110426772C2}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /FSPlayer/PacketQueue.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "PacketQueue.h" 3 | #include 4 | 5 | extern bool quit; 6 | 7 | PacketQueue::PacketQueue() 8 | { 9 | nb_packets = 0; 10 | size = 0; 11 | 12 | mutex = SDL_CreateMutex(); 13 | cond = SDL_CreateCond(); 14 | } 15 | 16 | bool PacketQueue::enQueue(const AVPacket *packet) 17 | { 18 | AVPacket *pkt = av_packet_alloc(); 19 | if (av_packet_ref(pkt, packet) < 0) 20 | return false; 21 | 22 | SDL_LockMutex(mutex); 23 | queue.push(*pkt); 24 | 25 | size += pkt->size; 26 | nb_packets++; 27 | 28 | SDL_CondSignal(cond); 29 | SDL_UnlockMutex(mutex); 30 | return true; 31 | } 32 | 33 | bool PacketQueue::deQueue(AVPacket *packet, bool block) 34 | { 35 | bool ret = false; 36 | 37 | SDL_LockMutex(mutex); 38 | while (true) 39 | { 40 | if (quit) 41 | { 42 | ret = false; 43 | break; 44 | } 45 | 46 | if (!queue.empty()) 47 | { 48 | if (av_packet_ref(packet, &queue.front()) < 0) 49 | { 50 | ret = false; 51 | break; 52 | } 53 | AVPacket pkt = queue.front(); 54 | 55 | queue.pop(); 56 | av_packet_unref(&pkt); 57 | nb_packets--; 58 | size -= packet->size; 59 | 60 | ret = true; 61 | break; 62 | } 63 | else if (!block) 64 | { 65 | ret = false; 66 | break; 67 | } 68 | else 69 | { 70 | SDL_CondWait(cond, mutex); 71 | } 72 | } 73 | SDL_UnlockMutex(mutex); 74 | return ret; 75 | } -------------------------------------------------------------------------------- /FSPlayer/FSPlayer.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 源文件 35 | 36 | 37 | 源文件 38 | 39 | 40 | 41 | 42 | 头文件 43 | 44 | 45 | 头文件 46 | 47 | 48 | 头文件 49 | 50 | 51 | 头文件 52 | 53 | 54 | 头文件 55 | 56 | 57 | 头文件 58 | 59 | 60 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /FSPlayer/Media.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Media.h" 3 | #include 4 | 5 | extern "C"{ 6 | #include 7 | } 8 | extern bool quit; 9 | 10 | MediaState::MediaState(char* input_file) 11 | :filename(input_file) 12 | { 13 | pFormatCtx = nullptr; 14 | audio = new AudioState(); 15 | 16 | video = new VideoState(); 17 | //quit = false; 18 | } 19 | 20 | MediaState::~MediaState() 21 | { 22 | if(audio) 23 | delete audio; 24 | 25 | if (video) 26 | delete video; 27 | } 28 | 29 | bool MediaState::openInput() 30 | { 31 | // Open input file 32 | if (avformat_open_input(&pFormatCtx, filename, nullptr, nullptr) < 0) 33 | return false; 34 | 35 | if (avformat_find_stream_info(pFormatCtx, nullptr) < 0) 36 | return false; 37 | 38 | // Output the stream info to standard 39 | av_dump_format(pFormatCtx, 0, filename, 0); 40 | 41 | for (uint32_t i = 0; i < pFormatCtx->nb_streams; i++) 42 | { 43 | if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio->stream_index < 0) 44 | audio->stream_index = i; 45 | 46 | if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && video->stream_index < 0) 47 | video->stream_index = i; 48 | } 49 | 50 | if (audio->stream_index < 0 || video->stream_index < 0) 51 | return false; 52 | 53 | // Fill audio state 54 | AVCodec *pCodec = avcodec_find_decoder(pFormatCtx->streams[audio->stream_index]->codec->codec_id); 55 | if (!pCodec) 56 | return false; 57 | 58 | audio->stream = pFormatCtx->streams[audio->stream_index]; 59 | 60 | audio->audio_ctx = avcodec_alloc_context3(pCodec); 61 | if (avcodec_copy_context(audio->audio_ctx, pFormatCtx->streams[audio->stream_index]->codec) != 0) 62 | return false; 63 | 64 | avcodec_open2(audio->audio_ctx, pCodec, nullptr); 65 | 66 | // Fill video state 67 | AVCodec *pVCodec = avcodec_find_decoder(pFormatCtx->streams[video->stream_index]->codec->codec_id); 68 | if (!pVCodec) 69 | return false; 70 | 71 | video->stream = pFormatCtx->streams[video->stream_index]; 72 | 73 | video->video_ctx = avcodec_alloc_context3(pVCodec); 74 | if (avcodec_copy_context(video->video_ctx, pFormatCtx->streams[video->stream_index]->codec) != 0) 75 | return false; 76 | 77 | avcodec_open2(video->video_ctx, pVCodec, nullptr); 78 | 79 | video->frame_timer = static_cast(av_gettime()) / 1000000.0; 80 | video->frame_last_delay = 40e-3; 81 | 82 | return true; 83 | } 84 | 85 | int decode_thread(void *data) 86 | { 87 | MediaState *media = (MediaState*)data; 88 | 89 | AVPacket *packet = av_packet_alloc(); 90 | 91 | while (true) 92 | { 93 | int ret = av_read_frame(media->pFormatCtx, packet); 94 | if (ret < 0) 95 | { 96 | if (ret == AVERROR_EOF) 97 | break; 98 | if (media->pFormatCtx->pb->error == 0) // No error,wait for user input 99 | { 100 | SDL_Delay(100); 101 | continue; 102 | } 103 | else 104 | break; 105 | } 106 | 107 | if (packet->stream_index == media->audio->stream_index) // audio stream 108 | { 109 | media->audio->audioq.enQueue(packet); 110 | av_packet_unref(packet); 111 | } 112 | 113 | else if (packet->stream_index == media->video->stream_index) // video stream 114 | { 115 | media->video->videoq->enQueue(packet); 116 | av_packet_unref(packet); 117 | } 118 | else 119 | av_packet_unref(packet); 120 | } 121 | 122 | av_packet_free(&packet); 123 | 124 | return 0; 125 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | FSPlayer/FFmpegX86D.props 10 | FSPlayer/SDL2X86D.props 11 | 12 | # Build results 13 | [Dd]ebug/ 14 | [Dd]ebugPublic/ 15 | [Rr]elease/ 16 | x64/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Build Results of an ATL Project 34 | [Dd]ebugPS/ 35 | [Rr]eleasePS/ 36 | dlldata.c 37 | 38 | *_i.c 39 | *_p.c 40 | *_i.h 41 | *.ilk 42 | *.meta 43 | *.obj 44 | *.pch 45 | *.pdb 46 | *.pgc 47 | *.pgd 48 | *.rsp 49 | *.sbr 50 | *.tlb 51 | *.tli 52 | *.tlh 53 | *.tmp 54 | *.tmp_proj 55 | *.log 56 | *.vspscc 57 | *.vssscc 58 | .builds 59 | *.pidb 60 | *.svclog 61 | *.scc 62 | 63 | # Chutzpah Test files 64 | _Chutzpah* 65 | 66 | # Visual C++ cache files 67 | ipch/ 68 | *.aps 69 | *.ncb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | *.vspx 78 | 79 | # TFS 2012 Local Workspace 80 | $tf/ 81 | 82 | # Guidance Automation Toolkit 83 | *.gpState 84 | 85 | # ReSharper is a .NET coding add-in 86 | _ReSharper*/ 87 | *.[Rr]e[Ss]harper 88 | *.DotSettings.user 89 | 90 | # JustCode is a .NET coding addin-in 91 | .JustCode 92 | 93 | # TeamCity is a build add-in 94 | _TeamCity* 95 | 96 | # DotCover is a Code Coverage Tool 97 | *.dotCover 98 | 99 | # NCrunch 100 | _NCrunch_* 101 | .*crunch*.local.xml 102 | 103 | # MightyMoose 104 | *.mm.* 105 | AutoTest.Net/ 106 | 107 | # Web workbench (sass) 108 | .sass-cache/ 109 | 110 | # Installshield output folder 111 | [Ee]xpress/ 112 | 113 | # DocProject is a documentation generator add-in 114 | DocProject/buildhelp/ 115 | DocProject/Help/*.HxT 116 | DocProject/Help/*.HxC 117 | DocProject/Help/*.hhc 118 | DocProject/Help/*.hhk 119 | DocProject/Help/*.hhp 120 | DocProject/Help/Html2 121 | DocProject/Help/html 122 | 123 | # Click-Once directory 124 | publish/ 125 | 126 | # Publish Web Output 127 | *.[Pp]ublish.xml 128 | *.azurePubxml 129 | ## TODO: Comment the next line if you want to checkin your 130 | ## web deploy settings but do note that will include unencrypted 131 | ## passwords 132 | #*.pubxml 133 | 134 | # NuGet Packages Directory 135 | packages/* 136 | ## TODO: If the tool you use requires repositories.config 137 | ## uncomment the next line 138 | #!packages/repositories.config 139 | 140 | # Enable "build/" folder in the NuGet Packages folder since 141 | # NuGet packages use it for MSBuild targets. 142 | # This line needs to be after the ignore of the build folder 143 | # (and the packages folder if the line above has been uncommented) 144 | !packages/build/ 145 | 146 | # Windows Azure Build Output 147 | csx/ 148 | *.build.csdef 149 | 150 | # Windows Store app package directory 151 | AppPackages/ 152 | 153 | # Others 154 | sql/ 155 | *.Cache 156 | ClientBin/ 157 | [Ss]tyle[Cc]op.* 158 | ~$* 159 | *~ 160 | *.dbmdl 161 | *.dbproj.schemaview 162 | *.pfx 163 | *.publishsettings 164 | node_modules/ 165 | 166 | # RIA/Silverlight projects 167 | Generated_Code/ 168 | 169 | # Backup & report files from converting an old project file 170 | # to a newer Visual Studio version. Backup files are not needed, 171 | # because we have git ;-) 172 | _UpgradeReport_Files/ 173 | Backup*/ 174 | UpgradeLog*.XML 175 | UpgradeLog*.htm 176 | 177 | # SQL Server files 178 | *.mdf 179 | *.ldf 180 | 181 | # Business Intelligence projects 182 | *.rdl.data 183 | *.bim.layout 184 | *.bim_*.settings 185 | 186 | # Microsoft Fakes 187 | FakesAssemblies/ 188 | 189 | # LightSwitch generated files 190 | GeneratedArtifacts/ 191 | _Pvt_Extensions/ 192 | ModelManifest.xml -------------------------------------------------------------------------------- /FSPlayer/FSPlayer.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {8B63C853-C990-4EB7-B631-D110426772C2} 15 | Win32Proj 16 | FSPlayer 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | true 46 | 47 | 48 | false 49 | 50 | 51 | 52 | 53 | 54 | Level3 55 | Disabled 56 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 57 | 58 | 59 | Console 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | 67 | 68 | MaxSpeed 69 | true 70 | true 71 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 72 | 73 | 74 | Console 75 | true 76 | true 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | --------------------------------------------------------------------------------