Я искал и почти ничего не нашел, поэтому буду очень признателен за помощь в моем вопросе.
Я пишу исходный фильтр DirectShow, который использует libav для чтения и отправки нисходящих пакетов h264 из FLV-файла youtube. Но я не могу найти соответствующие поля структуры libav для правильной реализации фильтров GetMediType () и FillBuffer (). Некоторые поля libav имеют значение null. В результате происходит сбой декодера h264 при попытке обработать полученные данные.
Где я не прав? В работе с libav или с интерфейсами DirectShow? Может быть, h264 требует дополнительной обработки при работе с libav или я неправильно заполняю эталонное время? Есть ли у кого-нибудь ссылки, полезные для написания фильтра исходного кода DirectShow h264 с помощью libav?
Часть GetMediaType ():
VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*) toMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
pvi->AvgTimePerFrame = UNITS_PER_SECOND / m_pFormatContext->streams[m_streamNo]->codec->sample_rate; //sample_rate is 0
pvi->dwBitRate = m_pFormatContext->bit_rate;
pvi->rcSource = videoRect;
pvi->rcTarget = videoRect;
//Bitmap
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = videoRect.right;
pvi->bmiHeader.biHeight = videoRect.bottom;
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biBitCount = m_pFormatContext->streams[m_streamNo]->codec->bits_per_raw_sample;//or should here be bits_per_coded_sample
pvi->bmiHeader.biCompression = FOURCC_H264;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
Часть FillBuffer ():
//Get buffer pointer
BYTE* pBuffer = NULL;
if (pSamp->GetPointer(&pBuffer) < 0)
return S_FALSE;
//Get next packet
AVPacket* pPacket = m_mediaFile.getNextPacket();
if (pPacket->data == NULL)
return S_FALSE;
//Check packet and buffer size
if (pSamp->GetSize() < pPacket->size)
return S_FALSE;
//Copy from packet to sample buffer
memcpy(pBuffer, pPacket->data, pPacket->size);
//Set media sample time
REFERENCE_TIME start = m_mediaFile.timeStampToReferenceTime(pPacket->pts);
REFERENCE_TIME duration = m_mediaFile.timeStampToReferenceTime(pPacket->duration);
REFERENCE_TIME end = start + duration;
pSamp->SetTime(&start, &end);
pSamp->SetMediaTime(&start, &end);
P.S. Я отладил свой фильтр с помощью декодера hax264, и он вылетал при вызове устаревшей функции libav img_convert ().