|
bool CWriteMp4::AddStream(int nWidth, int nHeight)
{
AVCodecContext *pC;
m_pVideoSt = avformat_new_stream(m_pOc, NULL);
if (!m_pVideoSt)
goto Exit0;
m_pVideoSt->id = m_pOc->nb_streams-1;
pC = m_pVideoSt->codec;
pC->codec_id = CODEC_ID_H264;
pC->bit_rate = 400000;
pC->width = nWidth;
pC->height = nHeight;
pC->time_base.den = STREAM_FRAME_RATE;
pC->time_base.num = 1;
pC->gop_size = 12;
pC->pix_fmt = STREAM_PIX_FMT;
if (pC->codec_id == AV_CODEC_ID_MPEG2VIDEO)
pC->max_b_frames = 2;
if (pC->codec_id == AV_CODEC_ID_MPEG1VIDEO)
pC->mb_decision = 2;
if (m_pOc->oformat->flags & AVFMT_GLOBALHEADER)
pC->flags |= CODEC_FLAG_GLOBAL_HEADER;
return true;
Exit0:
return false;
}
bool CWriteMp4::CreateMp4(const char* pszFileName, int nWidth, int nHeight)
{
AVOutputFormat* pFmt;
avformat_alloc_output_context2(&m_pOc, NULL, NULL, pszFileName);
if (!m_pOc)
avformat_alloc_output_context2(&m_pOc, NULL, "mpeg", pszFileName);
if (!m_pOc)
goto Exit0;
pFmt = m_pOc->oformat;
if (!AddStream(nWidth, nHeight))
goto Exit0;
if (!(pFmt->flags & AVFMT_NOFILE))
{
if (avio_open(&m_pOc->pb, pszFileName, AVIO_FLAG_WRITE) < 0)
goto Exit0;
}
if (avformat_write_header(m_pOc, NULL) < 0)
goto Exit0;
return true;
Exit0:
return false;
}
bool CWriteMp4::WriteVideo(const char* data, int nLen)
{
AVPacket pkt = {0};
const AVRational *time_base = &m_pVideoSt->codec->time_base;
av_init_packet(&pkt);
m_qwFileSize += nLen;
pkt.data = (uint8_t *)data;
pkt.size = nLen;
pkt.pts = av_rescale_q_rnd(pkt.pts, *time_base, m_pVideoSt->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, *time_base, m_pVideoSt->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, *time_base, m_pVideoSt->time_base);
pkt.stream_index = m_pVideoSt->index;
av_interleaved_write_frame(m_pOc, &pkt);
return true;
}
void CWriteMp4::CloseMp4()
{
if (m_pOc)
av_write_trailer(m_pOc);
m_pVideoSt = NULL;
if (m_pOc && !(m_pOc->oformat->flags & AVFMT_NOFILE))
avio_close(m_pOc->pb);
if (m_pOc)
{
avformat_free_context(m_pOc);
m_pOc = NULL;
}
m_qwFileSize = 0;
}
|
|