gpt4 book ai didi

c++ - ffmpeg 流解码 - 不使用 ffplay 时的人工制品

转载 作者:行者123 更新时间:2023-11-30 03:19:42 36 4
gpt4 key购买 nike

我使用 libx264 通过 RTP 流式传输视频捕获。现在,我只是流式传输到本地主机。为了观看流,我使用 ffmpeg 库。当我将 GOP 大小设置为大于 1(仅 I 帧)时,我在接收端得到了伪影 received image .奇怪的是,当我使用 ffplay 时,图像是完美的 like original .我做错了什么?

编码设置

output_codec_ctx->bit_rate = 5000000;
output_codec_ctx->width = 1920;
output_codec_ctx->height = 1080;
output_codec_ctx->time_base.den = 30; // frames per second
output_codec_ctx->time_base.num = 1;
output_codec_ctx->gop_size = 10; // gop size
output_codec_ctx->max_b_frames = 0; // B frames
output_codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; // output pixel format
output_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;

av_opt_set(output_codec_ctx->priv_data, "preset", "ultrafast", 0);
av_opt_set(output_codec_ctx->priv_data, "tune", "zerolatency", 0);

解码代码

AVFormatContext *pFormatCtx;
AVCodecContext *input_codec_ctx;
AVCode *pCodec;
avdevice_register_all(); // for device
avformat_network_init();
pFormatCtx = avformat_alloc_context();
input_codec_ctx = avcodec_alloc_context3(nullptr);
AVDictionary *options = nullptr;
av_dict_set(&options, "protocol_whitelist", "file,udp,rtp", 0);
av_dict_set(&options, "fflags", "nobuffer",0);

avformat_open_input(&pFormatCtx, "rtp://127.0.0.1:49990", nullptr, &options);

avformat_find_stream_info(pFormatCtx, nullptr);
for (uint i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = static_cast<int>(i);
break;
}

}

av_read_play(pFormatCtx); //play stream
pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);
AVCodecParameters *codec_param = pFormatCtx->streams[videoStream]->codecpar;
avcodec_parameters_to_context(input_codec_ctx, codec_param);
avcodec_open2(input_codec_ctx, pCodec, nullptr);

AVPacket packet;
AVPacket *pkt = &packet;
AVFrame *frame;
frame = av_frame_alloc();

av_init_packet(pkt);
pkt->data = nullptr; // packet data will be allocated by the encoder
pkt->size = 0;

while(true){
av_read_frame(pFormatCtx,pkt);
avcodec_send_packet(input_codec_ctx,pkt);
avcodec_receive_frame(input_codec_ctx,frame);
}

省略了初始化和其他内容。自定义解码的控制台输出:

NULL @ 0x1fb7b80] Opening 'stream.sdp' for reading
[sdp @ 0x1fb7b80] Format sdp probed with size=2048 and score=50
[sdp @ 0x1fb7b80] video codec set to: h264
[sdp @ 0x1fb7b80] RTP Packetization Mode: 1
[udp @ 0x1f34140] end receive buffer size reported is 131072
[udp @ 0x1fb8e40] end receive buffer size reported is 131072
[sdp @ 0x1fb7b80] setting jitter buffer size to 500

Success !
[sdp @ 0x1fb7b80] Before avformat_find_stream_info() pos: 181 bytes read:181 seeks:0 nb_streams:1
[AVBSFContext @ 0x1fa5880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[AVBSFContext @ 0x1fa5880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] Format yuv420p chosen by get_format().
[h264 @ 0x1fa51c0] Reinit context to 1920x1088, pix_fmt: yuv420p
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 57 packets
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] Invalid level prefix
[h264 @ 0x1fa51c0] error while decoding MB 2 36
[h264 @ 0x1fa51c0] concealing 3887 DC, 3887 AC, 3887 MV errors in I frame
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 155 packets
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] corrupted macroblock 32 41 (total_coeff=-1)
[h264 @ 0x1fa51c0] error while decoding MB 32 41
[h264 @ 0x1fa51c0] concealing 3257 DC, 3257 AC, 3257 MV errors in I frame
[h264 @ 0x1fa51c0] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1fa51c0] nal_unit_type: 5(IDR), nal_ref_idc: 3
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 52 packets
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 51 packets
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 10 packets
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 50 packets
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 52 packets
[sdp @ 0x1fb7b80] All info found
[sdp @ 0x1fb7b80] After avformat_find_stream_info() pos: 181 bytes read:181 seeks:0 frames:28
found video stream

The number of elements in stream is 1

