FFMPEG:avcodec_send_packet();使用多线程时发生错误

时间:2018-07-12 09:02:01

标签: ffmpeg pthreads

我编写了2个线程来解码来自IP摄像机的RTSP流,如下所示:

RTSP_read_paket函数用于从RTSP链接读取数据包,这些数据包存储在名为Packet_buf的队列中。

std::queue<AVPacket> Packet_buf;
bool pkt_pending_k = false;

int RTSP_read_packet (string url)
{
    rtsp_init(url);

    int ret;
    AVPacket packet;
    av_init_packet(&packet);

    while(1)
    {
       ret = av_read_frame(pFormatCtx,&packet);
       if(ret==0)
       {
           if (packet.stream_index == video_stream_index)
           {
               Packet_buf.push(packet);
               if((ready1 == false))
               {
                    ready1 = true;
                    conv1.notify_one();
               }
           }
           av_packet_unref(&packet);
           cout<<"number of RTSP packet: "<<Packet_buf.size()<<endl;
       }
    }
    return 0;
}

ffmpeg_decode从Packet_buf中读取数据包以解码帧

AVFrame ffmpeg_decode( void )
{
      AVPacket avpkt;
      av_init_packet(&avpkt);
      int ret;

      conv1.wait(lk1,[]{return ready1;});
      while(1)
      {
            while(1)
            {
                 ret = avcodec_receive_frame(pCodecCtx,pFrame);
                 if(ret == AVERROR(EAGAIN)||ret==AVERROR_EOF){
                       break;
                 }
                 return pFrame;
            }

            if(!Packet_buf.empty())
            {
                if(pkt_pending_k == false)
                {
                  avpkt = Packet_buf.front();
                  Packet_buf.pop();
                }else{
                    pkt_pending_k = false;
                }
            }


            ret = avcodec_send_packet(pCodecCtx, &avpkt); //program halting here
            cout<<"-------------> ret = "<<ret<<endl;

            if(ret==AVERROR(EAGAIN))
            {
                pkt_pending_k = true;
            }

               if(ret<0||ret==AVERROR_EOF)
               {
                     cout<<"avcodec_send_packet: "<<ret<<endl;
                     break;
               }
        }
}

int main () {
        thread Camera2_readPackets(RTSP_read_packet,url);
        thread Camera2_decode(ffmpeg_decode,url);
        Camera2_decode.join();
        return 0;
}

我的程序在以下行停止:

ret = avcodec_send_packet(pCodecCtx, &avpkt);

任何人都可以帮助我找到问题,谢谢!

P / s: rtsp_init函数:

int rtsp_init (string url)
{
    av_register_all();
    avdevice_register_all();
    avcodec_register_all();
    avformat_network_init();
    const char  *filenameSrc = url.c_str();

    pFormatCtx = avformat_alloc_context();
    if ( pFormatCtx == NULL )
            return -8;

    AVDictionary *options = NULL;
    av_dict_set(&options,"rtsp_flags","prefer_tcp",0);
    av_dict_set(&options,"stimeout","1000000",0);
    int avret = avformat_open_input( &pFormatCtx, filenameSrc, NULL, &options );
    av_dict_free(&options);

    if ( avret != 0 ) {
            std::cout << "Open File Error 12" << std::endl;
            return -12;
        }

    avret = avformat_find_stream_info( pFormatCtx, NULL );
    if (  avret < 0 ) {
            std::cout << "Get Stream Information Error 13" << std::endl;
            avformat_close_input( &pFormatCtx );
            pFormatCtx = NULL;
            return -13;
     }
    av_dump_format( pFormatCtx, 0, filenameSrc, 0 );

    video_stream_index = av_find_best_stream(pFormatCtx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);
    if ( video_stream_index < 0 ) {
        std::cout << "Video stream was not found Error 14" << std::endl;
        avformat_close_input( &pFormatCtx );
        pFormatCtx = NULL;
        return -14;
    }

    pCodecCtx = avcodec_alloc_context3(NULL);
    avret = avcodec_parameters_to_context(pCodecCtx,pFormatCtx->streams[video_stream_index]->codecpar);
    if(avret<0)
    {
        std::cout << "codec not found Error 15" << std::endl;
        return -15;
    }

    pCodec  = avcodec_find_decoder( pCodecCtx->codec_id );
    avret = avcodec_open2( pCodecCtx, pCodec, NULL );
    if ( avret < 0) {
        std::cout << "Open Codec Error 16" << std::endl;
       return -16;
    }

    pFrame    = av_frame_alloc();
    pFrameRGB = av_frame_alloc();

    pFrame->width = pCodecCtx->width;
    pFrame->height = pCodecCtx->height;
    pFrame->format = pCodecCtx->pix_fmt;
    avret = av_frame_get_buffer(pFrame,0);
    if (avret < 0)
    {
        return -17;
    }

    pFrameRGB->width = pCodecCtx->width;
    pFrameRGB->height = pCodecCtx->height;
    pFrameRGB->format = AV_PIX_FMT_BGR24;

    avret = av_frame_get_buffer(pFrameRGB, 0);
    if (avret < 0)
    {
        return -18;
    }

    return ( EXIT_SUCCESS );
}

0 个答案:

没有答案