का उपयोग कर स्मृति से वीडियो फ़ाइल को डीकोड करें मान लीजिए मेरे पास स्मृति में एक संपूर्ण वीडियो फ़ाइल है और मैं पूरे फ्रेम को डीकोड करने के लिए 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)
[...]
अग्रिम धन्यवाद,
दिदाक पेरेज़
आपकी सहायता के लिए धन्यवाद, मैं अभी इसे आजमाउंगा। –
मैंने वर्तमान में अपना स्वयं का AVIOContext बनाया है लेकिन ऐप avformat_find_stream_info() में क्रैश हो गया है –