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

📄 mjpeg_encode.c

📁 快速开发基于Blackfin处理器的视频应用
💻 C
📖 第 1 页 / 共 2 页
字号:

	// temporary!!!  Reading from File not implemented/defined yet!!!!!!!!!!!!!!!!
	if(!capture_video)
	{
		fprintf(fperr, "Encoding from *.??? file not implemented yet!\n");
		return CODEC_FILE_ERROR;
	}

	// Configure JPEG encoder
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_FRAME_WIDTH, Input_Width);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_FRAME_HEIGHT, Input_Height);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_QUALITYFACTOR, QualityFactor);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_IMAGEFORMAT, InterLeaveFormat);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_ENCODINGMODE, EncodingMode);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_THRESHOLD, Threshhold);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
    

	// allocate the output streambuffer
	StreamBuffer_Obj = JPEG_MemAlloc_NEW(3 * Input_Width * Input_Height,1,MEM_TYPE_DATA);
	if(StreamBuffer_Obj == NULL)
	{
		fprintf(fperr, "Memory allocation for StreamBuffer failed.\n");
		exit(1);
	}
	StreamBuffer = (uint8*)JPEG_MemAlloc_ADDRESS(StreamBuffer_Obj);

	// input for encoder is YUV buffer
	//JPEG_Param_CONFIG(&lImageParam, JPEG_POINTER_INPUT, (int)lInputBuffer);
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_POINTER_OUTPUT, (int)StreamBuffer);
	if(lResult != E_SUCCESS)    {
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    }
	
	// Create Instance of JPEG Encoder
	lJpegEnc = JPEG_Encoder_NEW(&lImageParam);

	if(NULL == lJpegEnc)
	{
		fprintf(fperr, "Encoder creation failed\n");
		return CODEC_MEMORY_ALLOCATION_ERROR;
	}


	/****************************/
	/* SETUP MJPEG ENCODER		*/
	/****************************/
	// Create the AVI output file, with the required file
	// write result to output file
	strcat(input_file, ".avi");		// add extension

	lResult = MJPEG_AVI_OpenFileWrite(&lStreamFileOutHandle, (uint8*)input_file,&lImageParam, FrameRate);
    if(lResult != MJPEG_AVI_RETURN_OK)
    {
        MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_OpenFileWrite");
        return CODEC_FILE_ERROR;
    }
	
	// Set stream parameters from the JPEG parameters
	lResult = MJPEG_AVI_SetStreamParams (&lStreamInfo, &lImageParam, FrameRate);
	if (MJPEG_AVI_RETURN_ERROR == lResult)
	{
		fprintf(fperr, "Cannot set MJPEG AVI encoder stream parameters\n");
		return CODEC_ALGORITHM_ERROR;
	}

	// Create the stream
	lResult = MJPEG_AVI_OpenStreamWrite(lStreamFileOutHandle, &lStreamHandle, &lStreamInfo);
	if(lResult == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot create MJPEG AVI encoder stream\n");
		return CODEC_ALGORITHM_ERROR;
	}

	// Copy the frame format from the JPEG parameters
	lResult = MJPEG_AVI_CopyParams (&lBitMapInfo, &lImageParam);
	if(lResult == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot copy MJPEG AVI encoder frame format from JPEG parameters\n");
		return CODEC_ALGORITHM_ERROR;
	}

	// Set the stream format from the JPEG parameters
	lFormatLength = sizeof(tMJPEG_AVI_BITMAPINFO);
	lResult = MJPEG_AVI_SetFormat(lStreamHandle, 0, (uint8 *)&lBitMapInfo, lFormatLength);
	if(lResult == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot set the MJPEG AVI encoder stream format\n");
		return CODEC_ALGORITHM_ERROR;
	}

	// Initialize the MDMA descriptors
	InitDescriptorChains_Input();

	// wait for user action
	printf("press and release button SW6 on EZ-kit to start recording\n");
	printf("press and release button SW6 AGAIN to stop recording\n");

	// wait for button SW6 to be pressed
	while(!ezIsButtonPushed(6));
	// wait for button SW6 to be released
	while(ezIsButtonPushed(6));
   *pPPI1_CONTROL = 0x0000;
	// initialise statistics
	max_frame_cycles = 0;
	min_frame_cycles = (cycle_t)10*600*1000000;		// set to time approx equivalent to 10Seconds at 600MHz - no frame should take longer than that to decode :)

	max_usb_cycles = 0;
	min_usb_cycles = (cycle_t)10*600*1000000;		// set to time approx equivalent to 10Seconds at 600MHz - no frame should take longer than that to be read :)
	max_usb_bytes = 0;
	min_usb_bytes = (unsigned int)0x0fffffff;		// big value for min calculation

	/****************************/
	/* ENCODE NEXT FRAME		*/
	/****************************/
	lNumFrames = 0;
	isMJEInputDataAvailable = E_TRUE;

	MaxBytesPerFrame = 0;

	// Set buffer level to max
	BufferLevel = NUM_OF_YUV_BUFS;

	// Enable MDMA
	Frame_Ready = true;
	Start_MDMA = true;

	start_frame = Video_Frame_Counter;			// we will wait for the next frame (small probability of being off by one)
	
	// Main loop for each frame
	do
	{
		// Wait for a filled buffer to encode
		while (BufferLevel >= NUM_OF_YUV_BUFS);

		ezTurnOnLED(7);

		lInputBuffer = (uint8*)(YUV_Buffer_Address[YUVBufferWriteIndex]);

		// Set input YUV buffer pointer
		// temporary workaround
		JPEG_McuBuffer_CONFIG(mcu_ex, MCU_POINTER_C1, (unsigned int)lInputBuffer);

		START_CYCLE_COUNT(start_count)				// begin counting time
		lResult = JPEG_EncodeSequentialImage(lJpegEnc, &NumBytes);
		STOP_CYCLE_COUNT(final_count,start_count)
		ezTurnOffLED(7);

		cycle_sum += (float)final_count;
		min_frame_cycles = min(min_frame_cycles, final_count);
		max_frame_cycles = max(max_frame_cycles, final_count);

		// Update the count and write index
		UpdateYUVIndex(UPDATETYPE_WRITE);
		BufferLevel++;

		if(lResult != E_SUCCESS)    {
            JPEG_ProcessErrorCode(lResult, "JPEG_EncodeSequentialImage");
        }
	    
		if (NumBytes > MaxBytesPerFrame) MaxBytesPerFrame = NumBytes;

		ezTurnOnLED(6);

		START_CYCLE_COUNT(start_count)				// begin counting time
		lResult = MJPEG_AVI_WriteStream(lStreamHandle, StreamBuffer, NumBytes, 0);
		STOP_CYCLE_COUNT(final_count,start_count)

		min_usb_cycles = min(min_usb_cycles, final_count);
		max_usb_cycles = max(max_usb_cycles, final_count);
		min_usb_bytes = min(min_usb_bytes, NumBytes);
		max_usb_bytes = max(max_usb_bytes, NumBytes);

		if (MJPEG_AVI_RETURN_ERROR == lResult) {
			fprintf(fperr, "\nCannot write MJPEG AVI encoder frame to stream\n");
			return CODEC_FILE_ERROR;
		} else if (MJPEG_AVI_RETURN_EVALUATIONLIMITREACHED == lResult) {
			fprintf(fperr, "\nEvaluation limit reached.  Encoding finished.\n");
			break;
		} else {
			if ((lNumFrames % 10) == 0)	printf("\n%8.8d: ", lNumFrames);
			printf(".");
			lNumFrames++;
		}

		ezTurnOffLED(6);
	} while ((!ezIsButtonPushed(6)));
	/* end while main loop */

	// Disable MDMA
	Start_MDMA = false;

	end_frame = Video_Frame_Counter;			//  (small probability of being off by one)

	// some statistics
	printf("\nRecorded %d Frames ", lNumFrames);
	printf("of %d Video Frames\n", end_frame-start_frame);
	printf("Average Frame Rate of %d Frames/sec\n", 30* lNumFrames/(end_frame-start_frame));

