static void enc_process(MSFilter *f){ EncData *d=(EncData*)f->data; uint32_t ts=f->ticker->time*90LL; int sizeAll=0,key=0; SPSInfo sps={0}; PPSInfo pps={0}; mblk_t *im; MSPicture pic; MSQueue nalus; ms_queue_init(&nalus); ms_mutex_lock(&f->lock); while((im=ms_queue_get(f->inputs[0]))!=NULL){ if (ms_yuv_buf_init_from_mblk(&pic,im)==0){ if (x264_encoder_start(d,&pic,&nalus,&sizeAll,&sps,&pps,&key)==0){ if (d->flv->state==Started){ MSQueue nalus_t; ms_queue_init(&nalus_t); x264_flv_to_file(f,&nalus,&nalus_t,sizeAll,&sps,&pps,key); //x264_nals_to_file(d->flv,&nalus,&nalus_t); rfc3984_pack(d->packer,&nalus_t,f->outputs[0],ts); } else{ rfc3984_pack(d->packer,&nalus,f->outputs[0],ts); } d->framenum++; }else{ ms_error("MSH264Enc: x264_encoder_start error"); } } freemsg(im); } ms_mutex_unlock(&f->lock); }
static void enc_process(MSFilter *f){ EncData *d=(EncData*)f->data; uint32_t ts=f->ticker->time*90LL; mblk_t *im; MSPicture pic; MSQueue nalus; ms_queue_init(&nalus); while((im=ms_queue_get(f->inputs[0]))!=NULL){ if (ms_yuv_buf_init_from_mblk(&pic,im)==0){ x264_picture_t xpic; x264_picture_t oxpic; x264_nal_t *xnals=NULL; int num_nals=0; memset(&xpic, 0, sizeof(xpic)); memset(&oxpic, 0, sizeof(oxpic)); /*send I frame 2 seconds and 4 seconds after the beginning */ if (video_starter_need_i_frame(&d->starter,f->ticker->time)) d->generate_keyframe=TRUE; if (d->generate_keyframe){ xpic.i_type=X264_TYPE_IDR; d->generate_keyframe=FALSE; }else xpic.i_type=X264_TYPE_AUTO; xpic.i_qpplus1=0; xpic.i_pts=d->framenum; xpic.param=NULL; xpic.img.i_csp=X264_CSP_I420; xpic.img.i_plane=3; xpic.img.i_stride[0]=pic.strides[0]; xpic.img.i_stride[1]=pic.strides[1]; xpic.img.i_stride[2]=pic.strides[2]; xpic.img.i_stride[3]=0; xpic.img.plane[0]=pic.planes[0]; xpic.img.plane[1]=pic.planes[1]; xpic.img.plane[2]=pic.planes[2]; xpic.img.plane[3]=0; if (x264_encoder_encode(d->enc,&xnals,&num_nals,&xpic,&oxpic)>=0){ x264_nals_to_msgb(xnals,num_nals,&nalus); /*if (num_nals == 0) ms_message("Delayed frames info: current=%d max=%d\n", x264_encoder_delayed_frames(d->enc), x264_encoder_maximum_delayed_frames(d->enc)); */ rfc3984_pack(d->packer,&nalus,f->outputs[0],ts); d->framenum++; if (d->framenum==0) video_starter_first_frame(&d->starter,f->ticker->time); }else{ ms_error("x264_encoder_encode() error."); } } freemsg(im); } }
static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSStatus status, VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer) { MSQueue nalu_queue; CMBlockBufferRef block_buffer; size_t read_size, frame_size; bool_t is_keyframe = FALSE; mblk_t *nalu; int i; if(sampleBuffer == NULL || status != noErr) { ms_error("VideoToolbox: could not encode frame: error %d", status); return; } ms_mutex_lock(&ctx->mutex); if(ctx->is_configured) { ms_queue_init(&nalu_queue); block_buffer = CMSampleBufferGetDataBuffer(sampleBuffer); frame_size = CMBlockBufferGetDataLength(block_buffer); for(i=0, read_size=0; read_size < frame_size; i++) { char *chunk; size_t chunk_size; int idr_count; CMBlockBufferGetDataPointer(block_buffer, i, &chunk_size, NULL, &chunk); ms_h264_stream_to_nalus((uint8_t *)chunk, chunk_size, &nalu_queue, &idr_count); if(idr_count) is_keyframe = TRUE; read_size += chunk_size; } if(is_keyframe) { mblk_t *insertion_point = ms_queue_peek_first(&nalu_queue); const uint8_t *parameter_set; size_t parameter_set_size; size_t parameter_set_count; CMFormatDescriptionRef format_desc = CMSampleBufferGetFormatDescription(sampleBuffer); i=0; do { CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format_desc, i, ¶meter_set, ¶meter_set_size, ¶meter_set_count, NULL); nalu = allocb(parameter_set_size, 0); memcpy(nalu->b_wptr, parameter_set, parameter_set_size); nalu->b_wptr += parameter_set_size; ms_queue_insert(&nalu_queue, insertion_point, nalu); i++; } while(i < parameter_set_count); } rfc3984_pack(&ctx->packer_ctx, &nalu_queue, &ctx->queue, (uint32_t)(ctx->f->ticker->time * 90)); } ms_mutex_unlock(&ctx->mutex); }
void MSOpenH264Encoder::feed() { if (!isInitialized()){ ms_queue_flush(mFilter->inputs[0]); return; } mblk_t *im; MSQueue nalus; ms_queue_init(&nalus); long long int ts = mFilter->ticker->time * 90LL; // Send I frame 2 seconds and 4 seconds after the beginning if (mVideoStarter.needIFrame(mFilter->ticker->time)) { generateKeyframe(); } while ((im = ms_queue_get(mFilter->inputs[0])) != NULL) { MSPicture pic; if (ms_yuv_buf_init_from_mblk(&pic, im) == 0) { SFrameBSInfo sFbi = { 0 }; SSourcePicture srcPic = { 0 }; srcPic.iColorFormat = videoFormatI420; srcPic.iPicWidth = pic.w; srcPic.iPicHeight = pic.h; for (int i = 0; i < 3; i++) { srcPic.iStride[i] = pic.strides[i]; srcPic.pData[i] = pic.planes[i]; } srcPic.uiTimeStamp = ts; int ret = mEncoder->EncodeFrame(&srcPic, &sFbi); if (ret == cmResultSuccess) { if ((sFbi.eOutputFrameType != videoFrameTypeSkip) && (sFbi.eOutputFrameType != videoFrameTypeInvalid)) { if (mFrameCount == 0) { mVideoStarter.firstFrame(mFilter->ticker->time); } mFrameCount++; fillNalusQueue(sFbi, &nalus); rfc3984_pack(mPacker, &nalus, mFilter->outputs[0], sFbi.uiTimeStamp); } } else { ms_error("OpenH264 encoder: Frame encoding failed: %d", ret); } } freemsg(im); } }
static void enc_process(MSFilter *f){ EncData *d=(EncData*)f->data; MSPicture pic = {0}; MSQueue nalus; mblk_t *im; long long int ts = f->ticker->time * 90LL; if (d->codec==NULL){ ms_queue_flush(f->inputs[0]); return; } ms_queue_init(&nalus); while((im=ms_queue_get(f->inputs[0]))!=NULL){ if (ms_yuv_buf_init_from_mblk(&pic,im)==0){ uint8_t *buf=NULL; size_t bufsize; ssize_t ibufidx, obufidx; ibufidx = AMediaCodec_dequeueInputBuffer(d->codec, TIMEOUT_US); if (ibufidx >= 0) { buf = AMediaCodec_getInputBuffer(d->codec, ibufidx, &bufsize); if(buf != NULL){ if(d->isYUV){ int ysize = pic.w * pic.h; int usize = ysize / 4; memcpy(buf, pic.planes[0], ysize); memcpy(buf + ysize, pic.planes[1], usize); memcpy(buf + ysize+usize, pic.planes[2], usize); } else { size_t size=(size_t) pic.w * pic.h; uint8_t *dst = pic.planes[0]; memcpy(buf,dst,size); int i; for (i = 0; i < pic.w/2*pic.h/2; i++){ buf[size+2*i]=pic.planes[1][i]; buf[size+2*i+1]=pic.planes[2][i]; } } AMediaCodec_queueInputBuffer(d->codec, ibufidx, 0, (size_t)(pic.w * pic.h)*3/2, f->ticker->time*1000,0); } } AMediaCodecBufferInfo info; obufidx = AMediaCodec_dequeueOutputBuffer(d->codec, &info, TIMEOUT_US); while(obufidx >= 0) { buf = AMediaCodec_getOutputBuffer(d->codec, obufidx, &bufsize); extractNalus(buf,info.size,ts,&nalus); AMediaCodec_releaseOutputBuffer(d->codec, obufidx, FALSE); obufidx = AMediaCodec_dequeueOutputBuffer(d->codec, &info, TIMEOUT_US); rfc3984_pack(d->packer,&nalus,f->outputs[0],ts); } if (d->framenum==0) ms_video_starter_first_frame(&d->starter, f->ticker->time); d->framenum++; } freemsg(im); } if (d->force_keyframe == TRUE) { AMediaCodec_setParams(d->codec,""); d->force_keyframe = FALSE; } }