3

検索してもほとんど何も見つかりませんでしたので、質問にご協力いただければ幸いです。

私は、libavを使用してYouTubeのFLVファイルからダウンストリームh264パケットを読み取って送信するDirectShowソースフィルターを作成しています。しかし、フィルターのGetMediType()とFillBuffer()を正しく実装するための適切なlibav構造体のフィールドが見つかりません。一部のlibavフィールドはnullです。その結果、受信したデータを処理しようとしてh264デコーダーがクラッシュします。

私はどこが間違っていますか?libavまたはDirectShowインターフェイスを使用していますか?たぶん、h264はlibavで作業するときに追加の処理が必要ですか、それとも参照時間を間違って入力しますか?誰かがlibavでDirectShowh264ソースフィルターを書くのに役立つリンクを持っていますか?

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);

PS hax264デコーダーを使用してフィルターをデバッグしましたが、libavの非推奨関数img_convert()を呼び出すとクラッシュします。

4

2 に答える 2

2

正しいH.264メディアタイプを作成するために必要なMSDNリンクは次のとおりです。H.264ビデオタイプ

于 2011-09-07T15:16:41.663 に答える
1

適切なフィールドに適切な値を入力する必要があります。

にはAM_MEDIA_TYPE、h264に適したMEDIASUBTYPEが含まれている必要があります。

そして、これらは明らかに間違っています:

pvi-> bmiHeader.biWidth = videoRect.right;

pvi-> bmiHeader.biHeight = videoRect.bottom;

rcSource / rcTargetに依存しない幅/高さを使用する必要があります。これは、それらがインジケーターであるためです。他のフィルターから取得する場合は、完全にゼロになる可能性があります。

pvi->bmiHeader.biBitCount = m_pFormatContext->streams[m_streamNo]->codec->bits_per_raw_sample;//or should here be bits_per_coded_sample

これbiWidth*biHeight*biBitCount/8は、がサンプルの実際のサイズである場合にのみ意味があります。そうは思わない ...

pvi->bmiHeader.biCompression = FOURCC_H264;

これは、サブタイプパラメータのAM_MEDIA_TYPEでも渡す必要があります。

pvi-> bmiHeader.biSizeImage = GetBitmapSize(&pvi-> bmiHeader);

これは失敗します。これは、fourccが関数に認識されておらず、フルフレームではないため、このサンプルのビット数が明らかに間違っているためです。

データストリームがダウンストリームh264フィルターによってどのように処理されるかを確認する必要があります。これには欠陥があるようです。

于 2011-08-15T15:34:13.480 に答える