Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265

Сообщение Anonymous »

Я хочу сжать видеопоток в формате 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265
    Anonymous » » в форуме C++
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Кодирование живого видео в качестве H265 и потоковое его по RTP
    Anonymous » » в форуме C++
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Я декодирую формат MJPG в формат YUY2 с помощью оборудования Intel и происходит сбой в API «ProcessOut» [закрыто]
    Anonymous » » в форуме C++
    0 Ответы
    35 Просмотры
    Последнее сообщение Anonymous
  • AVFrame с форматом NV12 прерывается с использованием аппаратного ускорения D3D11.
    Anonymous » » в форуме C#
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • WebRTC H265 в браузере
    Anonymous » » в форуме C++
    0 Ответы
    34 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»