libav

2012-12-12 4 views
7

का उपयोग कर स्मृति से वीडियो फ़ाइल को डीकोड करें मान लीजिए मेरे पास स्मृति में एक संपूर्ण वीडियो फ़ाइल है और मैं पूरे फ्रेम को डीकोड करने के लिए libav का उपयोग करना चाहता हूं। मैं इसे कैसे करूं? मुद्दा यह है कि मैं इसे avformat_open_input() फ़ंक्शन का उपयोग करके फ़ाइल से सीधे पढ़ सकता हूं लेकिन मुझे इसे स्मृति में संग्रहीत फ़ाइल से करने की आवश्यकता है।libav

मेरे AVIOContext कार्यान्वयन:

class AVIOMemContext 
{ 

public: 

    AVIOMemContext(char* videoData, const int videoLen) 
    { 
     // Output buffer 
     bufferSize = 32768; 
     buffer = static_cast<char*>(av_malloc(bufferSize)); 

     // Internal buffer 
     pos = 0; 
     this->videoData = videoData; 
     this->videoLen = videoLen; 

     ctx_ = avio_alloc_context((unsigned char*) buffer, bufferSize, AVIO_FLAG_READ, this, &AVIOMemContext::read, &AVIOMemContext::write, &AVIOMemContext::seek); 
    } 

    ~AVIOMemContext() 
    { 
     av_free(videoData); 
    } 

    static int read(void *opaque, unsigned char *buf, int buf_size) 
    { 
     AVIOMemContext* This = static_cast<AVIOMemContext*>(opaque); 

     // Read from pos to pos + buf_size 
     if (This->pos + buf_size > This->videoLen) 
     { 
      int len = This->videoLen - This->pos; 
      memcpy(buf, This->videoData + This->pos, len); 
      return len; 
     } 
     else 
     { 
      memcpy(buf, This->videoData + This->pos, buf_size); 
      return buf_size; 
     } 
    } 

    static int write(void *opaque, unsigned char *buf, int buf_size) 
    { 
     /* 
     AVIOMemContext* This = static_cast<AVIOMemContext*>(opaque); 
     return fwrite(buf, 1, buf_size, This->f_); 
     */ 

     return 0; 
    } 

    static int64_t seek(void *opaque, int64_t offset, int whence) 
    { 
     AVIOMemContext* This = static_cast<AVIOMemContext*>(opaque); 

     if (offset + whence > This->videoLen) 
     { 
      This->pos = This->videoLen; 

      return -1; 
     } 
     else 
     { 
      This->pos = offset + whence; 

      return 0; 
     } 
    } 

    AVIOContext *get_avio() 
    { 
     return ctx_; 
    } 

private: 

    // Output buffer 
    int bufferSize; 
    char* buffer; 

    // Internal buffer 
    int pos; 
    char* videoData; 
    int videoLen; 

    AVIOContext* ctx_; 

}; 

मेरे वर्तमान कोड:

[...] 

av_register_all(); 
avcodec_register_all(); 

AVFormatContext* context; 
AVCodec* pCodec; 
AVPacket packet; 
AVCodecContext* pCodecCtx; 
int video_stream_index; 
int res; 
int got_picture; 

// Init variables and objects 
context = avformat_alloc_context(); 

AVIOMemContext priv_ctx(videoData, videoLen); 
context->pb = priv_ctx.get_avio(); 

res = avformat_find_stream_info(context, NULL); 

if (res < 0) 
{ 
    // Error 
    avformat_free_context(context); 

    return 0; 
} 

// Obtain the video stream of the total set of streams 
for (unsigned int k = 0; k < context->nb_streams; ++k) 
{ 
    if (context->streams[k]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 
     video_stream_index = k; 
    context->streams[k]->codec->time_base.den = 90000; 
} 

pCodecCtx = context->streams[video_stream_index]->codec; 
pCodec = avcodec_find_decoder(pCodecCtx->codec_id); 

avcodec_open(pCodecCtx, pCodec); 

//allocate video frame 
AVFrame *pFrame = avcodec_alloc_frame(); 

unsigned int nFrame = 0; 

while (av_read_frame(context, &packet) >= 0) 

[...] 

अग्रिम धन्यवाद,

दिदाक पेरेज़

उत्तर

3

आप अपनी खुद की AVIOContext बना सकते हैं। आपको ::avio_alloc_context पर कॉल करना होगा और फिर इसे AVFormatContext::pb पर सेट करना होगा। विवरण के लिए, मेरा जवाब How can libavformat be used without using other libav libraries?

+0

आपकी सहायता के लिए धन्यवाद, मैं अभी इसे आजमाउंगा। –

+0

मैंने वर्तमान में अपना स्वयं का AVIOContext बनाया है लेकिन ऐप avformat_find_stream_info() में क्रैश हो गया है –