[Libav-user] Writing raw images to AVI file

Dejan Črnila dejan.crnila at dewesoft.com
Fri Nov 30 14:03:54 CET 2012


Hi,

I'm developing a plugin for writing raw images to uncompressed AVI. The
problem is that if file is larger than 1GB, windows media player cannot
open it, but media player classic can. Additionaly writing is stopped once
file size reaches 2GB and seeking does not work anymore. AVI muxer in
FFMPEG is supposed to support OpenDML AVI 2.0, right?

Any ideas?

Source code
----------------------------
#define RET(x) { res = x; goto failed;}

HRESULT __stdcall CFFMPEGVideoStoreEngine::CreateFile(BSTR fileName, int
pixelFormat, int width, int height, double frameRate)
{
DBGPRINT(_T("CFFMPEGVideoStoreEngine::CreateFile called"));
DBGPRINT(_T("  param fileName: %s"), fileName);

HRESULT res;
 _bstr_t fName;
fName.Assign(fileName);

if (!g_registered)
{
av_register_all();
g_registered = true;
}

m_lastErrNum = avformat_alloc_output_context2(&m_pFmtCtx, NULL, NULL,
fName);
if (m_lastErrNum < 0)
RET(FFMPEG_E_NOOUTPUTFORMAT);

AVOutputFormat* pOutFmt = m_pFmtCtx->oformat;

AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_RAWVIDEO);
 m_pStream = avformat_new_stream(m_pFmtCtx, codec);
if (!m_pStream)
RET(FFMPEG_E_CREATESTREAMFAILED);
 m_pCodCtx = m_pStream->codec;

        avcodec_get_context_defaults3(m_pCodCtx, codec);

m_pCodCtx->width = width;
m_pCodCtx->height = height;
m_pCodCtx->time_base = av_inv_q(av_d2q(frameRate, 1000));
m_pCodCtx->pix_fmt = (AVPixelFormat) pixelFormat;
if (pOutFmt->flags & AVFMT_GLOBALHEADER)
        m_pCodCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;

m_lastErrNum = avcodec_open2(m_pCodCtx, codec, NULL);
if (m_lastErrNum < 0)
RET(FFMPEG_E_OPENCODECFAILED);

m_pFrame = avcodec_alloc_frame();
        if (!m_pFrame)
RET(FFMPEG_E_ALLOCFRAMEFAILED);

int picSize = avpicture_get_size(m_pCodCtx->pix_fmt, m_pCodCtx->width,
m_pCodCtx->height);

m_pFrame->format = m_pCodCtx->pix_fmt;
m_pFrame->width = m_pCodCtx->width;
m_pFrame->height = m_pCodCtx->height;

if (!(pOutFmt->flags & AVFMT_NOFILE))
{
        m_lastErrNum = avio_open(&m_pFmtCtx->pb, fName, AVIO_FLAG_WRITE);
if (m_lastErrNum < 0)
RET(FFMPEG_E_CREATEFILEFAILED);
}

m_lastErrNum = avformat_write_header(m_pFmtCtx, NULL);
if (m_lastErrNum < 0)
{
avio_close(m_pFmtCtx->pb);
RET(FFMPEG_E_WRITEFILEFAILED);
}

DBGPRINT(_T("CFFMPEGVideoLoadEngine::CreateFile succeeded"));
return S_OK;

failed:
DBGPRINT(_T("CFFMPEGVideoLoadEngine::OpenFile failed (exit code %x)"), res);

FreeResources();

return res;
}

HRESULT __stdcall CFFMPEGVideoStoreEngine::WriteFrame(void* pData, int len)
{
DBGPRINT(_T("CFFMPEGVideoStoreEngine::WriteFrame called"));

HRESULT res;

        AVPacket pkt;
        int got_output;

avpicture_fill((AVPicture*) m_pFrame, (uint8_t*) pData, m_pCodCtx->pix_fmt,
m_pCodCtx->width, m_pCodCtx->height);

av_init_packet(&pkt);
        pkt.data = NULL;    // packet data will be allocated by the encoder
        pkt.size = 0;

m_lastErrNum = avcodec_encode_video2(m_pCodCtx, &pkt, m_pFrame,
&got_output);
if (m_lastErrNum < 0)
RET(FFMPEG_E_ENCODEFAILED);

        if (got_output)
{
pkt.pts = pkt.dts = m_cnt++;
if (m_pCodCtx->coded_frame->key_frame)
pkt.flags |= AV_PKT_FLAG_KEY;

pkt.stream_index = m_pStream->index;

m_lastErrNum = av_write_frame(m_pFmtCtx, &pkt);
if (m_lastErrNum < 0)
RET(FFMPEG_E_WRITEFILEFAILED);

av_free_packet(&pkt);
}

DBGPRINT(_T("CFFMPEGVideoLoadEngine::WriteFrame succeeded"));
return S_OK;

failed:
DBGPRINT(_T("CFFMPEGVideoLoadEngine::WriteFrame failed (exit code %x)"),
res);

return res;
}

HRESULT __stdcall CFFMPEGVideoStoreEngine::CloseFile()
{
DBGPRINT(_T("CFFMPEGVideoStoreEngine::CloseFile called"));

// Close file

av_write_trailer(m_pFmtCtx);

if (!(m_pFmtCtx->oformat->flags & AVFMT_NOFILE))
        avio_close(m_pFmtCtx->pb);

FreeResources();

DBGPRINT(_T("CFFMPEGVideoLoadEngine::CloseFile succeeded"));
return S_OK;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121130/f2ab5a42/attachment.html>


More information about the Libav-user mailing list