Play a Video from MemoryStream, Using FFMpeg

后端 未结 3 1711
庸人自扰
庸人自扰 2020-12-25 08:16

I\'m having a hard time, searching how to play a video file from a TMemoryStream (or a similar buffer in memory) using FFMpeg. I\'ve seen many things, including UltraStarDX,

3条回答
  •  眼角桃花
    2020-12-25 08:54

    To play video from memory stream, you can use custom AVIOContext.

    static const int kBufferSize = 4 * 1024;
    
    class my_iocontext_private
    {
    private:
        my_iocontext_private(my_iocontext_private const &);
        my_iocontext_private& operator = (my_iocontext_private const &);
    
    public:
        my_iocontext_private(IInputStreamPtr inputStream)
           : inputStream_(inputStream)
           , buffer_size_(kBufferSize)
           , buffer_(static_cast(::av_malloc(buffer_size_))) {
        ctx_ = ::avio_alloc_context(buffer_, buffer_size_, 0, this,
               &my_iocontext_private::read, NULL, &my_iocontext_private::seek); 
        }
    
        ~my_iocontext_private() { 
            ::av_free(ctx_);
            ::av_free(buffer_); 
        }
    
        void reset_inner_context() { ctx_ = NULL; buffer_ = NULL; }
    
        static int read(void *opaque, unsigned char *buf, int buf_size) {
            my_iocontext_private* h = static_cast(opaque);
            return h->inputStream_->Read(buf, buf_size); 
        }
    
        static int64_t seek(void *opaque, int64_t offset, int whence) {
            my_iocontext_private* h = static_cast(opaque);
    
            if (0x10000 == whence)
                return h->inputStream_->Size();
    
            return h->inputStream_->Seek(offset, whence); 
        }
    
        ::AVIOContext *get_avio() { return ctx_; }
    
        private:
           IInputStreamPtr inputStream_; // abstract stream interface, You can adapt it to TMemoryStream  
           int buffer_size_;
           unsigned char * buffer_;  
           ::AVIOContext * ctx_;
       };
    
    
       //// ..........
    
       /// prepare input stream:
       IInputStreamPtr inputStream = MyCustomCreateInputStreamFromMemory();
    
       my_iocontext_private priv_ctx(inputStream);
       AVFormatContext * ctx = ::avformat_alloc_context();
       ctx->pb = priv_ctx.get_avio();
    
       int err = avformat_open_input(&ctx, "arbitrarytext", NULL, NULL);
       if (err < 0) 
           return -1;
    
       //// normal usage of ctx
       //// avformat_find_stream_info(ctx, NULL);
       //// av_read_frame(ctx, &pkt); 
       //// etc..
    

提交回复
热议问题