Я хочу сжать видеопоток в формате Yuy2 или Uyvy, скажем, H265. Если я правильно понимаю ответы, данный этот поток, я должен быть в состоянии использовать функцию AV_IMAGE_FILL_ARRAYS () , чтобы заполнить массивы данных и размером LINES AVFRAME , вызовите AVCODEC_SEND_FRAME () , а затем AVCODEC_RECEIVE_PACKET () to ПОЛУЧИТЬ DATA: avcodec_find_encoder(AV_CODEC_ID_HEVC);
m_pCodecCtx = m_spAVCodecDlls->avcodec_alloc_context3(m_pCodec);
if (!m_pCodec || !m_pCodecCtx)
{
Log.Log(_T("Failed to find or allocate codec context!"));
return false;
}
AVPixelFormat ePixFmtInput = GetInputPixelFormat();
if (CanConvertInputFormat(ePixFmtInput) == false)
{
return false;
}
// we are able to convert
// so continue with setting it up
int nWidth = m_mtInput.GetWidth();
int nHeight = m_mtInput.GetHeight();
// Set encoding parameters
// Set bitrate (4 Mbps for 1920x1080)
m_pCodecCtx->bit_rate = (((int64)4000000 * nWidth / 1920) * nHeight / 1080);
m_pCodecCtx->width = nWidth;
m_pCodecCtx->height = nHeight;
// use reference time as time_base
m_pCodecCtx->time_base.den = 10000000;
m_pCodecCtx->time_base.num = 1;
SetAVRational(m_pCodecCtx->framerate, m_mtInput.GetFrameRate());
//m_pCodecCtx->framerate = (AVRational){ 30, 1 };
m_pCodecCtx->gop_size = 10; // GOP size
m_pCodecCtx->max_b_frames = 1;
// set pixel format
m_pCodecCtx->pix_fmt = ePixFmtInput; // YUV 4:2:0 format or YUV 4:2:2
// Open the codec
if (m_spAVCodecDlls->avcodec_open2(m_pCodecCtx, m_pCodec, NULL) < 0)
{
return false;
}
return true;
}
bool VideoEncoder::AllocateFrame()
{
m_pFrame = m_spAVCodecDlls->av_frame_alloc();
if (m_pFrame == NULL)
{
Log.Log(_T("Failed to allocate frame object!"));
return false;
}
m_pFrame->format = m_pCodecCtx->pix_fmt;
m_pFrame->width = m_pCodecCtx->width;
m_pFrame->height = m_pCodecCtx->height;
m_pFrame->time_base.den = m_pCodecCtx->time_base.den;
m_pFrame->time_base.num = m_pCodecCtx->time_base.num;
return true;
}
bool VideoEncoder::Encode(IMediaSample* pSample)
{
if (m_pFrame == NULL)
{
return false;
}
// get the time stamps
REFERENCE_TIME rtStart, rtEnd;
HRESULT hr = pSample->GetTime(&rtStart, &rtEnd);
m_rtInputFrameStart = rtStart;
m_rtInputFrameEnd = rtEnd;
// get length
int nLength = pSample->GetActualDataLength();
// get pointer to actual sample data
uint8_t* pData = NULL;
hr = pSample->GetPointer(&pData);
if (FAILED(hr) || NULL == pData)
return false;
m_pFrame->flags = (S_OK == pSample->IsSyncPoint()) ? (m_pFrame->flags | AV_FRAME_FLAG_KEY) : (m_pFrame->flags & ~AV_FRAME_FLAG_KEY);
// clear old data
for (int n = 0; n < AV_NUM_DATA_POINTERS; n++)
{
m_pFrame->data[n] = NULL;// (uint8_t*)aryData[n];
m_pFrame->linesize[n] = 0;// = aryStride[n];
}
int nRet = 0;
int nStride = m_mtInput.GetStride();
nRet = m_spAVCodecDlls->av_image_fill_arrays(m_pFrame->data, m_pFrame->linesize, pData, ePixFmt, m_pFrame->width, m_pFrame->height, 32);
if (nRet < 0)
{
return false;
}
m_pFrame->pts = (int64_t) rtStart;
m_pFrame->duration = rtEnd - rtStart;
nRet = m_spAVCodecDlls->avcodec_send_frame(m_pCodecCtx, m_pFrame);
if (nRet == AVERROR(EAGAIN))
{
ReceivePacket();
nRet = m_spAVCodecDlls->avcodec_send_frame(m_pCodecCtx, m_pFrame);
}
if (nRet < 0)
{
return false;
}
// Receive the encoded packets
ReceivePacket();
return true;
}
bool VideoEncoder::ReceivePacket()
{
bool bRet = true;
AVPacket* pkt = m_spAVCodecDlls->av_packet_alloc();
while (m_spAVCodecDlls->avcodec_receive_packet(m_pCodecCtx, pkt) == 0)
{
// Write pkt->data to output file or stream
m_pCallback->VideoEncoderWriteEncodedSample(pkt);
if (m_OutFile.IsOpen())
m_OutFile.Write(pkt->data, pkt->size);
m_spAVCodecDlls->av_packet_unref(pkt);
}
m_spAVCodecDlls->av_packet_free(&pkt);
return bRet;
}
< /code>
Я, должно быть, сделал что -то не так. Результат неверен. Например, вместо видео с лицом человека, показывающим в середине экрана, я получаю в основном зеленый экран с частями лица, отображаемых в левом нижнем и нижнем правом уголках.
может кто -нибудь мне помочь?
Подробнее здесь: https://stackoverflow.com/questions/795 ... -uyvy-into
Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265 ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265
Anonymous » » в форуме C++ - 0 Ответы
- 15 Просмотры
-
Последнее сообщение Anonymous
-
-
-
AVFrame с форматом NV12 прерывается с использованием аппаратного ускорения D3D11.
Anonymous » » в форуме C# - 0 Ответы
- 21 Просмотры
-
Последнее сообщение Anonymous
-