zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

RTSP服务器综合项目:rtsp实时监控

2023-09-14 09:05:27 时间

目标:添加摄像头采集编码和码流队列管理,完成实时监控功能。

protocol.h添加采集相关设置

// RTSP服务器测试
#define RTSP_USE_RTP_H264       0  // rtsp传输h264
#define RTSP_USE_RTP_H264_RT    1  // 实时监控

// capture_h264.c采集相关设置
#define MEDIA_DURATION 40
#define CAMERA_DEV "/dev/video0"
#define CAMERA_W    640
#define CAMERA_H    480
#define CAMERA_FPS  25
#define CAMERA_FMT AV_PIX_FMT_YUYV422
#define ENCODE_FMT AV_PIX_FMT_YUV420P

rtp_h264.c添加rtp_play_h264_rt

/************************ For Capture H264 *************************/
int rtp_play_h264_rt(int sockfd, client_t *client) {
    struct rtp_packet *rtp_pkt = (struct rtp_packet *)malloc(RTP_PACKET_SIZE);
    rtp_header_init(&rtp_pkt->header, RTP_PAYLOAD_TYPE_H264, 0, 0, 0, 0x88923423);

    pthread_t cap_tid;
    pthread_create(&cap_tid, NULL, capture_video_thread, NULL);

    // 必须等video_que初始化完成,才能执行add_user操作
    while (video_que == NULL)
        sched_yield(); 
    queue_add_user(video_que, READER_ROLE);

    int index = 0;
    while (1) {
        AVPacket *packet = dequeue(video_que);
        if (packet == NULL) break;

        rtp_send_h264_nalu(sockfd, client, packet->data, packet->size, rtp_pkt);
        rtp_pkt->header.timestamp += 90000/CAMERA_FPS;

        index++;
        //printf("send %4d rtp frame:%d\n", index, packet->size);
        usleep(1000*1000/CAMERA_FPS);
        av_packet_free(&packet);
    }

    free(rtp_pkt);
    if (video_que) // 如果capture线程先退出,则video_que已被销毁
        queue_del_user(video_que, READER_ROLE);
    pthread_cancel(cap_tid);
    pthread_join(cap_tid, NULL);
}

capture_h264.c

void *capture_video_thread(void *p) {
    // 采集输入初始化
    AVInputDev *input = malloc(sizeof(AVInputDev));
    VideoInput_Init(input, CAMERA_W, CAMERA_H);

    video_que = create_queue_buffer();
    queue_add_user(video_que, WRITER_ROLE);
    printf("start capture\n");
    while (1) {
        // 添加录制期限, 如果需要推流,有延迟
        if (av_compare_ts(input->yuvframe->pts, input->enc_ctx->time_base, \
                    MEDIA_DURATION, (AVRational){1, 1}) >= 0) {
            printf("capture %d s video finish.\n", MEDIA_DURATION);
            break;
        }

        get_rawframe(input);

        AVPacket *packet = av_packet_alloc();
        int ret = encodec_frame_to_packet(input->enc_ctx, input->yuvframe, packet);
        if (ret == EAGAIN) continue;
        else if (ret == EINVAL) break;
            
        enqueue(video_que, packet);         
    }

    queue_del_user(video_que, WRITER_ROLE);
    destroy_queue_buffer(video_que);
    VideoInput_Destroy(input);
    pthread_exit(NULL);
}

运行测试:

 

 

 本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