Чтение необработанных данных Genicam H.264 в avlib - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь ознакомиться с libav для обработки необработанного потока H.264 с камеры, поддерживающей GenICam. Я хотел бы получить необработанные данные через предоставленные 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?

Следующий вопрос: что делать потом, чтобы получить контейнер, который я могу транслировать (в реальном времени) игроку?

Заранее спасибо, Maik

1 Ответ

0 голосов
/ 18 апреля 2019

По крайней мере, для изначально заданного вопроса я нашел решение для себя:

Чтобы избавиться от ошибок при вызове функций

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, я думаю, что на этот вопрос дан ответ.

Обсуждение и предложения с / из Vencat в комментирующем разделе приводят к дополнительным вопросам, которые у меня есть, но я думаю, что их следует обсудить в новом вопросе.

...