Я пытаюсь ознакомиться с 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