Я хочу сжать видеопоток в формате 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++
Программы на C++. Форум разработчиков
1745250819
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>
Я, должно быть, сделал что -то не так. Результат неверен. Например, вместо видео с лицом человека, показывающим в середине экрана, я получаю в основном зеленый экран с частями лица, отображаемых в левом нижнем и нижнем правом уголках.
может кто -нибудь мне помочь?
Подробнее здесь: [url]https://stackoverflow.com/questions/79581449/how-to-fill-an-avframe-structure-in-order-to-encode-an-yuy2-video-or-uyvy-into[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия