예제 #1
0
mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
	mblk_t *m=NULL;
	struct stat statbuf;
	uint8_t *jpgbuf;
#if !defined(_MSC_VER)
	int fd=open(jpgpath,O_RDONLY);
#else
	int fd=_open(jpgpath,O_RDONLY);
#endif
	if (fd!=-1){
		fstat(fd,&statbuf);
		jpgbuf=(uint8_t*)alloca(statbuf.st_size);
#if !defined(_MSC_VER)
		read(fd,jpgbuf,statbuf.st_size);
#else
		_read(fd,jpgbuf,statbuf.st_size);
#endif
		m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize);
	}else{
		ms_error("Cannot load %s",jpgpath);
	}
	return m;
}
예제 #2
0
static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){
#ifndef NO_FFMPEG
	AVCodecContext av_context;
	int got_picture=0;
	AVFrame orig;
	mblk_t *ret;
	struct SwsContext *sws_ctx;
	AVPacket pkt;
	MSPicture dest;
	AVCodec *codec=avcodec_find_decoder(CODEC_ID_MJPEG);

	if (codec==NULL){
		ms_error("Could not find MJPEG decoder in ffmpeg.");
		return NULL;
	}

	avcodec_get_context_defaults(&av_context);
	if (avcodec_open(&av_context,codec)<0){
		ms_error("jpeg2yuv: avcodec_open failed");
		return NULL;
	}
	av_init_packet(&pkt);
	pkt.data=jpgbuf;
	pkt.size=bufsize;

	if (avcodec_decode_video2(&av_context,&orig,&got_picture,&pkt) < 0) {
		ms_error("jpeg2yuv: avcodec_decode_video failed");
		avcodec_close(&av_context);
		return NULL;
	}
	ret=ms_yuv_buf_alloc(&dest, reqsize->width,reqsize->height);
	/* not using SWS_FAST_BILINEAR because it doesn't play well with
	 * av_context.pix_fmt set to PIX_FMT_YUVJ420P by jpeg decoder */
	sws_ctx=sws_getContext(av_context.width,av_context.height,av_context.pix_fmt,
		reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_BILINEAR,
                NULL, NULL, NULL);
	if (sws_ctx==NULL) {
		ms_error("jpeg2yuv: ms_sws_getContext() failed.");
		avcodec_close(&av_context);
		freemsg(ret);
		return NULL;
	}

#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0)	
	if (sws_scale(sws_ctx,(const uint8_t* const *)orig.data,orig.linesize,0,av_context.height,dest.planes,dest.strides)<0){
#else
	if (sws_scale(sws_ctx,(uint8_t**)orig.data,orig.linesize,0,av_context.height,dest.planes,dest.strides)<0){
#endif
		ms_error("jpeg2yuv: ms_sws_scale() failed.");
		sws_freeContext(sws_ctx);
		avcodec_close(&av_context);
		freemsg(ret);
		return NULL;
	}
	sws_freeContext(sws_ctx);
	avcodec_close(&av_context);
	return ret;
#elif TARGET_OS_IPHONE
	MSPicture dest;
	CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, jpgbuf, bufsize, NULL);
	// use the data provider to get a CGImage; release the data provider
	CGImageRef image = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, FALSE, 
						kCGRenderingIntentDefault);
						CGDataProviderRelease(dataProvider);
	reqsize->width = CGImageGetWidth(image);
	reqsize->height = CGImageGetHeight(image);

	uint8_t* tmp = (uint8_t*) malloc(reqsize->width * reqsize->height * 4);
	mblk_t* ret=ms_yuv_buf_alloc(&dest, reqsize->width, reqsize->height);
	CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
	CGContextRef imageContext =
	CGBitmapContextCreate(tmp, reqsize->width, reqsize->height, 8, reqsize->width*4, colourSpace, kCGImageAlphaNoneSkipLast);
	CGColorSpaceRelease(colourSpace);
	// draw the image to the context, release it
	CGContextDrawImage(imageContext, CGRectMake(0, 0, reqsize->width, reqsize->height), image);
	CGImageRelease(image);

	/* convert tmp/RGB -> ret/YUV */
	for(int y=0; y<reqsize->height; y++) {
		for(int x=0; x<reqsize->width; x++) {
			uint8_t r = tmp[y * reqsize->width * 4 + x * 4 + 0];
			uint8_t g = tmp[y * reqsize->width * 4 + x * 4 + 1];
			uint8_t b = tmp[y * reqsize->width * 4 + x * 4 + 2];

			// Y
			*dest.planes[0]++ = (uint8_t)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);		

			// U/V subsampling
			if ((y % 2==0) && (x%2==0)) {
				uint32_t r32=0, g32=0, b32=0;
				for(int i=0; i<2; i++) {
					for(int j=0; j<2; j++) {
						r32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 0];
						g32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 1];
						b32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 2];
					}
				}
				r32 = (uint32_t)(r32 * 0.25f); g32 = (uint32_t)(g32 * 0.25f); b32 = (uint32_t) (b32 * 0.25f);

				// U
				*dest.planes[1]++ = (uint8_t)(-(0.148 * r32) - (0.291 * g32) + (0.439 * b32) + 128);
				// V
				*dest.planes[2]++ = (uint8_t)((0.439 * r32) - (0.368 * g32) - (0.071 * b32) + 128);
			}
		}
	}
	free(tmp);
	return ret;
#else
	return NULL;
#endif
}




mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
#if defined(WIN32)
	mblk_t *m=NULL;
	DWORD st_sizel;
	DWORD st_sizeh;
	uint8_t *jpgbuf;
	DWORD err;
	HANDLE fd;
	
#ifdef UNICODE
	WCHAR wUnicode[1024];
	MultiByteToWideChar(CP_UTF8, 0, jpgpath, -1, wUnicode, 1024);
	fd = CreateFile(wUnicode, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, 0, NULL);
#else
	fd = CreateFile(jpgpath, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, 0, NULL);
#endif
	if (fd==INVALID_HANDLE_VALUE){
		ms_error("Failed to open %s",jpgpath);
		return NULL;
	}
	st_sizel=0;
	st_sizeh=0;
	st_sizel = GetFileSize(fd, &st_sizeh);
	if (st_sizeh>0 || st_sizel<=0)
	{
		CloseHandle(fd);
		ms_error("Can't load file %s",jpgpath);
		return NULL;
	}
	jpgbuf=(uint8_t*)ms_malloc0(st_sizel);
	if (jpgbuf==NULL)
	{
		CloseHandle(fd);
		ms_error("Cannot allocate buffer for %s",jpgpath);
		return NULL;
	}
	err=0;
	ReadFile(fd, jpgbuf, st_sizel, &err, NULL) ;            
	
	if (err!=st_sizel){
		  ms_error("Could not read as much as wanted !");
	}
	m=jpeg2yuv(jpgbuf,st_sizel,reqsize);
	ms_free(jpgbuf);
	if (m==NULL)
	{
		CloseHandle(fd);
		ms_error("Cannot load image from buffer for %s",jpgpath);
		return NULL;
	}
	CloseHandle(fd);
	return m;
#else
	mblk_t *m=NULL;
	struct stat statbuf;
	uint8_t *jpgbuf;
	int err;
	int fd=open(jpgpath,O_RDONLY);

	if (fd!=-1){
		fstat(fd,&statbuf);
		if (statbuf.st_size<=0)
		{
			close(fd);
			ms_error("Cannot load %s",jpgpath);
			return NULL;
		}
		jpgbuf=(uint8_t*)ms_malloc0(statbuf.st_size + FF_INPUT_BUFFER_PADDING_SIZE);
		if (jpgbuf==NULL)
		{
			close(fd);
			ms_error("Cannot allocate buffer for %s",jpgpath);
			return NULL;
		}
		err=read(fd,jpgbuf,statbuf.st_size);
		if (err!=statbuf.st_size){
			ms_error("Could not read as much as wanted: %i<>%li !",err,(long)statbuf.st_size);
		}
		m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize);
		ms_free(jpgbuf);
		if (m==NULL)
		{
			close(fd);
			ms_error("Cannot load image from buffer for %s",jpgpath);
			return NULL;
		}
	}else{
		ms_error("Cannot load %s",jpgpath);
		return NULL;
	}
	close(fd);
	return m;
#endif
}