| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | #include "FFmpegHeaders.hpp" |
|---|
| 15 | #include "FFmpegImageStream.hpp" |
|---|
| 16 | #include "FFmpegParameters.hpp" |
|---|
| 17 | |
|---|
| 18 | #include <osgDB/Registry> |
|---|
| 19 | #include <osgDB/FileNameUtils> |
|---|
| 20 | #include <osgDB/FileUtils> |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | #if LIBAVCODEC_VERSION_MAJOR >= 53 || \ |
|---|
| 24 | (LIBAVCODEC_VERSION_MAJOR==52 && LIBAVCODEC_VERSION_MINOR>=30) || \ |
|---|
| 25 | (LIBAVCODEC_VERSION_MAJOR==52 && LIBAVCODEC_VERSION_MINOR==20 && LIBAVCODEC_VERSION_MICRO >= 1) |
|---|
| 26 | #define USE_AV_LOCK_MANAGER |
|---|
| 27 | #endif |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | class ReaderWriterFFmpeg : public osgDB::ReaderWriter |
|---|
| 34 | { |
|---|
| 35 | public: |
|---|
| 36 | |
|---|
| 37 | ReaderWriterFFmpeg() |
|---|
| 38 | { |
|---|
| 39 | supportsProtocol("http","Read video/audio from http using ffmpeg."); |
|---|
| 40 | supportsProtocol("rtsp","Read video/audio from rtsp using ffmpeg."); |
|---|
| 41 | |
|---|
| 42 | supportsExtension("ffmpeg", ""); |
|---|
| 43 | supportsExtension("avi", ""); |
|---|
| 44 | supportsExtension("flv", "Flash video"); |
|---|
| 45 | supportsExtension("mov", "Quicktime"); |
|---|
| 46 | supportsExtension("ogg", "Theora movie format"); |
|---|
| 47 | supportsExtension("mpg", "Mpeg movie format"); |
|---|
| 48 | supportsExtension("mpv", "Mpeg movie format"); |
|---|
| 49 | supportsExtension("wmv", "Windows Media Video format"); |
|---|
| 50 | supportsExtension("mkv", "Matroska"); |
|---|
| 51 | supportsExtension("mjpeg", "Motion JPEG"); |
|---|
| 52 | supportsExtension("mp4", "MPEG-4"); |
|---|
| 53 | supportsExtension("m4v", "MPEG-4"); |
|---|
| 54 | supportsExtension("sav", "Unknown"); |
|---|
| 55 | supportsExtension("3gp", "3G multi-media format"); |
|---|
| 56 | supportsExtension("sdp", "Session Description Protocol"); |
|---|
| 57 | supportsExtension("m2ts", "MPEG-2 Transport Stream"); |
|---|
| 58 | |
|---|
| 59 | supportsOption("format", "Force setting input format (e.g. vfwcap for Windows webcam)"); |
|---|
| 60 | supportsOption("pixel_format", "Set pixel format"); |
|---|
| 61 | supportsOption("frame_size", "Set frame size (e.g. 320x240)"); |
|---|
| 62 | supportsOption("frame_rate", "Set frame rate (e.g. 25)"); |
|---|
| 63 | supportsOption("audio_sample_rate", "Set audio sampling rate (e.g. 44100)"); |
|---|
| 64 | |
|---|
| 65 | #ifdef USE_AV_LOCK_MANAGER |
|---|
| 66 | |
|---|
| 67 | av_lockmgr_register(&lockMgr); |
|---|
| 68 | #endif |
|---|
| 69 | |
|---|
| 70 | av_register_all(); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | virtual ~ReaderWriterFFmpeg() |
|---|
| 74 | { |
|---|
| 75 | } |
|---|
| 76 | |
|---|
| 77 | virtual const char * className() const |
|---|
| 78 | { |
|---|
| 79 | return "ReaderWriterFFmpeg"; |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | virtual ReadResult readImage(const std::string & filename, const osgDB::ReaderWriter::Options* options) const |
|---|
| 83 | { |
|---|
| 84 | const std::string ext = osgDB::getLowerCaseFileExtension(filename); |
|---|
| 85 | if (ext=="ffmpeg") return readImage(osgDB::getNameLessExtension(filename),options); |
|---|
| 86 | |
|---|
| 87 | if (filename.compare(0, 5, "/dev/")==0) |
|---|
| 88 | { |
|---|
| 89 | return readImageStream(filename, NULL); |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | osg::ref_ptr<osgFFmpeg::FFmpegParameters> parameters(new osgFFmpeg::FFmpegParameters); |
|---|
| 93 | parseOptions(parameters.get(), options); |
|---|
| 94 | if (parameters->isFormatAvailable()) |
|---|
| 95 | { |
|---|
| 96 | return readImageStream(filename, parameters.get()); |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | if (! acceptsExtension(ext)) |
|---|
| 100 | return ReadResult::FILE_NOT_HANDLED; |
|---|
| 101 | |
|---|
| 102 | const std::string path = osgDB::containsServerAddress(filename) ? |
|---|
| 103 | filename : |
|---|
| 104 | osgDB::findDataFile(filename, options); |
|---|
| 105 | |
|---|
| 106 | if (path.empty()) |
|---|
| 107 | return ReadResult::FILE_NOT_FOUND; |
|---|
| 108 | |
|---|
| 109 | return readImageStream(path, parameters.get()); |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | ReadResult readImageStream(const std::string& filename, osgFFmpeg::FFmpegParameters* parameters) const |
|---|
| 113 | { |
|---|
| 114 | OSG_INFO << "ReaderWriterFFmpeg::readImage " << filename << std::endl; |
|---|
| 115 | |
|---|
| 116 | osg::ref_ptr<osgFFmpeg::FFmpegImageStream> image_stream(new osgFFmpeg::FFmpegImageStream); |
|---|
| 117 | |
|---|
| 118 | if (! image_stream->open(filename, parameters)) |
|---|
| 119 | return ReadResult::FILE_NOT_HANDLED; |
|---|
| 120 | |
|---|
| 121 | return image_stream.release(); |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | private: |
|---|
| 125 | |
|---|
| 126 | void parseOptions(osgFFmpeg::FFmpegParameters* parameters, const osgDB::ReaderWriter::Options * options) const |
|---|
| 127 | { |
|---|
| 128 | if (options && options->getNumPluginStringData()>0) |
|---|
| 129 | { |
|---|
| 130 | const FormatDescriptionMap& supportedOptList = supportedOptions(); |
|---|
| 131 | for (FormatDescriptionMap::const_iterator itr = supportedOptList.begin(); |
|---|
| 132 | itr != supportedOptList.end(); ++itr) |
|---|
| 133 | { |
|---|
| 134 | const std::string& name = itr->first; |
|---|
| 135 | parameters->parse(name, options->getPluginStringData(name)); |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | } |
|---|
| 139 | |
|---|
| 140 | #ifdef USE_AV_LOCK_MANAGER |
|---|
| 141 | static int lockMgr(void **mutex, enum AVLockOp op) |
|---|
| 142 | { |
|---|
| 143 | |
|---|
| 144 | OpenThreads::Mutex **m=(OpenThreads::Mutex**)mutex; |
|---|
| 145 | if (op==AV_LOCK_CREATE) |
|---|
| 146 | { |
|---|
| 147 | *m=new OpenThreads::Mutex; |
|---|
| 148 | return !*m; |
|---|
| 149 | } |
|---|
| 150 | else if (op==AV_LOCK_DESTROY) |
|---|
| 151 | { |
|---|
| 152 | delete *m; |
|---|
| 153 | return 0; |
|---|
| 154 | } |
|---|
| 155 | else if (op==AV_LOCK_OBTAIN) |
|---|
| 156 | { |
|---|
| 157 | (*m)->lock(); |
|---|
| 158 | return 0; |
|---|
| 159 | } |
|---|
| 160 | else if (op==AV_LOCK_RELEASE) |
|---|
| 161 | { |
|---|
| 162 | (*m)->unlock(); |
|---|
| 163 | return 0; |
|---|
| 164 | } |
|---|
| 165 | else |
|---|
| 166 | { |
|---|
| 167 | return -1; |
|---|
| 168 | } |
|---|
| 169 | } |
|---|
| 170 | #endif |
|---|
| 171 | |
|---|
| 172 | }; |
|---|
| 173 | |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | REGISTER_OSGPLUGIN(ffmpeg, ReaderWriterFFmpeg) |
|---|