#ifdef EXTRA_DEBUG_INFO
	printf("Slowest Frame encoded in %llu cycles, taking %llu msec\n", max_frame_cycles, max_frame_cycles/(unsigned long)(Core_Clock *1000));
	printf("equivalent to %lu cyles/pixel\n", max_frame_cycles/((Input_Width) * (Input_Height)));
	printf("Fastest Frame encoded in %llu cycles, taking %llu msec\n", min_frame_cycles, min_frame_cycles/(unsigned long)(Core_Clock *1000));
	printf("equivalent to %lu cyles/pixel\n", min_frame_cycles/((Input_Width) * (Input_Height)));
	printf("Encoding with an average of %.0f cycles, equivalent to %.2f cycles/pixel\n",cycle_sum/lNumFrames,cycle_sum/lNumFrames/(Input_Height*Input_Width));

	printf("Slowest Frame written %d bytes over USB in %llu cycles, taking %llu msec\n", max_usb_bytes, max_usb_cycles, max_usb_cycles/(unsigned long)(Core_Clock *1000));
	printf("equivalent to %lu kByte/sec\n", max_usb_bytes*(unsigned long)(Core_Clock *1000)/max_usb_cycles);
	printf("Fastest Frame written %d bytes over USB in %llu cycles, taking %llu msec\n", min_usb_bytes, min_usb_cycles, min_usb_cycles/(unsigned long)(Core_Clock *1000));
	printf("equivalent to %lu kByte/sec\n", min_usb_bytes*(unsigned long)(Core_Clock *1000)/min_usb_cycles);
#endif // #ifdef EXTRA_DEBUG_INFO

	/************************************/
	/* FINALISE AND DESTROY ENCODER		*/
	/************************************/
	printf("\nFinished encoding %d frames.\n", lNumFrames);
	printf("Writing AVI index table...\n");

	// Close the AVI stream
	lResult = MJPEG_AVI_CloseStreamWrite(lStreamHandle);
	if(lResult == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot close MJPEG AVI encoder stream\n");
		return CODEC_ALGORITHM_ERROR;
	}

	// Close the output file
	lResult = MJPEG_AVI_CloseFileWrite(lStreamFileOutHandle);
	if(lResult == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot close MJPEG AVI encoder file\n");
	}
	// Free and destroy used resources
	JPEG_Encoder_DELETE(lJpegEnc);
    JPEG_MemAlloc_DELETE(StreamBuffer_Obj);

	printf("***  MJPEG Conversion successful ***\n");
  	return CODEC_SUCCESS;
}

⌨️ 快捷键说明

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