Use FileGroup in FFmpeg.
authorCarl Hetherington <cth@carlh.net>
Sat, 23 Nov 2013 13:12:04 +0000 (13:12 +0000)
committerCarl Hetherington <cth@carlh.net>
Sat, 23 Nov 2013 13:12:04 +0000 (13:12 +0000)
src/lib/content.h
src/lib/ffmpeg.cc
src/lib/ffmpeg.h
src/lib/file_group.cc
src/lib/file_group.h

index e569c1431a7907064150ede6f72f82829edaceb2..b4d90b22f4353a28a800424652ba9cd43a3a16f8 100644 (file)
@@ -68,6 +68,11 @@ public:
 
        std::string path_summary () const;
 
+       std::vector<boost::filesystem::path> paths () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _paths;
+       }
+
        size_t number_of_paths () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _paths.size ();
index bc2f67a9d868266ad67058feb4bbe863a4b957e0..bbf853af1588aaad35a98618150a7594007152b4 100644 (file)
@@ -40,6 +40,9 @@ boost::mutex FFmpeg::_mutex;
 /** @param long_probe true to do a long probe of the file looking for streams */
 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c, bool long_probe)
        : _ffmpeg_content (c)
+       , _avio_buffer (0)
+       , _avio_buffer_size (4096)
+       , _avio_context (0)
        , _format_context (0)
        , _frame (0)
        , _video_stream (-1)
@@ -65,11 +68,33 @@ FFmpeg::~FFmpeg ()
        avformat_close_input (&_format_context);
 }
 
+static int
+avio_read_wrapper (void* data, uint8_t* buffer, int amount)
+{
+       return reinterpret_cast<FFmpeg*>(data)->avio_read (buffer, amount);
+}
+
+static int64_t
+avio_seek_wrapper (void* data, int64_t offset, int whence)
+{
+       if (whence == AVSEEK_SIZE) {
+               return reinterpret_cast<FFmpeg*>(data)->avio_length ();
+       }
+                       
+       return reinterpret_cast<FFmpeg*>(data)->avio_seek (offset, whence);
+}
+
 void
 FFmpeg::setup_general (bool long_probe)
 {
        av_register_all ();
 
+       _file_group.set_paths (_ffmpeg_content->paths ());
+       _avio_buffer = static_cast<uint8_t*> (av_malloc (_avio_buffer_size));
+       _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
+       _format_context = avformat_alloc_context ();
+       _format_context->pb = _avio_context;
+       
        AVDictionary* options = 0;
        if (long_probe) {
                /* These durations are in microseconds, and represent how far into the content file
@@ -157,3 +182,21 @@ FFmpeg::audio_codec_context () const
 {
        return _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec;
 }
+
+int
+FFmpeg::avio_read (uint8_t* buffer, int const amount)
+{
+       return _file_group.read (buffer, amount);
+}
+
+int64_t
+FFmpeg::avio_seek (int64_t const pos, int whence)
+{
+       return _file_group.seek (pos, whence);
+}
+
+int64_t
+FFmpeg::avio_size ()
+{
+       return _file_group.length ();
+}
index d5f4db2916c67e45fb014bb676397579a1cb8ef4..c94b8d8ac22ae697db346eb33c25afedb9b83a2d 100644 (file)
@@ -26,6 +26,7 @@
 extern "C" {
 #include <libavcodec/avcodec.h>
 }
+#include "file_group.h"
 
 struct AVFilterGraph;
 struct AVCodecContext;
@@ -35,6 +36,7 @@ struct AVFrame;
 struct AVBufferContext;
 struct AVCodec;
 struct AVStream;
+struct AVIOContext;
 
 class FFmpegContent;
 
@@ -48,16 +50,25 @@ public:
                return _ffmpeg_content;
        }
 
+       int avio_read (uint8_t *, int);
+       int64_t avio_seek (int64_t, int);
+       int64_t avio_length ();
+
 protected:
        AVCodecContext* video_codec_context () const;
        AVCodecContext* audio_codec_context () const;
        
        boost::shared_ptr<const FFmpegContent> _ffmpeg_content;
 
+       uint8_t* _avio_buffer;
+       int _avio_buffer_size;
+       AVIOContext* _avio_context;
+       FileGroup _file_group;
+       
        AVFormatContext* _format_context;
        AVPacket _packet;
        AVFrame* _frame;
-
+       
        int _video_stream;
 
        /* It would appear (though not completely verified) that one must have
index cdd78c6a30e0427c28887465a93274480934b73f..9c206514152acc077d84419a4afafe846283c4e3 100644 (file)
 using std::vector;
 using std::cout;
 
+FileGroup::FileGroup ()
+       : _current_path (0)
+       , _current_file (0)
+{
+
+}
+
 FileGroup::FileGroup (boost::filesystem::path p)
        : _current_path (0)
        , _current_file (0)
@@ -49,6 +56,13 @@ FileGroup::~FileGroup ()
        }
 }
 
+void
+FileGroup::set_paths (vector<boost::filesystem::path> const & p)
+{
+       _paths = p;
+       ensure_open_path (0);
+       seek (0, SEEK_SET);
+}
 
 /** Ensure that the given path index in the content is the _current_file */
 void
index 99803d3869fdd9b0f6367bcdf7a8c39cd2ba16c5..65091c93646ac410c7f83b2c1a6d90dc1ef70e3a 100644 (file)
 class FileGroup
 {
 public:
+       FileGroup ();
        FileGroup (boost::filesystem::path);
        FileGroup (std::vector<boost::filesystem::path> const &);
        ~FileGroup ();
 
+       void set_paths (std::vector<boost::filesystem::path> const &);
+
        int64_t seek (int64_t, int) const;
        int read (uint8_t*, int) const;
        int64_t length () const;