📄 avin_ha2.c
字号:
/********************************************** * Dawn Light Player * * avin_ha2.c * * Created by kf701.ye at gmail.com * 17:48:08 02/26/08 CST * * $Id: avin_ha2.c 174 2008-03-22 06:30:04Z kf701 $ **********************************************/#if ENABLE_AVIN_HA2#if !defined(__MINGW32__)#include <netdb.h>#endif#include "avdecode.h"#include "avformat.h"#include "avinput.h"#include "avoutput.h"#include "global.h"static void avctx_init_aac(AVCodecContext *avctxp){ avctxp->skip_bottom = 0; strcpy(avctxp->codec_name, "libfaad"); avctxp->codec_type = CODEC_TYPE_AUDIO; avctxp->codec_id = CODEC_ID_AAC; avctxp->bit_rate = 39*1024; avctxp->sample_fmt = 1; avctxp->sample_rate = 48000; avctxp->channels = 2; /* set dlpctx */ dlpctxp->bit_rate = avctxp->bit_rate; dlpctxp->sample_fmt = avctxp->sample_fmt; dlpctxp->sample_rate = avctxp->sample_rate; dlpctxp->channels = avctxp->channels;}static void avctx_init_h264(AVCodecContext *avctxp){ avctxp->skip_bottom = 0; strcpy(avctxp->codec_name, "h264"); avctxp->codec_type = CODEC_TYPE_VIDEO; avctxp->codec_id = CODEC_ID_H264; avctxp->bits_per_sample = 32; avctxp->width = 320; avctxp->height = 240; /* set dlpctx */ dlpctxp->width = avctxp->width; dlpctxp->height = avctxp->height; dlpctxp->fps = 25;}#define DATA_SERVER_PORT 5120#define DATA_PLAYER_PORT 5122#define MAX_VIDEO_UNIT_LEN 4096*5#define MAX_AUDIO_UNIT_LEN 512#define GET_VIDEO_UNIT 1#define GET_AUDIO_UNIT 2static int player_listen_fd;static struct sockaddr_in seraddr;static char *daemon_ip;typedef struct{ uint8_t frame_type; /* I,B,P */ uint8_t spi_syn; uint16_t coderate; /* 1/100 bps */ uint8_t framerate; /* fps: 15, 25, 30 */ uint32_t inittime; uint16_t relatetime; /* 1/22500s */ uint32_t len;} video_play_t;typedef struct{ uint8_t spi_syn; uint16_t coderate; /* 1/100 bps */ uint32_t samplerate; uint32_t inittime; uint16_t relatetime; /* 1/22500s */ uint32_t len;} audio_play_t;static int open_udp( uint16_t port);static int ha2_ipc_init(void);static int get_audio( audio_play_t *ag, uint8_t *buf, int size );static int get_video( video_play_t *vg, uint8_t *buf, int size );static int avin_ha2_init(void){ dlp_vctxp = &dlp_vctx; dlp_actxp = &dlp_actx; avctx_init_h264(dlp_vctxp); avctx_init_aac(dlp_actxp);#if defined(__MINGW32__) { WSADATA wsaData; WSAStartup(MAKEWORD(1,1), &wsaData); }#endif daemon_ip = dlpctxp->filename; ha2_ipc_init(); av_log(NULL, AV_LOG_INFO, "init input for CMMB, Daemon IP: %s\n", daemon_ip); return 0;}static int avin_ha2_uninit(void){#if defined(__MINGW32__) WSACleanup();#endif av_log(NULL, AV_LOG_INFO, "uninit input from CMMB\n"); return 0;}static void avin_ha2_main(void){ video_play_t vg; audio_play_t ag; uint8_t abuf[MAX_AUDIO_UNIT_LEN]; uint8_t vbuf[MAX_VIDEO_UNIT_LEN]; AVPacket *pkt; int aret, vret, vqlen, aqlen; /* sync packet first */ memset(&ag, 0, sizeof(ag)); memset(&vg, 0, sizeof(vg)); vret = get_video(&vg, vbuf, sizeof(vbuf)); aret = get_audio(&ag, abuf, sizeof(abuf)); while ( aret < 0 ) { vret = get_video(&vg, vbuf, sizeof(vbuf)); aret = get_audio(&ag, abuf, sizeof(abuf)); } if ( ag.spi_syn != vg.spi_syn ) { while ( ag.spi_syn > vg.spi_syn && ag.spi_syn - vg.spi_syn > 100 ) aret = get_audio(&ag, abuf, sizeof(abuf)); while ( vg.spi_syn > ag.spi_syn && vg.spi_syn - ag.spi_syn > 100 ) vret = get_video(&vg, vbuf, sizeof(vbuf)); while ( ag.spi_syn > vg.spi_syn ) vret = get_video(&vg, vbuf, sizeof(vbuf)); while ( ag.spi_syn < vg.spi_syn ) aret = get_audio(&ag, abuf, sizeof(abuf)); } while (1) { vqlen = dlp_queue_length(video_packet_queue); aqlen = dlp_queue_length(audio_packet_queue); if ( aqlen > MAX_VIDEO_PACKET_QUEUE_LEN || vqlen > MAX_AUDIO_PACKET_QUEUE_LEN ) { av_log(NULL, AV_LOG_DEBUG, "video packet queue len: %d\n", vqlen); av_log(NULL, AV_LOG_DEBUG, "audio packet queue len: %d\n", aqlen); usleep(50*1000); continue; } if ( vret > 0 ) { pkt = av_mallocz( sizeof(AVPacket) ); av_new_packet( pkt, vret); memcpy( pkt->data, vbuf, vret ); pkt->pts = vg.inittime + vg.relatetime; dlp_queue_push_tail( video_packet_queue, pkt ); } if ( aret > 0 ) { pkt = av_mallocz( sizeof(AVPacket) ); av_new_packet( pkt, aret); memcpy( pkt->data, abuf, aret ); pkt->pts = ag.inittime + ag.relatetime; dlp_queue_push_tail( audio_packet_queue, pkt ); } while ( ag.inittime > vg.inittime ) { vret = get_video(&vg, vbuf, sizeof(vbuf)); if ( vret < 0 ) continue; if ( vg.inittime == 1 ) { memset(&ag, 0, sizeof(ag)); memset(&vg, 0, sizeof(vg)); vret = aret = 0; break; } pkt = av_mallocz( sizeof(AVPacket) ); av_new_packet( pkt, vret); memcpy( pkt->data, vbuf, vret ); pkt->pts = vg.inittime + vg.relatetime; dlp_queue_push_tail( video_packet_queue, pkt ); } while ( ag.inittime < vg.inittime ) { aret = get_audio(&ag, abuf, sizeof(abuf)); if ( -4 == aret ) /* Add silent */ { AVSample *s = av_mallocz( sizeof(AVSample) ); av_new_sample( s, 4096 ); memset( s->data, 0, 4096 ); s->pts = 0; dlp_queue_push_tail(samples_queue, s); } if ( aret < 0 ) continue; if ( ag.inittime == 1 ) { memset(&ag, 0, sizeof(ag)); memset(&vg, 0, sizeof(vg)); vret = aret = 0; break; } pkt = av_mallocz( sizeof(AVPacket) ); av_new_packet( pkt, aret); memcpy( pkt->data, abuf, aret ); pkt->pts = ag.inittime + ag.relatetime; dlp_queue_push_tail( audio_packet_queue, pkt ); } vret = get_video(&vg, vbuf, sizeof(vbuf)); aret = get_audio(&ag, abuf, sizeof(abuf)); if ( ag.inittime == 1 || vg.inittime == 1 ) { memset(&ag, 0, sizeof(ag)); memset(&vg, 0, sizeof(vg)); vret = aret = 0; } }}static int avin_ha2_control(int cmd, void *arg){ av_log(NULL, AV_LOG_ERROR, "not support now for avin ha2\n"); return -1;}avin_t avin_ha2 ={ AVIN_ID_HA2, "ha2", avin_ha2_init, avin_ha2_uninit, avin_ha2_main, avin_ha2_control,};static int open_udp( uint16_t port){ int fd; struct sockaddr_in addr; fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if ( fd == -1 ) { av_log(NULL, AV_LOG_ERROR,"%s,%d:socket error\n",__func__,__LINE__); return -1; } memset((char*) &(addr),0, sizeof((addr))); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if ( bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 ) { av_log(NULL,AV_LOG_ERROR,"%s,%d:bind error\n",__func__,__LINE__); return -1; } return fd;}static int ha2_ipc_init(void){ struct hostent *hent; if ( NULL == daemon_ip ) { av_log(NULL, AV_LOG_ERROR, "ha2 init: must set daemon IP as filename\n"); dlp_exit(1); } player_listen_fd = open_udp( DATA_PLAYER_PORT ); if ( -1 == player_listen_fd ) { av_log(NULL, AV_LOG_ERROR, "ha2 init: open udp error\n"); return -1; } hent = gethostbyname(daemon_ip); if (NULL == hent) { av_log(NULL, AV_LOG_ERROR, "ha2 init: get hostname error\n"); return -1; } memset(&seraddr, 0, sizeof(seraddr)); seraddr.sin_family = AF_INET; seraddr.sin_port = htons(DATA_SERVER_PORT); seraddr.sin_addr = *(struct in_addr *)hent->h_addr; return 0;}static int get_video( video_play_t *vg, uint8_t *buf, int size ){ uint8_t temp[16], video[MAX_VIDEO_UNIT_LEN]; int ret; fd_set readset; struct timeval tv = { 0, 200*1000 }; temp[0] = GET_VIDEO_UNIT; ret = sendto( player_listen_fd, (const char *)temp, 16, 0, (struct sockaddr*)&seraddr, sizeof(seraddr) ); if ( -1 == ret ) { av_log(NULL, AV_LOG_DEBUG, "avin ha2 get_video: sendto error\n"); return -1; } FD_ZERO(&readset); FD_SET( player_listen_fd, &readset ); ret = select(player_listen_fd + 1, &readset, NULL, NULL, &tv); if ( !FD_ISSET( player_listen_fd, &readset ) ) { av_log(NULL, AV_LOG_DEBUG, "avin ha2 get_video: readset not set\n"); return -1; } ret = recvfrom( player_listen_fd, (char*)video, sizeof(video), 0, NULL, NULL ); if ( ret <= sizeof(video_play_t) || size < ret - sizeof(video_play_t) ) { av_log(NULL, AV_LOG_DEBUG, "avin ha2 get_video: recvfrom error\n"); return -1; } memcpy( vg, video, sizeof(video_play_t) ); memcpy( buf, video+sizeof(video_play_t), ret-sizeof(video_play_t) ); return vg->len;}static int get_audio( audio_play_t *ag, uint8_t *buf, int size ){ uint8_t temp[16], audio[MAX_AUDIO_UNIT_LEN]; int ret; struct timeval tv = { 0, 200*1000 }; fd_set readset; temp[0] = GET_AUDIO_UNIT; ret = sendto( player_listen_fd, (const char *)temp, sizeof(temp), 0, (struct sockaddr*)&seraddr, sizeof(seraddr) ); if ( -1 == ret ) { av_log(NULL, AV_LOG_DEBUG, "avin ha2 get_audio: sendto error\n"); return -1; } FD_ZERO(&readset); FD_SET( player_listen_fd, &readset ); ret = select(player_listen_fd + 1, &readset, NULL, NULL, &tv); if ( !FD_ISSET( player_listen_fd, &readset ) ) { av_log(NULL, AV_LOG_DEBUG, "avin ha2 get_audio: readset not set\n"); return -1; } ret = recvfrom( player_listen_fd, (char*)audio, sizeof(audio), 0, NULL, NULL ); if ( ret <= sizeof(audio_play_t) || size < ret-sizeof(audio_play_t) ) { av_log(NULL, AV_LOG_DEBUG, "avin ha2 get_audio: recvfrom error\n"); return -1; } memcpy( ag, audio, sizeof(audio_play_t) ); if ( ag->len == 4 ) /* FUCK for qwdu player */ return -4; memcpy( buf, audio+sizeof(audio_play_t), ret-sizeof(audio_play_t) ); return ag->len;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -