Декодирование потока H264 завершается ошибкой

После многих недель попыток подключиться к моей домашней системе видеонаблюдения в моем проекте c ++ / Qt с использованием libav на моем raspberry pi (armv7) я могу корректно отображать свою камеру в течение некоторого времени (по крайней мере, 20 минут), почти не имея предупреждений NAL в консоль (но некоторые предупреждения о недопустимом блоке NAL). Однако, в конце концов, я просто начну видеть только серый экран и множество предупреждений NAL на консоли, и мне придется закрыть и снова открыть соединение, чтобы моя камера отображалась правильно. Я много раз искал в интернете, чтобы убедиться, что я правильно понимаю av_parser_parse2 и думаю, что да.

Я вставил ниже три свои основные функции в надежде, что кто-нибудь мне скажет — есть ли еще что-то для декодирования потока h264 с использованием libav, чем я сейчас понимаю?

Спасибо.

void MainWindow::playStreamToScreen(MainWindow* app)
{

avcodec_register_all();

codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) {
qDebug() << "codec not found\n";
return;
}

c = avcodec_alloc_context3(codec);
/* if(codec->capabilities & CODEC_CAP_TRUNCATED)
c->flags |= CODEC_FLAG_TRUNCATED;
if(codec->capabilities & CODEC_FLAG2_CHUNKS)
c->flags |= CODEC_FLAG2_CHUNKS;*//* We may send incomplete frames */
picture = av_frame_alloc();
pFrameRGB=av_frame_alloc();
int  numBytes=avpicture_get_size(pix_fmt_dst, myWidth, myHeight);
buffer= (uint8_t*)malloc(numBytes);
if(avpicture_fill((AVPicture *)pFrameRGB, buffer, pix_fmt_dst,
myWidth, myHeight) < 0)
{
qDebug() << "failed fill picture";
}
if (avcodec_open2(c, codec, NULL) < 0) {
qDebug() << "could not open codec\n";
return;
}

frame = 0;

if(parser == NULL)parser = av_parser_init(AV_CODEC_ID_H264);
if(parser == NULL)
{
qDebug() << "after init parser is null";
return;
}
parser->flags |= PARSER_FLAG_ONCE;

struct timeval t;
float inv_fps2;// = 4;
int ii = 0;
inv_fps2 = 1e6/9.98;//av_q2d(c->time_base);
qDebug() << "before timebase";
c->time_base = (AVRational){1,10};
c->bit_rate =  251000;
c->width = 352;
c->height = 288;
c->pix_fmt = AV_PIX_FMT_YUV420P;

if(img_convert_ctx == NULL)
{

img_convert_ctx = sws_getCachedContext ( img_convert_ctx, c->width, c->height,
AV_PIX_FMT_YUV420P, myWidth, myHeight,  AV_PIX_FMT_RGB555,
SWS_LANCZOS | SWS_ACCURATE_RND , NULL, NULL, NULL );
}

running = true;
int retval;
gettimeofday(&t, 0);}void MainWindow::display_frame(AVCodecContext* cc, AVFrame *frame, SwsContext* img_convert_ctx, MainWindow* app)
{

sws_scale ( img_convert_ctx, frame->data, frame->linesize, 0,
288, pFrameRGB->data, pFrameRGB->linesize );

app->currentImage = QImage(pFrameRGB->data[0], app->myWidth, app->myHeight, pFrameRGB->linesize[0], QImage::Format_RGB555) .copy();// - See more at: http://www.mzan.com/article/30784549-best-simplest-way-to-display-ffmpeg-frames-in-qt5-solved.shtml#sthash.RvAFLQsc.dpuf
QImage img2 = app->currentImage.scaled(app->width(), app->height(), Qt::KeepAspectRatio);
QMetaObject::invokeMethod(app->myLabel, "setImage", Qt::QueuedConnection, Q_ARG(QImage, img2));
app->myLabel->setFixedSize(app->width(), app->height());}void MainWindow::socketReadyRead()
{
if(connectingToLive && i  == 0)
{
qDebug() << "starting live stream";
i++;
this->playStreamToScreen(this);

}
else if(connectingToLive && i > 0)
{
QByteArray temp;
int inbuf_start = 0;
int inbuf_len = 0;

temp.append(socket->readAll());//reads from network hereinbuf_len = temp.size();
inbuf_start = 0;

int out_size;

while (inbuf_len)
{
av_init_packet(&packet2);
packet2.data = 0;
packet2.size = 0;
len = av_parser_parse2(parser, c, &packet2.data, &packet2.size,
(uint8_t*)temp.constData()+ inbuf_start, inbuf_len,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);

inbuf_start += len;
inbuf_len -= len;

if(packet2.size == 0 && len >= 0)
{break;

}

else if(len)
{

retval = avcodec_decode_video2(c, picture, &got_picture, &packet2);

if (got_picture && retval > 0)
{
display_frame(c, picture, img_convert_ctx, this);

}

}

}}

}

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]