libav c++ raw h264 TCP Stream to opencv Mat
up vote
1
down vote
favorite
I writting a software for my classes that receive a h264 stream from a drone and i need to convert the video stream to opencv Mat.
I have no trouble to receive the frame and if i save it to a .264 file i can read the output with VLC.
The drone is sending IDR-Frame and P-Frame , since i don't need to see the video stream juste some frame of it, i was thinking of only using the IDR-Frame to get the image but i have trouble to understand how to use libavcodec from FFMPEG, how can i create a AVFrame from my IDR-Frame and how to convert it to cv::Mat after.
i have try the following code, i have store the full frame in .raw file and i try to decode them , but i get read error when i try to parse the packet to a frame, i don't thing a initialize the buffer of ARPacket the right way :
AVFormatContext* fc = 0;
int vi = -1; // vi veut dire video index
inline cv::Mat avframe_to_mat(const AVFrame* avframe)
{
AVFrame dst;
cv::Mat m;
memset(&dst, 0, sizeof(dst));
int w = avframe->width, h = avframe->height;
m = cv::Mat(h, w, CV_8UC3);
dst.data[0] = (uint8_t*)m.data;
avpicture_fill((AVPicture*)&dst, dst.data[0], AV_PIX_FMT_BGR24, w, h);
struct SwsContext *convert_ctx = NULL;
enum AVPixelFormat src_pixfmt = AV_PIX_FMT_BGR24;
enum AVPixelFormat dst_pixfmt = AV_PIX_FMT_BGR24;
convert_ctx = sws_getContext(w, h, src_pixfmt, w, h, dst_pixfmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(convert_ctx, avframe->data, avframe->linesize, 0, h, dst.data, dst.linesize);
sws_freeContext(convert_ctx);
return m;
}
inline bool init_stream(unsigned char* data, int len)
{
const char* file = "test.avi";
const AVCodecID codec_id = AV_CODEC_ID_H264;
AVCodec* codec = avcodec_find_encoder(codec_id);
// Crée le container pour le stream
fc = avformat_alloc_context();
/*
AVOutputFormat *of = av_guess_format(0, file, 0);
fc = avformat_alloc_context();
fc->oformat = of;
strcpy(fc->filename, file);
*/
int br = 1000000;
int w = 640;
int h = 360;
int fps = 24;
// ajoute un stream video
AVStream* pst = avformat_new_stream(fc, codec); // Pourquoi je passe pas le codec ici ?
vi = pst->index;
codec_context = avcodec_alloc_context3(codec);
codec_context->bit_rate = br;
codec_context->width = w;
codec_context->height = h;
codec_context->time_base = {1,fps};
codec_context->gop_size = 10; // Emit one intra frame every ten frames
codec_context->max_b_frames = 1;
codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
// Vu quon n'est en h264
av_opt_set(codec_context->priv_data, "preset", "slow", 0);
// Ouvre notre codec
if(avcodec_open2(codec_context, codec,nullptr) < 0)
{
cerr << "Impossible d'ouvrir le codec" << endl;
return false;
}
if (!(fc->oformat->flags & AVFMT_NOFILE))
avio_open(&fc->pb, fc->filename,0);
// avformat_write_header(fc,nullptr);
return true;
}
inline void append_stream(uint8_t* data, int len)
{
if( 0 > vi)
{
cerr << "video index is less than 0" << endl;
return;
}
AVStream* pst = fc->streams[vi];
AVPacket pkt;
// Init un nouveau packet
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.data = data;
pkt.stream_index = pst->index;
pkt.size = len;
pkt.dts = AV_NOPTS_VALUE;
pkt.pts = AV_NOPTS_VALUE;
// ERROR accessing location
av_interleaved_write_frame(fc, &pkt);
}
inline void execute_staging_test(const fs::path& folder, int nbr_trame)
{
fs::path file_name = folder / "stream.bin";
if(!fs::exists(file_name))
{
cerr << "The file " << file_name.string() << " does not exists" << endl;
return;
}
avcodec_register_all();
av_log_set_level(AV_LOG_DEBUG);
int length = 0;
char* buffer;
for(int i = 0; i < nbr_trame;i++)
{
fs::path file = std::to_string(i) + ".raw";
file = folder / file;
cout << "Got frame on " << file.string() << endl;
ifstream ifs(file, ofstream::binary);
// Get la longeur du fichier pour savoir le buffer a prendre
ifs.seekg(0, ios::end);
length = ifs.tellg();
ifs.seekg(0, ios::beg);
if (length == 0) {
std::cerr << "No data in file " << file << std::endl;
return;
}
buffer = new char[length];
std::cout << "File " << file << " length is " << length << std::endl;
ifs.read(buffer, length);
cv::VideoWriter vw;
int codec = cv::VideoWriter::fourcc('X', '2', '6', '4');
if(!fc)
{
if(!init_stream((unsigned char*)buffer, length))
{
return;
}
}
if(fc)
{
append_stream((unsigned char*)buffer, length);
}
}
}
Thanks you very mutch if you can help me , i'm a novice in c++ and i have never deal with video stream. If you want to see the full code its host on github repo to this project
c++ opencv libavcodec libav
add a comment |
up vote
1
down vote
favorite
I writting a software for my classes that receive a h264 stream from a drone and i need to convert the video stream to opencv Mat.
I have no trouble to receive the frame and if i save it to a .264 file i can read the output with VLC.
The drone is sending IDR-Frame and P-Frame , since i don't need to see the video stream juste some frame of it, i was thinking of only using the IDR-Frame to get the image but i have trouble to understand how to use libavcodec from FFMPEG, how can i create a AVFrame from my IDR-Frame and how to convert it to cv::Mat after.
i have try the following code, i have store the full frame in .raw file and i try to decode them , but i get read error when i try to parse the packet to a frame, i don't thing a initialize the buffer of ARPacket the right way :
AVFormatContext* fc = 0;
int vi = -1; // vi veut dire video index
inline cv::Mat avframe_to_mat(const AVFrame* avframe)
{
AVFrame dst;
cv::Mat m;
memset(&dst, 0, sizeof(dst));
int w = avframe->width, h = avframe->height;
m = cv::Mat(h, w, CV_8UC3);
dst.data[0] = (uint8_t*)m.data;
avpicture_fill((AVPicture*)&dst, dst.data[0], AV_PIX_FMT_BGR24, w, h);
struct SwsContext *convert_ctx = NULL;
enum AVPixelFormat src_pixfmt = AV_PIX_FMT_BGR24;
enum AVPixelFormat dst_pixfmt = AV_PIX_FMT_BGR24;
convert_ctx = sws_getContext(w, h, src_pixfmt, w, h, dst_pixfmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(convert_ctx, avframe->data, avframe->linesize, 0, h, dst.data, dst.linesize);
sws_freeContext(convert_ctx);
return m;
}
inline bool init_stream(unsigned char* data, int len)
{
const char* file = "test.avi";
const AVCodecID codec_id = AV_CODEC_ID_H264;
AVCodec* codec = avcodec_find_encoder(codec_id);
// Crée le container pour le stream
fc = avformat_alloc_context();
/*
AVOutputFormat *of = av_guess_format(0, file, 0);
fc = avformat_alloc_context();
fc->oformat = of;
strcpy(fc->filename, file);
*/
int br = 1000000;
int w = 640;
int h = 360;
int fps = 24;
// ajoute un stream video
AVStream* pst = avformat_new_stream(fc, codec); // Pourquoi je passe pas le codec ici ?
vi = pst->index;
codec_context = avcodec_alloc_context3(codec);
codec_context->bit_rate = br;
codec_context->width = w;
codec_context->height = h;
codec_context->time_base = {1,fps};
codec_context->gop_size = 10; // Emit one intra frame every ten frames
codec_context->max_b_frames = 1;
codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
// Vu quon n'est en h264
av_opt_set(codec_context->priv_data, "preset", "slow", 0);
// Ouvre notre codec
if(avcodec_open2(codec_context, codec,nullptr) < 0)
{
cerr << "Impossible d'ouvrir le codec" << endl;
return false;
}
if (!(fc->oformat->flags & AVFMT_NOFILE))
avio_open(&fc->pb, fc->filename,0);
// avformat_write_header(fc,nullptr);
return true;
}
inline void append_stream(uint8_t* data, int len)
{
if( 0 > vi)
{
cerr << "video index is less than 0" << endl;
return;
}
AVStream* pst = fc->streams[vi];
AVPacket pkt;
// Init un nouveau packet
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.data = data;
pkt.stream_index = pst->index;
pkt.size = len;
pkt.dts = AV_NOPTS_VALUE;
pkt.pts = AV_NOPTS_VALUE;
// ERROR accessing location
av_interleaved_write_frame(fc, &pkt);
}
inline void execute_staging_test(const fs::path& folder, int nbr_trame)
{
fs::path file_name = folder / "stream.bin";
if(!fs::exists(file_name))
{
cerr << "The file " << file_name.string() << " does not exists" << endl;
return;
}
avcodec_register_all();
av_log_set_level(AV_LOG_DEBUG);
int length = 0;
char* buffer;
for(int i = 0; i < nbr_trame;i++)
{
fs::path file = std::to_string(i) + ".raw";
file = folder / file;
cout << "Got frame on " << file.string() << endl;
ifstream ifs(file, ofstream::binary);
// Get la longeur du fichier pour savoir le buffer a prendre
ifs.seekg(0, ios::end);
length = ifs.tellg();
ifs.seekg(0, ios::beg);
if (length == 0) {
std::cerr << "No data in file " << file << std::endl;
return;
}
buffer = new char[length];
std::cout << "File " << file << " length is " << length << std::endl;
ifs.read(buffer, length);
cv::VideoWriter vw;
int codec = cv::VideoWriter::fourcc('X', '2', '6', '4');
if(!fc)
{
if(!init_stream((unsigned char*)buffer, length))
{
return;
}
}
if(fc)
{
append_stream((unsigned char*)buffer, length);
}
}
}
Thanks you very mutch if you can help me , i'm a novice in c++ and i have never deal with video stream. If you want to see the full code its host on github repo to this project
c++ opencv libavcodec libav
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I writting a software for my classes that receive a h264 stream from a drone and i need to convert the video stream to opencv Mat.
I have no trouble to receive the frame and if i save it to a .264 file i can read the output with VLC.
The drone is sending IDR-Frame and P-Frame , since i don't need to see the video stream juste some frame of it, i was thinking of only using the IDR-Frame to get the image but i have trouble to understand how to use libavcodec from FFMPEG, how can i create a AVFrame from my IDR-Frame and how to convert it to cv::Mat after.
i have try the following code, i have store the full frame in .raw file and i try to decode them , but i get read error when i try to parse the packet to a frame, i don't thing a initialize the buffer of ARPacket the right way :
AVFormatContext* fc = 0;
int vi = -1; // vi veut dire video index
inline cv::Mat avframe_to_mat(const AVFrame* avframe)
{
AVFrame dst;
cv::Mat m;
memset(&dst, 0, sizeof(dst));
int w = avframe->width, h = avframe->height;
m = cv::Mat(h, w, CV_8UC3);
dst.data[0] = (uint8_t*)m.data;
avpicture_fill((AVPicture*)&dst, dst.data[0], AV_PIX_FMT_BGR24, w, h);
struct SwsContext *convert_ctx = NULL;
enum AVPixelFormat src_pixfmt = AV_PIX_FMT_BGR24;
enum AVPixelFormat dst_pixfmt = AV_PIX_FMT_BGR24;
convert_ctx = sws_getContext(w, h, src_pixfmt, w, h, dst_pixfmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(convert_ctx, avframe->data, avframe->linesize, 0, h, dst.data, dst.linesize);
sws_freeContext(convert_ctx);
return m;
}
inline bool init_stream(unsigned char* data, int len)
{
const char* file = "test.avi";
const AVCodecID codec_id = AV_CODEC_ID_H264;
AVCodec* codec = avcodec_find_encoder(codec_id);
// Crée le container pour le stream
fc = avformat_alloc_context();
/*
AVOutputFormat *of = av_guess_format(0, file, 0);
fc = avformat_alloc_context();
fc->oformat = of;
strcpy(fc->filename, file);
*/
int br = 1000000;
int w = 640;
int h = 360;
int fps = 24;
// ajoute un stream video
AVStream* pst = avformat_new_stream(fc, codec); // Pourquoi je passe pas le codec ici ?
vi = pst->index;
codec_context = avcodec_alloc_context3(codec);
codec_context->bit_rate = br;
codec_context->width = w;
codec_context->height = h;
codec_context->time_base = {1,fps};
codec_context->gop_size = 10; // Emit one intra frame every ten frames
codec_context->max_b_frames = 1;
codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
// Vu quon n'est en h264
av_opt_set(codec_context->priv_data, "preset", "slow", 0);
// Ouvre notre codec
if(avcodec_open2(codec_context, codec,nullptr) < 0)
{
cerr << "Impossible d'ouvrir le codec" << endl;
return false;
}
if (!(fc->oformat->flags & AVFMT_NOFILE))
avio_open(&fc->pb, fc->filename,0);
// avformat_write_header(fc,nullptr);
return true;
}
inline void append_stream(uint8_t* data, int len)
{
if( 0 > vi)
{
cerr << "video index is less than 0" << endl;
return;
}
AVStream* pst = fc->streams[vi];
AVPacket pkt;
// Init un nouveau packet
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.data = data;
pkt.stream_index = pst->index;
pkt.size = len;
pkt.dts = AV_NOPTS_VALUE;
pkt.pts = AV_NOPTS_VALUE;
// ERROR accessing location
av_interleaved_write_frame(fc, &pkt);
}
inline void execute_staging_test(const fs::path& folder, int nbr_trame)
{
fs::path file_name = folder / "stream.bin";
if(!fs::exists(file_name))
{
cerr << "The file " << file_name.string() << " does not exists" << endl;
return;
}
avcodec_register_all();
av_log_set_level(AV_LOG_DEBUG);
int length = 0;
char* buffer;
for(int i = 0; i < nbr_trame;i++)
{
fs::path file = std::to_string(i) + ".raw";
file = folder / file;
cout << "Got frame on " << file.string() << endl;
ifstream ifs(file, ofstream::binary);
// Get la longeur du fichier pour savoir le buffer a prendre
ifs.seekg(0, ios::end);
length = ifs.tellg();
ifs.seekg(0, ios::beg);
if (length == 0) {
std::cerr << "No data in file " << file << std::endl;
return;
}
buffer = new char[length];
std::cout << "File " << file << " length is " << length << std::endl;
ifs.read(buffer, length);
cv::VideoWriter vw;
int codec = cv::VideoWriter::fourcc('X', '2', '6', '4');
if(!fc)
{
if(!init_stream((unsigned char*)buffer, length))
{
return;
}
}
if(fc)
{
append_stream((unsigned char*)buffer, length);
}
}
}
Thanks you very mutch if you can help me , i'm a novice in c++ and i have never deal with video stream. If you want to see the full code its host on github repo to this project
c++ opencv libavcodec libav
I writting a software for my classes that receive a h264 stream from a drone and i need to convert the video stream to opencv Mat.
I have no trouble to receive the frame and if i save it to a .264 file i can read the output with VLC.
The drone is sending IDR-Frame and P-Frame , since i don't need to see the video stream juste some frame of it, i was thinking of only using the IDR-Frame to get the image but i have trouble to understand how to use libavcodec from FFMPEG, how can i create a AVFrame from my IDR-Frame and how to convert it to cv::Mat after.
i have try the following code, i have store the full frame in .raw file and i try to decode them , but i get read error when i try to parse the packet to a frame, i don't thing a initialize the buffer of ARPacket the right way :
AVFormatContext* fc = 0;
int vi = -1; // vi veut dire video index
inline cv::Mat avframe_to_mat(const AVFrame* avframe)
{
AVFrame dst;
cv::Mat m;
memset(&dst, 0, sizeof(dst));
int w = avframe->width, h = avframe->height;
m = cv::Mat(h, w, CV_8UC3);
dst.data[0] = (uint8_t*)m.data;
avpicture_fill((AVPicture*)&dst, dst.data[0], AV_PIX_FMT_BGR24, w, h);
struct SwsContext *convert_ctx = NULL;
enum AVPixelFormat src_pixfmt = AV_PIX_FMT_BGR24;
enum AVPixelFormat dst_pixfmt = AV_PIX_FMT_BGR24;
convert_ctx = sws_getContext(w, h, src_pixfmt, w, h, dst_pixfmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(convert_ctx, avframe->data, avframe->linesize, 0, h, dst.data, dst.linesize);
sws_freeContext(convert_ctx);
return m;
}
inline bool init_stream(unsigned char* data, int len)
{
const char* file = "test.avi";
const AVCodecID codec_id = AV_CODEC_ID_H264;
AVCodec* codec = avcodec_find_encoder(codec_id);
// Crée le container pour le stream
fc = avformat_alloc_context();
/*
AVOutputFormat *of = av_guess_format(0, file, 0);
fc = avformat_alloc_context();
fc->oformat = of;
strcpy(fc->filename, file);
*/
int br = 1000000;
int w = 640;
int h = 360;
int fps = 24;
// ajoute un stream video
AVStream* pst = avformat_new_stream(fc, codec); // Pourquoi je passe pas le codec ici ?
vi = pst->index;
codec_context = avcodec_alloc_context3(codec);
codec_context->bit_rate = br;
codec_context->width = w;
codec_context->height = h;
codec_context->time_base = {1,fps};
codec_context->gop_size = 10; // Emit one intra frame every ten frames
codec_context->max_b_frames = 1;
codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
// Vu quon n'est en h264
av_opt_set(codec_context->priv_data, "preset", "slow", 0);
// Ouvre notre codec
if(avcodec_open2(codec_context, codec,nullptr) < 0)
{
cerr << "Impossible d'ouvrir le codec" << endl;
return false;
}
if (!(fc->oformat->flags & AVFMT_NOFILE))
avio_open(&fc->pb, fc->filename,0);
// avformat_write_header(fc,nullptr);
return true;
}
inline void append_stream(uint8_t* data, int len)
{
if( 0 > vi)
{
cerr << "video index is less than 0" << endl;
return;
}
AVStream* pst = fc->streams[vi];
AVPacket pkt;
// Init un nouveau packet
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.data = data;
pkt.stream_index = pst->index;
pkt.size = len;
pkt.dts = AV_NOPTS_VALUE;
pkt.pts = AV_NOPTS_VALUE;
// ERROR accessing location
av_interleaved_write_frame(fc, &pkt);
}
inline void execute_staging_test(const fs::path& folder, int nbr_trame)
{
fs::path file_name = folder / "stream.bin";
if(!fs::exists(file_name))
{
cerr << "The file " << file_name.string() << " does not exists" << endl;
return;
}
avcodec_register_all();
av_log_set_level(AV_LOG_DEBUG);
int length = 0;
char* buffer;
for(int i = 0; i < nbr_trame;i++)
{
fs::path file = std::to_string(i) + ".raw";
file = folder / file;
cout << "Got frame on " << file.string() << endl;
ifstream ifs(file, ofstream::binary);
// Get la longeur du fichier pour savoir le buffer a prendre
ifs.seekg(0, ios::end);
length = ifs.tellg();
ifs.seekg(0, ios::beg);
if (length == 0) {
std::cerr << "No data in file " << file << std::endl;
return;
}
buffer = new char[length];
std::cout << "File " << file << " length is " << length << std::endl;
ifs.read(buffer, length);
cv::VideoWriter vw;
int codec = cv::VideoWriter::fourcc('X', '2', '6', '4');
if(!fc)
{
if(!init_stream((unsigned char*)buffer, length))
{
return;
}
}
if(fc)
{
append_stream((unsigned char*)buffer, length);
}
}
}
Thanks you very mutch if you can help me , i'm a novice in c++ and i have never deal with video stream. If you want to see the full code its host on github repo to this project
c++ opencv libavcodec libav
c++ opencv libavcodec libav
asked Nov 10 at 18:16
William Quintal
61
61
add a comment |
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242005%2flibav-c-raw-h264-tcp-stream-to-opencv-mat%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown