⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_enc.c

📁 sample on embedded linux
💻 C
📖 第 1 页 / 共 3 页
字号:
    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl(INADDR_ANY);    addr.sin_port = htons(port);    memset(&(addr.sin_zero), '\0', 8); // zero the rest of the struct    if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)))    {        HI_CloseSocket(fd);        printf("UDP Socket Open error: bind socket error.\n");        return -1;    }    #if 0    /* set to non-blocking */    if (ioctlsocket(f, FIONBIO, &on) < 0)    {        WRITE_LOG_DEBUG("UDP Socket Open error: set to nonblock mode error.\n");        return -1;    }    #endif    return fd;}#define RTP_DEFAULT_SSRC 41030HI_S32 HI_RTP_Sender_Create(RTP_SENDER_S ** ppRtpStream, RTP_PT_E    pt){    RTP_SENDER_S* pSender;        HI_SOCKET sock;    HI_PORT port = 0;        pSender = (RTP_SENDER_S*)malloc(sizeof(RTP_SENDER_S));    if (NULL == pSender)    {        printf("create new rtp sender error. not enough memory.\n");        return -1;    }        memset(pSender, 0 , sizeof(RTP_SENDER_S));    //INIT_LIST_HEAD(&pSender->targethosts);    memset(pSender->targethosts, 0, sizeof(pSender->targethosts));    pSender->bActive = HI_FALSE;    pSender->last_ts = 3600;    *ppRtpStream = pSender;    pSender->pt = pt;    pSender->ssrc = RTP_DEFAULT_SSRC;    sock = HI_SOCKET_Udp_Open(0);        if (sock < 0 )     {        printf("<RTP>create socket error.\n");         return -1;    }    port = HI_SOCKET_Udp_GetPort(sock);            if (port & 0x1) /*odd*/    {        pSender->rtcpport = port;        close(sock);                port -= 1;        sock = HI_SOCKET_Udp_Open(0);                if ( sock < 0 )         {            printf("<RTP>create socket error.\n");             return -1;        }        port = HI_SOCKET_Udp_GetPort(sock);    }        pSender->rtpport = port;        pSender->rtcpport = port + 1;    pSender->sock = sock;    int yes = 1;    if (setsockopt(pSender->sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)     {        printf("HI_ERR_RTP_SOCKET\n");        return -1;    }        printf("Create RTP Sender at port: %d", pSender->rtpport );        return HI_SUCCESS;    }RTP_TARGETHOST_S* HI_RTP_Sender_Find(IN RTP_SENDER_S* pRtpStream,                         IN HI_CHAR* ip,                         IN HI_PORT  port){    int i = 0;    for (i = 0 ; i < RTP_MAX_SENDER ; i++)    {                if ((strcmp(ip, pRtpStream->targethosts[i].remote_ip) == 0) &&             (port == pRtpStream->targethosts[i].remote_port))        {            return (&pRtpStream->targethosts[i]);        }    }    return NULL;    }RTP_TARGETHOST_S* HI_RTP_Sender_FindAvail(IN RTP_SENDER_S* pRtpStream){    int i = 0;    for (i = 0 ; i < RTP_MAX_SENDER ; i++)    {        if (pRtpStream->targethosts[i].bActive == HI_FALSE)        {            //WRITE_LOG_DEBUG("rtp host avail %d \n", i);            return (&pRtpStream->targethosts[i]);        }            }    return NULL;    }HI_S32 HI_RTP_Sender_Add(IN RTP_SENDER_S* pRtpStream,                         IN HI_CHAR* ip,                         IN HI_PORT  port){    RTP_TARGETHOST_S* pTarget = NULL;    printf("rtp sender add ip, %s:%d", ip, port);    pTarget = HI_RTP_Sender_Find(pRtpStream, ip, port);    if (pTarget == NULL)    {        pTarget = HI_RTP_Sender_FindAvail(pRtpStream);        if (pTarget == NULL)        {            return -1;        }        memset(pTarget, 0 , sizeof(RTP_TARGETHOST_S));        strcpy(pTarget->remote_ip, ip);        pTarget->remote_port = port;        pTarget->remote_addr.sin_family = AF_INET; // host byte order        pTarget->remote_addr.sin_port = htons(pTarget->remote_port); // short, network byte order        pTarget->remote_addr.sin_addr.s_addr = inet_addr(pTarget->remote_ip);        memset(&(pTarget->remote_addr.sin_zero), '\0', 8); // zero the rest of the struct    }    pTarget->hostState = RTP_TARGETHOST_STATE_REQ_IFrame;    pTarget->bActive = HI_TRUE;     return HI_SUCCESS;}/*synchronization header*/HI_S32 HI_RTP_Packet(IN RTP_SENDER_S * pRtpStream , HI_S32 ts_inc, HI_U32 marker,                 HI_CHAR *pPayload, HI_S32 len){    RTP_HDR_S* pRtpHdr = NULL;    memset(pRtpStream->buff, 0, RPT_MAX_PACKET_BUFF);    pRtpStream->buffLen = 0;        pRtpHdr = (RTP_HDR_S*)pRtpStream->buff;    RTP_HDR_SET_VERSION(pRtpHdr, RTP_VERSION);    RTP_HDR_SET_P(pRtpHdr, 0);    RTP_HDR_SET_X(pRtpHdr, 0);    RTP_HDR_SET_CC(pRtpHdr, 0);    RTP_HDR_SET_M(pRtpHdr, marker);    RTP_HDR_SET_PT(pRtpHdr, pRtpStream->pt);    RTP_HDR_SET_SEQNO(pRtpHdr, htons(pRtpStream->last_sn));        RTP_HDR_SET_TS(pRtpHdr, htonl(pRtpStream->last_ts));    RTP_HDR_SET_SSRC(pRtpHdr, htonl(pRtpStream->ssrc));        pRtpStream->last_sn++;    pRtpStream->last_ts   += ts_inc;            memcpy(pRtpStream->buff + RTP_HDR_LEN, pPayload, len);    pRtpStream->buffLen = RTP_HDR_LEN + len;    return HI_SUCCESS;}HI_S32 HI_RTP_Send(IN RTP_SENDER_S * pRtpStream){    RTP_TARGETHOST_S* pHost = NULL;    HI_S32 iRet;    int i = 0;    for(i = 0;i < RTP_MAX_SENDER;i++)    {        pHost = &pRtpStream->targethosts[i];        //WRITE_LOG_DEBUG("***Active: %d, BuffLen: %d, hostState:%d**\n",         //    pHost->bActive ,pRtpStream->buffLen ,pHost->hostState );        if (pHost->bActive && pRtpStream->buffLen > 0 )        {            iRet = sendto(pRtpStream->sock, pRtpStream->buff,                               pRtpStream->buffLen, 0,                               (struct sockaddr*)&pHost->remote_addr,                               sizeof(struct sockaddr) );                        if (iRet != pRtpStream->buffLen)            {                perror("send rtp error.");                pRtpStream->stats.sent_error++;                printf("<RTP>send packet error. %s", strerror(errno));                //HI_ERRNO(HI_ERR_RTP_SEND);            }            else            {                pRtpStream->stats.sent_byte += pRtpStream->buffLen;                pRtpStream->stats.sent_packet++;            }            if (pRtpStream->buffLen <= 16)                exit(-1);                    }    }        return HI_SUCCESS;}/*for rtp**********************************************************/#define CHECK_RET(hiRet) if(hiRet!=HI_SUCCESS) return hiRet;/*config parameter form the system*/HI_U16 mode = CIF;HI_U16 normal = PAL;VENC_FORMAT_E format = VENC_FORMAT_H264;HI_S32 venc_start(void *arg){    HI_S32   hiRet;    VI_CHN   vi_chn;            VENC_CHN venc_chn;    VENC_STREAM_S  venc_stream;      VENC_CONFIG_S  venc_config;    FILE *pfile = NULL;    char filename[255];    HI_U32 i, aucWriteLen = 0;;    vi_chn = *((VI_CHN*)arg);      /*step 1: start VI channel*/    hiRet = ViChnConfig(mode, normal, vi_chn);	if (HI_SUCCESS != hiRet)	{	    printf ("vi chn atr config failed\n");        HI_VENC_Close();	    return hiRet;	}	     /*step 2: create VIDEO encode channel*/    hiRet = HI_VENC_CreateCH(vi_chn, &venc_chn);    printf("venc_chn is %d\n", venc_chn);    if ( hiRet != HI_SUCCESS )    {        HI_VENC_DestroyCH(venc_chn, HI_TRUE);        return hiRet;    }	    switch (format)    {       case VENC_FORMAT_H264:            sprintf(filename, "venc_file_chn%d.h264", venc_chn);        break;       case VENC_FORMAT_H263:            sprintf(filename, "venc_file_chn%d.263", venc_chn);        break;        default:            break;    }        pfile = fopen(filename, "wb");    if ( NULL == pfile )    {        printf("open file error\n");        return HI_FAILURE;	}    /*step 3: start video encode channel*/    hiRet = HI_VENC_StartCH(venc_chn, 0);    if ( hiRet != HI_SUCCESS )    {        HI_VENC_DestroyCH(venc_chn, HI_TRUE);         return hiRet;    }    while ( 1 )    {          /*step 4: get stream with BLOCK way*/        hiRet = HI_VENC_GetStream(venc_chn, &venc_stream, HI_TRUE);        if ( hiRet != HI_SUCCESS )        {            HI_VENC_DestroyCH(venc_chn, HI_TRUE); /*if err, we destroy venc chn forcely*/            return hiRet;        }        //printf("save file slice num: %u, frame len: %u\n", venc_stream.u32DataNum, venc_stream.u32DataLen);                /*save stream to file*/        for ( i = 0 ; i < venc_stream.u32DataNum ; i++ )        {            switch (format)            {                case VENC_FORMAT_H264:                    aucWriteLen = fwrite(venc_stream.struData[i].pAddr, venc_stream.struData[i].u32Len, 1, pfile);                    if ( 1 != aucWriteLen )                    {                        printf("write file error: toLen:%u, aucLen:%d\n", venc_stream.struData[i].u32Len, aucWriteLen);                        exit(1);                   }                            break;               case VENC_FORMAT_H263:                {                    HI_U32 *payAddr, payLen;                     HI_U32 FrameLastPacketFlag, LastByteOverLapFlag, RTPModeAFlag;                      HI_U32 *dataAddr, dataLen;                     payAddr = (HI_U32*)(venc_stream.struData[i].pAddr);                    payLen = venc_stream.struData[i].u32Len;                                        /*save stream file*/                    FrameLastPacketFlag = venc_stream.struProp[i].FrameLastPacketFlag;                    LastByteOverLapFlag = venc_stream.struProp[i].LastByteOverLapFlag;                    RTPModeAFlag    =     venc_stream.struProp[i].RTPModeAFlag;                                        if ( RTPModeAFlag == 1 ) /*A mode rtp payload head is 32 bit*/                    {                        dataAddr = payAddr + 1;                        dataLen  = payLen - 4;                    }                    else if ( RTPModeAFlag == 0 )                    {                        dataAddr = payAddr + 2;                        dataLen  = payLen - 8;                                    }                    if ( LastByteOverLapFlag == 0 && FrameLastPacketFlag == 0) /*Bytes aligin*/                    {                        dataLen--;                    }                    aucWriteLen = fwrite((HI_VOID*)dataAddr, dataLen, 1, pfile);                    if ( 1 != aucWriteLen )                    {                        printf("write file error: toLen:%u, aucLen:%d\n",                             venc_stream.struData[i].u32Len, aucWriteLen);                        exit(1);                    }                                   }               break;               default:                break;                            }            //printf("chnid=%d, Iflag=%u, seq=%u, pts=%u\n",            //venc_stream.struDataInfo.ChnID, venc_stream.struDataInfo.u16IFrameFlag,            //venc_stream.struDataInfo.u32Seq,venc_stream.struDataInfo.u64PTS);        }        /*step 5: release stream buffer*/        hiRet = HI_VENC_ReleaseStream(venc_chn, &venc_stream);                    if ( hiRet != HI_SUCCESS )        {            HI_VENC_DestroyCH(venc_chn, HI_TRUE); /*if err, we destroy venc chn forcely*/            return hiRet;        }      		if(g_s32VencStopFlag[venc_chn] == HI_TRUE)		{			g_s32VencStopFlag[venc_chn] = HI_FALSE;			break;		}    }    /*step 6: stop video encode channel*/    hiRet = HI_VENC_StopCH(venc_chn);                    /*step 7: destroy video encode channel*/    hiRet = HI_VENC_DestroyCH(venc_chn, HI_TRUE);                fclose(pfile);    return 0;}int venc_sender_start(void *arg){    HI_S32   hiRet;    VI_CHN   vi_chn;            VENC_CHN venc_chn;    VENC_STREAM_S  venc_stream;      VENC_CONFIG_S  venc_config;    RTP_SENDER_S * pSender;    VSTART_ARG_S *pVstartArg = (VSTART_ARG_S*)arg;    vi_chn = pVstartArg->viChn;    HI_RTP_Sender_Create(&pSender, RTP_PT_H264);    HI_RTP_Sender_Add(pSender, pVstartArg->ipaddr, 6666);    /*step 1: start VI channel*/    hiRet = ViChnConfig(mode, normal, vi_chn);	if (HI_SUCCESS != hiRet)	{	    printf ("vi chn atr config failed\n");        HI_VENC_Close();	    return hiRet;	}	    /*step 2: create video encode channel*/    hiRet = HI_VENC_CreateCH(vi_chn, &venc_chn);    printf("vi chn is %d, venc_chn is %d\n", vi_chn, venc_chn);    if ( hiRet != HI_SUCCESS )    {        HI_VENC_Close();        return hiRet;    }    /*step 3: start video encode channel*/    hiRet = HI_VENC_StartCH(venc_chn, 0);    if ( hiRet != HI_SUCCESS )    {        return hiRet;    }    FILE *pfile = NULL;    char filename[255];    HI_U32 i;    sprintf(filename, "venc_file_chn%d.h264", venc_chn);    pfile = fopen(filename, "wb");    if ( NULL == pfile )    {        printf("open file error\n");        exit(1);    }    while ( 1 )    {          /*step 4: get stream */        hiRet = HI_VENC_GetStream(venc_chn, &venc_stream, HI_TRUE);        if ( hiRet != HI_SUCCESS )        {            printf("HI_VENC_GetStream error\n");            HI_VENC_Close();            return hiRet;        }        //printf("save file slice num: %u, frame len: %u\n", venc_stream.u32DataNum, venc_stream.u32DataLen);                /*send stream with RTP*/        for ( i = 0 ; i < venc_stream.u32DataNum ; i++ )        {#if 0                        aucWriteLen = fwrite(venc_stream.struData[i].pAddr, venc_stream.struData[i].u32Len, 1, pfile);            if ( 1 != aucWriteLen )            {                printf("write file error: toLen:%u, aucLen:%d\n", venc_stream.struData[i].u32Len, aucWriteLen);                exit(1);            }#endif                        HI_RTP_Packet(pSender, 0, 0, venc_stream.struData[i].pAddr, venc_stream.struData[i].u32Len);            HI_RTP_Send(pSender);            //printf("chnid=%d, Iflag=%u, seq=%u, pts=%u\n",            //venc_stream.struDataInfo.ChnID, venc_stream.struDataInfo.u16IFrameFlag,            //venc_stream.struDataInfo.u32Seq,venc_stream.struDataInfo.u64PTS);        }        /*step 5: releate stream*/        hiRet = HI_VENC_ReleaseStream(venc_chn, &venc_stream);                    if ( hiRet != HI_SUCCESS )        {            printf("HI_VENC_GetStream error\n");                        HI_VENC_Close();                        return hiRet;        }             /*you can stop this venc thread by vstop*/		if(g_s32VencStopFlag[venc_chn] == HI_TRUE)		{			g_s32VencStopFlag[venc_chn] = HI_FALSE;			break;		}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -