簡體   English   中英

將原始Genicam H.264數據讀取到avlib

[英]Read raw Genicam H.264 data to avlib

我嘗試熟悉libav,以便從支持GenICam的相機處理原始H.264流。 我希望通過GenICam提供的接口(API)接收原始數據,然后將這些數據轉發到libav中,以便生成一個容器文件,然后將其傳輸到像VLC這樣的播放設備或(稍后)傳輸給自己實現的顯示。

到目前為止,我使用了GenICam示例代碼,它將原始H.264數據轉換為“sample.h264”文件。 這個文件,我已經通過命令行工具ffmpeg,以生成一個mp4容器文件,我可以打開並在VLC中觀看

command: ffmpeg -i "sample.h264" -c:v copy -f mp4 "out.mp4"

目前,我通過挖掘每個H.264,ffmpeg,libav和視頻處理的示例和文檔。 我不得不承認,作為初學者,它讓我很困惑。 我正處於這樣的地步,我認為我找到了有助於我的事業的相應的libav功能:

我認為,基本上,我需要函數avcodec_send_packet()和avcodec_receive_packet()(因為不推薦使用avcodec_decode_video2())。 在此之前,我設置了一個avCodedContext結構並用H.264編解碼器(AV_CODEC_ID_H264)打開(或組合?!?)。

到目前為止,我的代碼看起來像這樣(省略錯誤檢查和其他東西):

...
AVCodecContext* avCodecContext = nullptr;
AVCodec *avCodec = nullptr;
AVPacket *avPacket = av_packet_alloc();
AVFrame *avFrame = nullptr;
...
avCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
avCodecContext = avcodec_alloc_context3(avCodec);
avcodec_open2 ( avCodecContext, avCodec, NULL );
av_init_packet(avPacket);
...

while(receivingRawDataFromCamera)
{
  ...
  // receive raw data via GenICam
  DSGetBufferInfo<void*>(hDS, sBuffer.BufferHandle, BUFFER_INFO_BASE, NULL, pPtr)

  // libav action
  avPacket->data =static_cast<uint8_t*>(pPtr);  
  avErr = avcodec_send_packet(avCodecContext, avPacket);
  avFrame = av_frame_alloc();
  avErr = avcodec_receive_frame( avCodecContext, avFrame);

  // pack frame in container? (not implemented yet)
  ..
}

上面代碼的結果是,對send_packet()和receive_frame()的調用都返回錯誤代碼(-22和-11),我無法通過av_strerror()解密(它只是說,這些都是錯誤代碼22和11)。

編輯:可能作為一個額外的信息,誰想知道是否

avPacket->data = static_cast<uint8_t*>(pPtr);

是一個有效的操作......在第一次調用此操作后,avPacket-> data的內容是

{0x0, 0x0, 0x0, 0x1, 0x67, 0x64, 0x0, 0x28, 0xad, 0x84, 0x5,
  0x45, 0x62, 0xb8, 0xac, 0x54, 0x74, 0x20, 0x2a, 0x2b, 0x15, 0xc5,
  0x62}

由於NAL標記和數字在一開始,某種程度上看起來像預期的東西? 我不知道,因為我真的是一個初學者....

現在的問題是,我是在正確的道路上嗎? 缺少什么,代碼22和11是什么意思?

接下來的問題是,為了獲得一個我可以流式傳輸(實時)給玩家的容器,該怎么辦呢?

邁克,提前謝謝

至少對於最初提出的問題,我找到了自己的解決方案:

為了擺脫調用函數的錯誤

avcodec_send_packet(avCodecContext, avPacket);
...
avcodec_receive_frame( avCodecContext, avFrame);

我不得不手動填充'avCodecContext'和'avPacket'的一些參數:

avCodecContext->bit_rate = 8000000;
avCodecContext->width = 1920;
avCodecContext->height = 1080;
avCodecContext->time_base.num = 1;
avCodecContext->time_base.den = 25;
...
avPacket->data = static_cast<uint8_t*>(pPtr);
avPacket->size = datasize;
avPacket->pts = frameid;

而'datasize'和'frameid'是通過GenICam接收的,可能不是這些字段的適當參數,但至少我不會再出現任何錯誤。

由於這回答了我關於如何將原始數據導入libav結構的初步問題,我認為,問題得到了回答。

在Comcomst部分與Vencat的討論和建議引發了我的其他問題,但我想這應該在一個新問題中討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM