static void *capture_loop( void *d ) { struct dc1394_input *conf = (struct dc1394_input *)d; struct frame *f; int cam; for(;;) { dc1394_dma_multi_capture( conf->camera, conf->cam_count ); for( cam = 0; cam < conf->cam_count; ++cam ) { if( conf->cam[cam].running && ( f = new_frame() ) ) { f->length = HEIGHT * WIDTH * 2; f->format = FORMAT_RAW_UYVY; f->width = WIDTH; f->height = HEIGHT; f->key = 1; memcpy( f->d, conf->camera[cam].capture_buffer, f->length ); if( soft_queue_add( conf->cam[cam].outq, f ) < 0 ) unref_frame( f ); } dc1394_dma_done_with_buffer( &conf->camera[cam] ); } } return NULL; }
static void *mpeg4_loop( void *d ) { struct mpeg4_decoder *en = (struct mpeg4_decoder *)d; xvid_dec_frame_t xvid_dec_frame; xvid_dec_stats_t xvid_dec_stats; struct frame *out, *input; int used, pos; for(;;) { input = get_next_frame( en->ex, 1 ); if( en->reset_pending && en->xvid_handle ) mpeg4_stop( en ); if( ! en->xvid_handle ) mpeg4_start( en, input ); out = new_frame(); out->width = en->width; out->height = en->height; pos = 0; while( input->length - pos > 0 ) { memset( &xvid_dec_frame, 0, sizeof( xvid_dec_frame ) ); xvid_dec_frame.version = XVID_VERSION; xvid_dec_frame.general = 0; xvid_dec_frame.bitstream = input->d + pos; xvid_dec_frame.length = input->length - pos; xvid_dec_frame.output.plane[0] = out->d; xvid_dec_frame.output.stride[0] = 2 * out->width; xvid_dec_frame.output.csp = XVID_CSP_UYVY; xvid_dec_stats.version = XVID_VERSION; used = xvid_decore( en->xvid_handle, XVID_DEC_DECODE, &xvid_dec_frame, &xvid_dec_stats ); if( used < 0 ) { out->length = 0; spook_log( SL_WARN, "mpeg4: XviD decoding failed!" ); } if( xvid_dec_stats.type == XVID_TYPE_VOL ) { out->width = en->width = xvid_dec_stats.data.vol.width; out->height = en->height = xvid_dec_stats.data.vol.height; } pos += used; } out->format = FORMAT_RAW_UYVY; out->length = 2 * out->width * out->height; out->key = 1; deliver_frame( en->ex, out ); unref_frame( input ); } return NULL; }
static void do_framedrop( struct frame *input, void *d ) { struct framedropper *drop = (struct framedropper *)d; if( drop->count == 0 ) deliver_frame_to_stream( input, drop->output ); else unref_frame( input ); if( ++drop->count == drop->scale ) drop->count = 0; }
static void get_back_frame1( struct frame *f, void *d ) { struct frame *newf; struct rtp_spook_input *conf = (struct rtp_spook_input *)d; newf = new_frame(); if(newf) { exchange_frame( conf->ex, newf ); deliver_frame_to_stream( f, conf->output ); } else { //printf("\r\ndrop frame!"); unref_frame(f); } }
static void *mpeg4_loop( void *d ) { struct mpeg4_encoder *en = (struct mpeg4_encoder *)d; xvid_enc_frame_t xvid_enc_frame; struct frame *mpeg, *input; for(;;) { input = get_next_frame( en->ex, 1 ); if( en->reset_pending && en->xvid_handle ) mpeg4_stop( en ); if( ! en->xvid_handle ) mpeg4_start( en, input ); if( input->width != en->width || input->height != en->height ) { spook_log( SL_WARN, "mpeg4: image size changed midstream!" ); unref_frame( input ); continue; } mpeg = new_frame(); memset( &xvid_enc_frame, 0, sizeof( xvid_enc_frame ) ); xvid_enc_frame.version = XVID_VERSION; xvid_enc_frame.bitstream = mpeg->d; xvid_enc_frame.length = -1; xvid_enc_frame.input.plane[0] = input->d; switch( input->format ) { case FORMAT_RAW_BGR24: xvid_enc_frame.input.csp = XVID_CSP_BGR; xvid_enc_frame.input.stride[0] = en->width * 3; break; case FORMAT_RAW_UYVY: xvid_enc_frame.input.csp = XVID_CSP_UYVY; xvid_enc_frame.input.stride[0] = en->width * 2; break; } xvid_enc_frame.vol_flags = 0; xvid_enc_frame.vop_flags = 0; xvid_enc_frame.type = XVID_TYPE_AUTO; xvid_enc_frame.quant = 0; xvid_enc_frame.motion = XVID_ME_ADVANCEDDIAMOND16; xvid_enc_frame.quant_intra_matrix = NULL; xvid_enc_frame.quant_inter_matrix = NULL; mpeg->length = xvid_encore( en->xvid_handle, XVID_ENC_ENCODE, &xvid_enc_frame, NULL ); if( mpeg->length < 0 ) { mpeg->length = 0; spook_log( SL_WARN, "mpeg4: XviD encoding failed!" ); } mpeg->format = FORMAT_MPEG4; mpeg->width = en->width; mpeg->height = en->height; mpeg->key = xvid_enc_frame.out_flags & XVID_KEYFRAME; deliver_frame( en->ex, mpeg ); unref_frame( input ); } return NULL; }
void DeliverIFrame( struct h264_encoder *en, uint8_t *pu8BitStreamBuf, uint32_t u32BitStreamLen, S_UTIL_H264_FRAME_INFO *psFrameInfo ) { struct frame *psH264Frame = NULL; int32_t i32TryCnt; E_UTIL_H264_NALTYPE_MASK eFrameMask; uint32_t u32FrameOffset; uint32_t u32FrameLen; if (u32BitStreamLen > en->u32IFrameBufSize) { if (en->pu8IFrameBuf) { free(en->pu8IFrameBuf); en->u32IFrameBufSize = 0; } en->pu8IFrameBuf = malloc(u32BitStreamLen + 100); if (en->pu8IFrameBuf) { en->u32IFrameBufSize = u32BitStreamLen; } else { en->u32IFrameBufSize = 0; } } if (en->pu8IFrameBuf == NULL) { printf("Spook DeliverIFrame: s_pu8IFrameBuf is null\n"); return; } memcpy(en->pu8IFrameBuf, pu8BitStreamBuf, u32BitStreamLen); eFrameMask = psFrameInfo->eNALType; while (eFrameMask) { if (eFrameMask & eUTIL_H264_NAL_SPS) { u32FrameOffset = psFrameInfo->u32SPSOffset + psFrameInfo->u32SPSStartCodeLen; u32FrameLen = psFrameInfo->u32SPSLen - psFrameInfo->u32SPSStartCodeLen; eFrameMask &= (~eUTIL_H264_NAL_SPS); } else if (eFrameMask & eUTIL_H264_NAL_PPS) { u32FrameOffset = psFrameInfo->u32PPSOffset + psFrameInfo->u32PPSStartCodeLen; u32FrameLen = psFrameInfo->u32PPSLen - psFrameInfo->u32PPSStartCodeLen; eFrameMask &= (~eUTIL_H264_NAL_PPS); } else { u32FrameOffset = psFrameInfo->u32IPOffset + psFrameInfo->u32IPStartCodeLen; u32FrameLen = psFrameInfo->u32IPLen - psFrameInfo->u32IPStartCodeLen; eFrameMask = 0; } i32TryCnt = 100; while (i32TryCnt) { psH264Frame = new_frame(); if (psH264Frame) break; i32TryCnt --; usleep(10000); } if (psH264Frame == NULL) { printf("Spook DeliverIFrame: psH264Frame is null\n"); return; } if (psH264Frame->size < u32FrameLen) { // enlarge frame size struct frame *new_frame; new_frame = enlarge_frame_buffer(psH264Frame, u32FrameLen + 40); if (new_frame) { psH264Frame = new_frame; } else { printf("Spook DeliverIFrame: unable enlarge frame buffer size\n"); unref_frame(psH264Frame); continue; } } memcpy(psH264Frame->d, en->pu8IFrameBuf + u32FrameOffset, u32FrameLen); psH264Frame->format = FORMAT_H264; psH264Frame->width = en->sH264EncConfig.m_asEncPipeInfo[en->eH264EncRes].m_uiWidth; psH264Frame->height = en->sH264EncConfig.m_asEncPipeInfo[en->eH264EncRes].m_uiHeight; psH264Frame->length = u32FrameLen; psH264Frame->key = 1; if (deliver_frame(en->ex, psH264Frame) != 0) printf("Spook DeliverIFrame: Deliver frame failed\n"); } }
void DeliverPFrame( struct h264_encoder *en, uint8_t *pu8BitStreamBuf, uint32_t u32BitStreamLen, S_UTIL_H264_FRAME_INFO *psFrameInfo ) { struct frame *psH264Frame = NULL; int32_t i32TryCnt; #if 1 i32TryCnt = 100; while (i32TryCnt) { psH264Frame = new_frame(); if (psH264Frame) break; i32TryCnt --; usleep(10000); } #else psH264Frame = new_frame(); #endif if (psH264Frame == NULL) { printf("Spook DeliverPFrame: psH264Frame is null\n"); return; } if (psH264Frame->size < u32BitStreamLen) { // enlarge frame size struct frame *new_frame; new_frame = enlarge_frame_buffer(psH264Frame, u32BitStreamLen + 40); if (new_frame) { psH264Frame = new_frame; } else { printf("Spook DeliverPFrame: unable enlarge frame buffer size\n"); unref_frame(psH264Frame); return; } } uint32_t u32FrameOffset = psFrameInfo->u32IPOffset + psFrameInfo->u32IPStartCodeLen; uint32_t u32FrameLen = psFrameInfo->u32IPLen - psFrameInfo->u32IPStartCodeLen; memcpy(psH264Frame->d, pu8BitStreamBuf + u32FrameOffset, u32FrameLen); psH264Frame->format = FORMAT_H264; psH264Frame->width = en->sH264EncConfig.m_asEncPipeInfo[en->eH264EncRes].m_uiWidth; psH264Frame->height = en->sH264EncConfig.m_asEncPipeInfo[en->eH264EncRes].m_uiHeight; psH264Frame->length = u32FrameLen; psH264Frame->key = 0; if (deliver_frame(en->ex, psH264Frame) != 0) printf("Spook DeliverPFrame: Deliver frame failed\n"); }