Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
	}
}
Ejemplo n.º 3
0
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, &parameter_set, &parameter_set_size, &parameter_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);
}
Ejemplo n.º 4
0
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);
	}
}
Ejemplo n.º 5
0
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;
	}
}