[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] Format yuv420p chosen by get_format().
[h264 @ 0x1ee3880] Reinit context to 1920x1088, pix_fmt: yuv420p
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 256 packets
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] Invalid level prefix
[h264 @ 0x1ee3880] error while decoding MB 119 41
[h264 @ 0x1ee3880] concealing 3170 DC, 3170 AC, 3170 MV errors in I frame
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 5 packets
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 4 packets
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] out of range intra chroma pred mode
[h264 @ 0x1ee3880] error while decoding MB 100 56
[h264 @ 0x1ee3880] corrupted macroblock 84 65 (total_coeff=-1)
[h264 @ 0x1ee3880] error while decoding MB 84 65
[h264 @ 0x1ee3880] concealing 754 DC, 754 AC, 754 MV errors in I frame
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 160 packets
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] corrupted macroblock 17 36 (total_coeff=-1)
[h264 @ 0x1ee3880] error while decoding MB 17 36
[h264 @ 0x1ee3880] concealing 3872 DC, 3872 AC, 3872 MV errors in I frame
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[sdp @ 0x1fb7b80] max delay reached. need to consume packet
[sdp @ 0x1fb7b80] RTP: missed 53 packets
[h264 @ 0x1ee3880] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 8(PPS), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] nal_unit_type: 5(IDR), nal_ref_idc: 3
[h264 @ 0x1ee3880] corrupted macroblock 62 39 (total_coeff=-1)
[h264 @ 0x1ee3880] error while decoding MB 62 39
[h264 @ 0x1ee3880] concealing 3467 DC, 3467 AC, 3467 MV errors in I frame

最佳答案

最后我通过与 ffplay 相同的方式实现它解决了它:一个线程执行 av_read_frame() 并将接收到的数据包推送到数据包队列,第二个线程解码数据包。

不知道为什么它不能在一个线程中工作。

您可能会从以下片段中获得示例:

数据包接收者:

must_abort = false; // class member, externally set to true if abort requested
AVPacket packet;
AVPacket *pkt = &packet;
int ret;

while (must_abort == false){
ret = av_read_frame(pFormatCtx,pkt);
if (ret>=0 && !must_abort){
queue->putPacket(pkt);
}
else{
qDebug("no packet received");
}
QApplication::processEvents();
}

数据包队列:

class PacketQueue{
public:
void init(){
abort_request = false;
}
void putPacket(AVPacket *pkt) {

mutex.lock();
queue.enqueue(*pkt);
waitForNewPacket.wakeAll();
mutex.unlock();
}

int getPacket(AVPacket *pkt){
int ret;
mutex.lock();
forever {
if (abort_request) {
ret = -1;
break;
}
if (queue.size() == 0){
if (waitForNewPacket.wait(&mutex, 1000)){
}else{
qDebug("PacketQueue timeout, try again...");
}
continue;
}
*pkt= queue.dequeue();
ret = 1;
break;
}

mutex.unlock();
return ret;
}

void abort(){
mutex.lock();
abort_request = true;
mutex.unlock();
}

bool abort_request;
QQueue<AVPacket> queue;
QMutex mutex;
QWaitCondition waitForNewPacket;
};

解码器:

AVFrame *frame = av_frame_alloc();
AVFrame *frame_RGB = av_frame_alloc();
struct SwsContext *img_convert_ctx = nullptr;
int ret;
int cnt = 0;
int width_current = 0;
int height_current = 0;

avcodec_flush_buffers(mData->input_codec_ctx);

forever{
cnt++;
ret = decodeFrame(frame);
if (ret < 0 ){
break;
}
if (ret == 0){
continue;
}

// check if height and width have changed
if (width_current != frame->width || height_current != frame->height){
av_frame_free(&frame_RGB);
frame_RGB = av_frame_alloc();
frame_RGB->width = width_current = frame->width;
frame_RGB->height = height_current = frame->height;
frame_RGB->format = AV_PIX_FMT_RGB24;
av_image_alloc(frame_RGB->data, frame_RGB->linesize, frame_RGB->width, frame_RGB->height, AV_PIX_FMT_RGB24, 32);
img_convert_ctx = sws_getContext( frame->width,
frame->height,
static_cast<AVPixelFormat>(frame->format),
frame->width,
frame->height,
AV_PIX_FMT_RGB24,
SWS_BICUBIC,
nullptr, nullptr, nullptr);
}

if (img_convert_ctx != nullptr) {
sws_scale(img_convert_ctx, static_cast<uint8_t const * const *>(frame->data),
frame->linesize, 0, frame->height,
frame_RGB->data, frame_RGB->linesize);
// here is the frame available as RGB in frame_RGB
}

av_frame_unref(frame);

}

}

int VideoDecoder::decodeFrame(AVFrame* frame){
int ret = AVERROR(EAGAIN);

forever {
AVPacket pkt;

do {
ret = avcodec_receive_frame(input_codec_ctx, frame);
if (ret >= 0) {
//frame->pts = frame->pkt_dts;
//frame->pts = frame->best_effort_timestamp;
}

if (ret == AVERROR_EOF) {
avcodec_flush_buffers(input_codec_ctx);
return 0;
}
if (ret >= 0)
return 1;
} while (ret != AVERROR(EAGAIN));

if (queue->getPacket(&pkt) < 0)
return -1;

ret = avcodec_send_packet(input_codec_ctx, &pkt);

if (ret == AVERROR(EAGAIN)) {
qFatal("Receive_frame and send_packet both returned EAGAIN, which is an API violation.");
}

if (pkt.buf->buffer != nullptr){
av_packet_unref(&pkt);
}else{
qDebug() << "Packet cannot be freed, pkt.buf->buffer == NULL!";
}

}
}

关于c++ - ffmpeg 流解码 - 不使用 ffplay 时的人工制品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53449946/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com