【问题标题】:Blurry picture when decoding h264 mpegts udp stream with ffmpeg使用ffmpeg解码h264 mpegts udp流时图片模糊
【发布时间】:2019-05-14 12:09:23
【问题描述】:

我使用 ffmpeg 确实读取了一个 udp 流(仅包含视频)并解码帧,然后我想再次编码,但在解码或从解复用过程中我得到模糊的图片图片尤其是下部。


我有一个视频播放器,它也使用 ffmpeg 完美显示视频,我尝试查看该代码,但我没有看到任何差异。
在日志中,我看到了类似的东西

NAL 单元 8 无效,正在跳过。 nal_unit_type:1(非IDR图片的编码切片),nal_ref_idc:3 NAL 单元 7 无效,正在跳过。 字节流重读 td 解码 MB 109 49,字节流 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();

}

【问题讨论】:

    标签: ffmpeg h.264


    【解决方案1】:

    经过大量调试,我发现了问题所在。问题是 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);
    
      ... 
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-26
      • 2020-10-06
      • 2016-04-09
      • 2018-09-17
      • 2011-08-21
      • 2011-11-24
      • 2016-05-22
      • 2015-08-24
      • 2017-05-07
      相关资源
      最近更新 更多