Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ffmpeg stream decoding - artefacts when not using ffplay

Tags:

c++

ffmpeg

h.264

I stream a video capture via RTP using libx264. For now, I just stream to localhost. For watching the stream, I use the ffmpeg library. When I set the GOP size greater than 1 (only I frames), I get artefacts on the receiver side received image. The strange thing is, when I use ffplay, the image is perfect like original. What am I doing wrong?

Settings for encoding

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);

Code for decoding

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);
}

Initialization and stuff omitted. Console output for custom decoding:

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
like image 912
Lucker10 Avatar asked Nov 23 '18 16:11

Lucker10


1 Answers

In the end I solved it by implementing it the same way ffplay does: One thread performs av_read_frame() and pushes the received packets to a packetqueue, and a second thread decodes the packets.

No idea why it does not work in one thread.

You might get an example from the following snippets:

PacketReceiver:

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();
}

PacketQueue:

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;
};

Decoder:

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!";
    }

}
}
like image 123
Lucker10 Avatar answered Oct 05 '22 12:10

Lucker10