Размытая картинка при декодировании h264 mpegts udp stream с помощью ffmpeg - PullRequest
0 голосов
/ 14 мая 2019

Я использую ffmpeg для чтения потока udp (содержит только видео) и для декодирования кадров, затем мне нравится снова кодировать, но во время декодирования или демультиплексирования я получаю размытые картинки, особенно нижнюю часть.


У меня есть видеоплеер, который также использует ffmpeg, который отлично отображает видео, и я пытаюсь посмотреть в этом коде, но я не вижу различий.
В журнале я вижу такие вещи, как

Invalid NAL unit 8, skipping.

nal_unit_type: 1(Coded slice of a non-IDR picture), nal_ref_idc: 3
Invalid NAL unit 7, skipping.
bytestream overread td
error while decoding MB 109 49, bytestream td

Основные вещи в коде выглядят так:

av_register_all();

AVFormatContext *fmt_ctx = 0;

AVDictionary *options = 0;
av_dict_set(&options, "analyzeduration", "500000", NULL);
av_dict_set(&options, "probesize", "500000", NULL);
char* url = "udp://239.0.0.3:8081";
avformat_open_input(&fmt_ctx, url, 0, &options);

avformat_find_stream_info(fmt_ctx, &options);

int nRet = 0;
av_dump_format(fmt_ctx, 0, url, 0);
AVStream *pStream = fmt_ctx->streams[0];
AVCodecID nCodecid = pStream->codec->codec_id;
AVCodec* pCodec = avcodec_find_decoder(nCodecid);
AVCodecContext* pCodecCtx = pStream->codec;

nRet = avcodec_open2(pCodecCtx, pCodec, NULL);
int nInH = pStream->codec->height;
int nInW = pStream->codec->width;
int nOutW = nInW / 4;
int nOutH = nInH / 4;

SwsContext* pSwsCtx = sws_getContext(nInW, nInH, AV_PIX_FMT_YUV420P,
                                     nOutW, nOutH, AV_PIX_FMT_RGB24,
                                     SWS_BICUBIC, NULL, NULL, NULL);


m_pFilmWdg->m_img = QImage(nOutW, nOutH, QImage::Format_RGB888);
int linesizes[4];
av_image_fill_linesizes(linesizes, AV_PIX_FMT_RGB24, nOutW);


for (;;)
{
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;
    nRet = av_read_frame(fmt_ctx, &pkt);

    nRet = avcodec_send_packet(pCodecCtx, &pkt);

    AVFrame*  picture = av_frame_alloc();

    nRet = avcodec_receive_frame(pCodecCtx, picture);

    if (AVERROR(EAGAIN) == nRet)
        continue;

    uint8_t* p[] = { m_pFilmWdg->m_img.bits() };



    nRet = sws_scale(pSwsCtx, picture->data, picture->linesize, 0, nInH, p, linesizes);

    av_packet_unref(&pkt);
    av_frame_free(&picture);
    m_pFilmWdg->update();

}

1 Ответ

0 голосов
/ 10 июня 2019

Я обнаружил проблему после большой отладки. Проблема заключалась в том, что пакеты udp были потеряны или повреждены во время декодирования. Я разделил петлю на две части в разных темах. Один DemuxLoop и один DecodeLoop что-то вроде

void VideoDecode::DemuxLoop()
{
   ..
    int nRet = av_read_frame(fmt_ctx, &pkt);
    put in queue

}


void VideoDecode::DecodeLoop()
{
  ...
   pick from queue
   int nRet = avcodec_send_packet(pCodecCtx, &pkt);

   AVFrame*  picture = av_frame_alloc();

   nRet = avcodec_receive_frame(pCodecCtx, picture);

  ... 
}
...