Load JVM in a DLL - c++

I am loading JVM in a dll but it fails (indicated in the code where it fails.). I tried the same code in an exe and it works fine.
JavaVMInitArgs vm_args; /* JDK 1.1 VM initialization arguments */
JNIEnv *env;
JavaVMOption options;
options.optionString = "-Djava.class.path=C:\\Core\\bin\\otk-1.4.1-with-dependencies.jar";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = &options;
vm_args.ignoreUnrecognized = 0;
jvm_dll = LoadLibrary("C:\\Program Files\\Java\\jdk1.6.0_23\\jre\\bin\\server\\jvm.dll");
if(jvm_dll == NULL)
{
getManager()->log( "InitialiseJava::Can't Load JVM DLL.", HIGH_IMPORTANCE );
return false;
}
JNI_CreateJavaVM_ptr = (JNI_CreateJavaVM_func)GetProcAddress(jvm_dll, "JNI_CreateJavaVM");
if(JNI_CreateJavaVM_ptr == NULL)
{
getManager()->log( "InitialiseJava::Can't create JVM.", HIGH_IMPORTANCE );
return false;
}
int ret = JNI_CreateJavaVM_ptr(jvm, (void**)&env, &vm_args); // fails here
if(ret < 0)
{
getManager()->log( "InitialiseJava::Unable to call JVM.", HIGH_IMPORTANCE );
return false;
}
Please help.

Related

Passing SCSI commands over network

I want to share cdrom device over network.
On the client side I create root enumerated device (scsi bus). On the server side (where cdrom device resides) I replace device stack's FDO with my own (in other words - cdrom.sys is replaced by another driver).
Requests are redirected from client to server using windows sockets.
The format of data transferred over network (from client to server): USER_HEADER, USER_SCSI_REQUEST_BLOCK, [data to be transferred to device]
The format of data transferred over network (from server to client):
USER_HEADER, USER_SCSI_REQUEST_BLOCK, [data to be transferred from device / sense data]
The structures are defined as follows:
struct USER_HEADER
{
ULONG Id;
ULONG Length;
ULONG MajorFunction;
ULONG MinorFunction;
ULONG IoControlCode;
ULONG InputBufferLength;
ULONG OutputBufferLength;
NTSTATUS Status;
ULONG Information;
};
struct USER_SCSI_REQUEST_BLOCK
{
UCHAR Function;
UCHAR SrbStatus;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR QueueTag;
UCHAR QueueAction;
UCHAR CdbLength;
UCHAR SenseInfoBufferLength;
ULONG SrbFlags;
ULONG DataTransferLength;
ULONG TimeOutValue;
ULONG QueueSortKey;
UCHAR Cdb[16];
};
Client side code to pack and unpack requests sent from cdrom.sys:
PVOID GetBuffer(MDL *pSourceMdl, MDL *pTargetMdl, PVOID pBuffer, ULONG Length, BOOLEAN *pUnmap)
{
PVOID pBuffer2;
if (pSourceMdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
{
pBuffer2 = (UCHAR*)pSourceMdl->MappedSystemVa + ((UCHAR*)pBuffer - ((UCHAR*)pSourceMdl->StartVa + pSourceMdl->ByteOffset));
*pUnmap = FALSE;
}
else
{
IoBuildPartialMdl(pSourceMdl, pTargetMdl, pBuffer, Length);
pBuffer2 = MmMapLockedPagesSpecifyCache(pTargetMdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority);
*pUnmap = TRUE;
}
return pBuffer2;
}
void PackRequest(IRP *pIrp, USER_HEADER *pUserHeader, STORAGE_EXTENSION *pStorageExtension)
{
BOOLEAN Unmap;
PVOID pBuffer;
IO_STACK_LOCATION *pStack;
USER_SCSI_REQUEST_BLOCK *pUserSrb;
SCSI_REQUEST_BLOCK *pSrb;
pStack = IoGetCurrentIrpStackLocation(pIrp);
pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pStorageExtension->Id;
pUserHeader->Id = pStorageExtension->Id;
++pStorageExtension->Id;
pUserHeader->Status = 0;
pUserHeader->Information = 0;
pUserHeader->MajorFunction = pStack->MajorFunction;
pUserHeader->MinorFunction = pStack->MinorFunction;
if (pStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
{
pUserHeader->IoControlCode = 0;
pUserHeader->InputBufferLength = 0;
pUserHeader->OutputBufferLength = 0;
pUserHeader->Length = sizeof(USER_HEADER) + sizeof(USER_SCSI_REQUEST_BLOCK);
pUserSrb = (USER_SCSI_REQUEST_BLOCK*)((UCHAR*)pUserHeader + sizeof(USER_HEADER));
pSrb = pStack->Parameters.Scsi.Srb;
pUserSrb->Function = pSrb->Function;
pUserSrb->SrbStatus = pSrb->SrbStatus;
pUserSrb->ScsiStatus = pSrb->ScsiStatus;
pUserSrb->PathId = pSrb->PathId;
pUserSrb->TargetId = pSrb->TargetId;
pUserSrb->Lun = pSrb->Lun;
pUserSrb->QueueTag = pSrb->QueueTag;
pUserSrb->QueueAction = pSrb->QueueAction;
pUserSrb->CdbLength = pSrb->CdbLength;
pUserSrb->SenseInfoBufferLength = pSrb->SenseInfoBufferLength;
pUserSrb->SrbFlags = pSrb->SrbFlags;
pUserSrb->DataTransferLength = pSrb->DataTransferLength;
pUserSrb->TimeOutValue = pSrb->TimeOutValue;
if ((pSrb->DataTransferLength) && (pSrb->SrbFlags & SRB_FLAGS_DATA_OUT))
{
pBuffer = GetBuffer(pIrp->MdlAddress, pStorageExtension->pMdl, pSrb->DataBuffer, pSrb->DataTransferLength, &Unmap);
memcpy((UCHAR*)pUserSrb + sizeof(USER_SCSI_REQUEST_BLOCK), pBuffer, pSrb->DataTransferLength);
if (Unmap) MmUnmapLockedPages(pBuffer, pStorageExtension->pMdl);
pUserHeader->Length += pSrb->DataTransferLength;
}
pUserSrb->QueueSortKey = pSrb->QueueSortKey;
memcpy(pUserSrb->Cdb, pSrb->Cdb, sizeof(pSrb->Cdb));
}
else
{
pUserHeader->IoControlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
pUserHeader->InputBufferLength = pStack->Parameters.DeviceIoControl.InputBufferLength;
pUserHeader->OutputBufferLength = pStack->Parameters.DeviceIoControl.OutputBufferLength;
pUserHeader->Length = sizeof(USER_HEADER);
if ((pUserHeader->IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY) ||
(pUserHeader->IoControlCode == IOCTL_STORAGE_ENABLE_IDLE_POWER))
{
pUserHeader->Length += pUserHeader->InputBufferLength;
memcpy((UCHAR*)pUserHeader + sizeof(USER_HEADER), pIrp->AssociatedIrp.SystemBuffer, pUserHeader->InputBufferLength);
}
else if ((pUserHeader->IoControlCode != IOCTL_STORAGE_POWER_ACTIVE) &&
(pUserHeader->IoControlCode != IOCTL_SCSI_GET_ADDRESS))
{
__debugbreak();
}
}
}
void UnpackRequest(USER_HEADER *pUserHeader, IRP *pIrp, STORAGE_EXTENSION *pStorageExtension)
{
BOOLEAN Unmap;
PVOID pBuffer;
IO_STACK_LOCATION *pStack;
USER_SCSI_REQUEST_BLOCK *pUserSrb;
SCSI_REQUEST_BLOCK *pSrb;
pStack = IoGetCurrentIrpStackLocation(pIrp);
if (pUserHeader->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
{
pUserSrb = (USER_SCSI_REQUEST_BLOCK*)((UCHAR*)pUserHeader + sizeof(USER_HEADER));
pSrb = pStack->Parameters.Scsi.Srb;
pSrb->SrbStatus = pUserSrb->SrbStatus;
pSrb->ScsiStatus = pUserSrb->ScsiStatus;
pSrb->SenseInfoBufferLength = pUserSrb->SenseInfoBufferLength;
pSrb->DataTransferLength = pUserSrb->DataTransferLength;
if (NT_SUCCESS(pUserHeader->Status))
{
if ((pUserSrb->DataTransferLength) && (pUserSrb->SrbFlags & SRB_FLAGS_DATA_IN))
{
pBuffer = GetBuffer(pIrp->MdlAddress, pStorageExtension->pMdl, pSrb->DataBuffer, pUserSrb->DataTransferLength, &Unmap);
memcpy(pBuffer, (UCHAR*)pUserSrb + sizeof(USER_SCSI_REQUEST_BLOCK), pUserSrb->DataTransferLength);
if (Unmap) MmUnmapLockedPages(pBuffer, pStorageExtension->pMdl);
}
else
{
if (pUserSrb->Function == SRB_FUNCTION_CLAIM_DEVICE) pSrb->DataBuffer = pStack->DeviceObject;
}
}
else
{
if ((pUserSrb->SenseInfoBufferLength) && (pUserSrb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID))
{
memcpy(pSrb->SenseInfoBuffer, (UCHAR*)pUserSrb + sizeof(USER_SCSI_REQUEST_BLOCK), pUserSrb->SenseInfoBufferLength);
}
}
}
else
{
if (NT_SUCCESS(pUserHeader->Status))
{
if ((pUserHeader->IoControlCode == IOCTL_SCSI_GET_ADDRESS) ||
(pUserHeader->IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY))
{
memcpy(pIrp->AssociatedIrp.SystemBuffer, (UCHAR*)pUserHeader + sizeof(USER_HEADER), pUserHeader->Information);
}
}
}
}
Server side code to allocate request and IO completion routine:
NTSTATUS AllocateRequest(DEVICE_EXTENSION *pDeviceExtension, IRP *pIrp, IRP **ppIrp2)
{
IRP *pIrp2;
PVOID pBuffer;
NTSTATUS Status;
IO_STACK_LOCATION *pStack;
SCSI_REQUEST_BLOCK *pSrb;
USER_SCSI_REQUEST_BLOCK *pUserSrb;
DEVICE_OBJECT *pDeviceObject;
USER_HEADER *pUserHeader;
pUserHeader = (USER_HEADER*)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
pDeviceObject = pDeviceExtension->pLowerDeviceObject;
pIrp2 = IoAllocateIrp(pDeviceObject->StackSize, FALSE);
if (pIrp2)
{
pStack = IoGetNextIrpStackLocation(pIrp2);
pStack->DeviceObject = pDeviceObject;
pIrp2->Tail.Overlay.Thread = PsGetCurrentThread();
pStack->MajorFunction = pUserHeader->MajorFunction;
pStack->MinorFunction = pUserHeader->MinorFunction;
if (pUserHeader->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
{
pUserSrb = (USER_SCSI_REQUEST_BLOCK*)((UCHAR*)pUserHeader + sizeof(USER_HEADER));
pSrb = (SCSI_REQUEST_BLOCK*)((UCHAR*)pUserSrb + (sizeof(USER_SCSI_REQUEST_BLOCK) + pUserSrb->DataTransferLength + pUserSrb->SenseInfoBufferLength));
pSrb->Length = sizeof(SCSI_REQUEST_BLOCK);
pSrb->Function = pUserSrb->Function;
pSrb->SrbStatus = pUserSrb->SrbStatus;
pSrb->ScsiStatus = pUserSrb->ScsiStatus;
pSrb->PathId = pUserSrb->PathId;
pSrb->TargetId = pUserSrb->TargetId;
pSrb->Lun = pUserSrb->Lun;
pSrb->QueueTag = pUserSrb->QueueTag;
pSrb->QueueAction = pUserSrb->QueueAction;
pSrb->CdbLength = pUserSrb->CdbLength;
pSrb->SenseInfoBufferLength = pUserSrb->SenseInfoBufferLength;
pSrb->SrbFlags = pUserSrb->SrbFlags;
pSrb->DataTransferLength = pUserSrb->DataTransferLength;
pSrb->TimeOutValue = pUserSrb->TimeOutValue;
if (pUserSrb->DataTransferLength)
{
pSrb->DataBuffer = (UCHAR*)pIrp->MdlAddress->StartVa + pIrp->MdlAddress->ByteOffset + (sizeof(USER_HEADER) + sizeof(USER_SCSI_REQUEST_BLOCK));
IoBuildPartialMdl(pIrp->MdlAddress, pDeviceExtension->pMdl, pSrb->DataBuffer, pUserSrb->DataTransferLength);
pIrp2->MdlAddress = pDeviceExtension->pMdl;
}
else pSrb->DataBuffer = NULL;
if (pUserSrb->SenseInfoBufferLength)
{
pSrb->SenseInfoBuffer = (UCHAR*)pUserSrb + (sizeof(USER_SCSI_REQUEST_BLOCK) + pUserSrb->DataTransferLength);
}
else pSrb->SenseInfoBuffer = NULL;
pSrb->NextSrb = NULL;
pSrb->OriginalRequest = pIrp2;
pSrb->SrbExtension = NULL;
pSrb->QueueSortKey = pUserSrb->QueueSortKey;
memcpy(pSrb->Cdb, pUserSrb->Cdb, sizeof(pSrb->Cdb));
pStack->Parameters.Scsi.Srb = pSrb;
}
else
{
pStack->Parameters.DeviceIoControl.IoControlCode = pUserHeader->IoControlCode;
pBuffer = (UCHAR*)pUserHeader + sizeof(USER_HEADER);
if (pUserHeader->IoControlCode == IOCTL_SCSI_GET_ADDRESS)
{
pStack->Parameters.DeviceIoControl.OutputBufferLength = pUserHeader->OutputBufferLength;
pIrp2->AssociatedIrp.SystemBuffer = pBuffer;
}
else if (pUserHeader->IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY)
{
pStack->Parameters.DeviceIoControl.InputBufferLength = pUserHeader->InputBufferLength;
pStack->Parameters.DeviceIoControl.OutputBufferLength = pUserHeader->OutputBufferLength;
pIrp2->AssociatedIrp.SystemBuffer = pBuffer;
}
else if (pUserHeader->IoControlCode == IOCTL_STORAGE_ENABLE_IDLE_POWER)
{
pStack->Parameters.DeviceIoControl.InputBufferLength = pUserHeader->InputBufferLength;
pIrp2->AssociatedIrp.SystemBuffer = pBuffer;
}
}
*ppIrp2 = pIrp2;
Status = STATUS_SUCCESS;
}
else Status = STATUS_INSUFFICIENT_RESOURCES;
return Status;
}
NTSTATUS IoCompletionRoutine3(DEVICE_OBJECT *pDeviceObject, IRP *pIrp2, void *pContext)
{
IRP *pIrp;
USER_HEADER *pUserHeader;
DEVICE_EXTENSION *pDeviceExtension;
USER_SCSI_REQUEST_BLOCK *pUserSrb;
SCSI_REQUEST_BLOCK *pSrb;
pDeviceExtension = (DEVICE_EXTENSION*)pIrp2->Tail.Overlay.DriverContext[0];
pIrp = (IRP*)pIrp2->Tail.Overlay.DriverContext[1];
pUserHeader = (USER_HEADER*)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
pUserHeader->Status = pIrp2->IoStatus.Status;
pUserHeader->Information = pIrp2->IoStatus.Information;
if (pUserHeader->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
{
pUserSrb = (USER_SCSI_REQUEST_BLOCK*)((UCHAR*)pUserHeader + sizeof(USER_HEADER));
pSrb = (SCSI_REQUEST_BLOCK*)((UCHAR*)pUserSrb + (sizeof(USER_SCSI_REQUEST_BLOCK) + pUserSrb->DataTransferLength + pUserSrb->SenseInfoBufferLength));
pUserSrb->SrbStatus = pSrb->SrbStatus;
pUserSrb->ScsiStatus = pSrb->ScsiStatus;
pUserSrb->SenseInfoBufferLength = pSrb->SenseInfoBufferLength;
pUserSrb->DataTransferLength = pSrb->DataTransferLength;
pUserHeader->Length = sizeof(USER_HEADER) + sizeof(USER_SCSI_REQUEST_BLOCK);
if (NT_SUCCESS(pUserHeader->Status))
{
if ((pSrb->DataTransferLength) && (pSrb->SrbFlags & SRB_FLAGS_DATA_IN))
{
pUserHeader->Length += pUserSrb->DataTransferLength;
}
}
else
{
if ((pSrb->SenseInfoBufferLength) && (pSrb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID))
{
pUserHeader->Length += pUserSrb->SenseInfoBufferLength;
if (pSrb->DataTransferLength)
{
memmove((UCHAR*)pUserSrb + sizeof(USER_SCSI_REQUEST_BLOCK), (UCHAR*)pUserSrb + (sizeof(USER_SCSI_REQUEST_BLOCK) + pUserSrb->DataTransferLength), pUserSrb->SenseInfoBufferLength);
}
}
}
}
else
{
pUserHeader->Length = sizeof(USER_HEADER);
if (pUserHeader->IoControlCode == IOCTL_SCSI_GET_ADDRESS)
{
pUserHeader->Length += pUserHeader->Information;
}
else if (pUserHeader->IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY)
{
pUserHeader->Length += pUserHeader->Information;
}
}
IoFreeIrp(pIrp2);
CompleteRequest(pIrp, STATUS_SUCCESS, 0);
IoReleaseRemoveLock(&pDeviceExtension->RemoveLock, pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
Everything runs fine (requests are passed between server and client, no BSOD, etc), but cdrom device just does not show up on the client side. I thought it might be something with srb data buffer access. Can you help me to figure it out? Thank you.

How to obtain the GLXContext in SDL

Is there a way to obtain the GLXContext associated with a window, without calling glXGetCurrentContext()?
Cast the SDL_GLContext you get from SDL_GL_CreateContext() to GLXContext:
SDL_GLContext
X11_GL_CreateContext(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
Display *display = data->videodata->display;
int screen =
((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen;
XWindowAttributes xattr;
XVisualInfo v, *vinfo;
int n;
GLXContext context = NULL, share_context;
if (_this->gl_config.share_with_current_context) {
share_context = (GLXContext)SDL_GL_GetCurrentContext();
} else {
share_context = NULL;
}
/* We do this to create a clean separation between X and GLX errors. */
X11_XSync(display, False);
errorHandlerOperation = "create GL context";
errorBase = _this->gl_data->errorBase;
errorCode = Success;
handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
X11_XGetWindowAttributes(display, data->xwindow, &xattr);
v.screen = screen;
v.visualid = X11_XVisualIDFromVisual(xattr.visual);
vinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
if (vinfo) {
if (_this->gl_config.major_version < 3 &&
_this->gl_config.profile_mask == 0 &&
_this->gl_config.flags == 0) {
/* Create legacy context */
context =
_this->gl_data->glXCreateContext(display, vinfo, share_context, True);
} else {
/* max 10 attributes plus terminator */
int attribs[11] = {
GLX_CONTEXT_MAJOR_VERSION_ARB,
_this->gl_config.major_version,
GLX_CONTEXT_MINOR_VERSION_ARB,
_this->gl_config.minor_version,
0
};
int iattr = 4;
/* SDL profile bits match GLX profile bits */
if( _this->gl_config.profile_mask != 0 ) {
attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
attribs[iattr++] = _this->gl_config.profile_mask;
}
/* SDL flags match GLX flags */
if( _this->gl_config.flags != 0 ) {
attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
attribs[iattr++] = _this->gl_config.flags;
}
/* only set if glx extension is available */
if( _this->gl_data->HAS_GLX_ARB_context_flush_control ) {
attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
attribs[iattr++] =
_this->gl_config.release_behavior ?
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
}
attribs[iattr++] = 0;
/* Get a pointer to the context creation function for GL 3.0 */
if (!_this->gl_data->glXCreateContextAttribsARB) {
SDL_SetError("OpenGL 3.0 and later are not supported by this system");
} else {
int glxAttribs[64];
/* Create a GL 3.x context */
GLXFBConfig *framebuffer_config = NULL;
int fbcount = 0;
X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE);
if (!_this->gl_data->glXChooseFBConfig
|| !(framebuffer_config =
_this->gl_data->glXChooseFBConfig(display,
DefaultScreen(display), glxAttribs,
&fbcount))) {
SDL_SetError("No good framebuffers found. OpenGL 3.0 and later unavailable");
} else {
context = _this->gl_data->glXCreateContextAttribsARB(display,
framebuffer_config[0],
share_context, True, attribs);
}
}
}
X11_XFree(vinfo);
}
X11_XSync(display, False);
X11_XSetErrorHandler(handler);
if (!context) {
if (errorCode == Success) {
SDL_SetError("Could not create GL context");
}
return NULL;
}
if (X11_GL_MakeCurrent(_this, window, context) < 0) {
X11_GL_DeleteContext(_this, context);
return NULL;
}
return context;
}
SDL2 does not otherwise store the context anywhere.

C++ - applying filter in ffmpeg

I'm trying to deinterlace a frame using ffmpeg (latest release). Related with this question, I can get the filter I want using this sentence:
AVFilter *filter = avfilter_get_by_name("yadif");
After that, I open the filter context as:
AVFilterContext *filter_ctx;
avfilter_open(&filter_ctx, filter, NULL);
My first question is about this function. Visual Studio warns me about avfilter_open is deprecated. Which is the alternative?
After that, I do:
avfilter_init_str(filter_ctx, "yadif=1:-1");
And always fails. I've tried "1:-1" instead "yadif=1:-1", but always fails too, what parameter I should use?
EDIT: A value of "1" or "2", for example, it works. Debuging it, I found that with one of this values, the function uses mode=1 or mode=2. The explanation of those values is in this link.
Then, I have a AVFrame *frame that is the frame I want to deinterlace. When the last sentence work, I'll have the filter and his context init. How do I apply this filter to my frame?
Thanks for your help.
I undertsnad your question is over a year now but recently I had to work with interlaced DVB-TS streams so I might be able to help anybody else coming across this subject.
These snippets are from a finished player I've written
Initialise the filter graph:
void VideoManager::init_filter_graph(AVFrame *frame) {
if (filter_initialised) return;
int result;
AVFilter *buffer_src = avfilter_get_by_name("buffer");
AVFilter *buffer_sink = avfilter_get_by_name("buffersink");
AVFilterInOut *inputs = avfilter_inout_alloc();
AVFilterInOut *outputs = avfilter_inout_alloc();
AVCodecContext *ctx = ffmpeg.vid_stream.context;
char args[512];
int frame_fix = 0; // fix bad width on some streams
if (frame->width < 704) frame_fix = 2;
else if (frame->width > 704) frame_fix = -16;
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
frame->width + frame_fix,
frame->height,
frame->format,// ctx->pix_fmt,
ctx->time_base.num,
ctx->time_base.den,
ctx->sample_aspect_ratio.num,
ctx->sample_aspect_ratio.den);
const char *description = "yadif=1:-1:0";
LOGD("Filter: %s - Settings: %s", description, args);
filter_graph = avfilter_graph_alloc();
result = avfilter_graph_create_filter(&filter_src_ctx, buffer_src, "in", args, NULL, filter_graph);
if (result < 0) {
LOGI("Filter graph - Unable to create buffer source");
return;
}
AVBufferSinkParams *params = av_buffersink_params_alloc();
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
params->pixel_fmts = pix_fmts;
result = avfilter_graph_create_filter(&filter_sink_ctx, buffer_sink, "out", NULL, params, filter_graph);
av_free(params);
if (result < 0) {
LOGI("Filter graph - Unable to create buffer sink");
return;
}
inputs->name = av_strdup("out");
inputs->filter_ctx = filter_sink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
outputs->name = av_strdup("in");
outputs->filter_ctx = filter_src_ctx;
outputs->pad_idx = 0;
outputs->next = NULL;
result = avfilter_graph_parse_ptr(filter_graph, description, &inputs, &outputs, NULL);
if (result < 0) LOGI("avfilter_graph_parse_ptr ERROR");
result = avfilter_graph_config(filter_graph, NULL);
if (result < 0) LOGI("avfilter_graph_config ERROR");
filter_initialised = true;
}
When processing the video packets from the stream, check if it is an interlaced frame and send the frame off to the filter. The filter will then return the de-interlaced frames back to you.
void FFMPEG::process_video_packet(AVPacket *pkt) {
int got;
AVFrame *frame = vid_stream.frame;
avcodec_decode_video2(vid_stream.context, frame, &got, pkt);
if (got) {
if (!frame->interlaced_frame) { // not interlaced
Video.add_av_frame(frame, 0);
} else {
if (!Video.filter_initialised) {
Video.init_filter_graph(frame);
}
av_buffersrc_add_frame_flags(Video.filter_src_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF);
int c = 0;
while (true) {
AVFrame *filter_frame = ffmpeg.vid_stream.filter_frame;
int result = av_buffersink_get_frame(Video.filter_sink_ctx, filter_frame);
if (result == AVERROR(EAGAIN) || result == AVERROR(AVERROR_EOF)) break;
if (result < 0) return;
Video.add_av_frame(filter_frame, c++);
av_frame_unref(filter_frame);
}
}
}
}
Hope this helps anyone because finding information about ffmpeg is tough going.

Creating VHD files with the VirtualDisk API

I'm trying to use a VSS snapshot as the source for CreateVirtualDisk(). Environment/tools are C++ VS2008SP1 and 7.1 SDK on W7x64Ultimate
[Edited]
This works on Windows 7 x64
BOOL CreateVHD_Fixed(PCWSTR pszVhdPath, ULONG sizeInMB)
{
BOOL bRet = FALSE;
HANDLE hvhd;
CREATE_VIRTUAL_DISK_PARAMETERS params;
VIRTUAL_DISK_ACCESS_MASK mask;
VIRTUAL_STORAGE_TYPE vst =
{
VIRTUAL_STORAGE_TYPE_DEVICE_VHD,
VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT
};
wprintf(L"CreateVHD_Fixed %s, size (MB) %d\n", pszVhdPath, sizeInMB);
params.Version1.UniqueId = GUID_NULL;
params.Version1.BlockSizeInBytes = 0;
params.Version1.MaximumSize = sizeInMB * 1024 * 1024;
params.Version1.ParentPath = NULL;
params.Version1.SourcePath = NULL;
params.Version1.SectorSizeInBytes = 512;
params.Version = CREATE_VIRTUAL_DISK_VERSION_1;
mask = VIRTUAL_DISK_ACCESS_CREATE;
DWORD ret = CreateVirtualDisk(&vst,
pszVhdPath,
mask,
NULL,
// To create a dynamic disk, use CREATE_VIRTUAL_DISK_FLAG_NONE instead.
CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION,
0,
&params,
NULL,
&hvhd);
if (ret == ERROR_SUCCESS)
{
bRet = TRUE;
}
else
{
bRet = FALSE;
printf("failed to create vdisk...err 0x%x\n", ret);
PrintErrorMessage(GetLastError());
}
if (INVALID_HANDLE_VALUE != hvhd)
{
CloseHandle(hvhd);
}
return bRet;
}
[Edited] - now failing in a different way with ERROR_INVALID_PARAMETER. Parameters are below with a root path of "\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy64"
VIRTUAL_STORAGE_TYPE storageType =
{
VIRTUAL_STORAGE_TYPE_DEVICE_VHD,
// do not use any other GUID else you get an unknown provider error
VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT // **critical!**
};
VIRTUAL_DISK_ACCESS_MASK vdam = (VIRTUAL_DISK_ACCESS_MASK)(VIRTUAL_DISK_ACCESS_CREATE); // |VIRTUAL_DISK_ACCESS_WRITABLE|VIRTUAL_DISK_ACCESS_READ|VIRTUAL_DISK_ACCESS_GET_INFO);
CREATE_VIRTUAL_DISK_FLAG flags = CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION; // CREATE_VIRTUAL_DISK_FLAG_NONE;
CREATE_VIRTUAL_DISK_PARAMETERS parameters;
//
parameters.Version = CREATE_VIRTUAL_DISK_VERSION_1;
parameters.Version1.UniqueId = GUID_NULL;
parameters.Version1.MaximumSize = 0;
parameters.Version1.BlockSizeInBytes = CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE;
parameters.Version1.ParentPath = 0;
parameters.Version1.SourcePath = root.c_str();
parameters.Version1.SectorSizeInBytes = CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_SECTOR_SIZE;
ULONG ProviderSpecificFlags = 0;
HANDLE handle = 0;
dwRet = CreateVirtualDisk(&storageType,
_T("t:\\test.vhd"),
vdam,
NULL,
flags,
ProviderSpecificFlags,
&parameters,0,&handle);
Any ideas? The virtual disk API does not seem to have much example code.
Thx++
Jerry.
Jerry,
Use CreateVirtualDisk API to create a VHD or a differential VHD, make sure u send the right parameters. You have to specify the parent hard disk but not the source hard disk. Care must also be taken while using the flags.
Refer the links below:
"http://code.msdn.microsoft.com/windowshardware/CppVhdAPI-4412d182"
and
"http://code.msdn.microsoft.com/windowsdesktop/Virtual-hard-disk-03108ed3"

Can i call multiple times JNI_CreateJavaVM?

I´m Trying to launch two threads witch calls "DispFrontEnd" function
First thread ended OK, second failed to start jvm.. ??
tks
#include "jni.h"
#include <process.h>
#include "Stdafx.h"
//DISPATCH Thread Check
bool DispatchThreadCreated = FALSE;
if (DispatchThreadCreated == FALSE)
{
HANDLE hDispThread;
hDispThread = (HANDLE)_beginthread(DispFrontEnd,0,(void *)dispatchInputs);
if ((long)hDispThread == -1)
{
log.LogError("Thread DispFrontEnd Returned********BG ", (long)hDispThread);
log.LogError("errno", errno);
log.LogError("_doserrno", _doserrno);
}
else
{
logloc->LogMethod("Dispatch Thread CREATED");
DispatchThreadCreated= TRUE;
//Espera que a thread termine
WaitForSingleObject( hDispThread, INFINITE );
DispatchThreadCreated= FALSE; // 01_02_2010
logloc->LogMethod("Dispatch Thread ENDED");
}
}
if (DispatchThreadCreated == FALSE)
{
HANDLE hDispThread3;
logloc->LogMethod("3 : Dispatch Thread CREATED");
hDispThread3 = (HANDLE)_beginthread(DispFrontEnd,0,(void *)dispatchInputs);
if ((long)hDispThread3 == -1)
{
log.LogError("3 : Thread DispFrontEnd Returned********BG ", (long)hDispThread3);
log.LogError("errno", errno);
log.LogError("_doserrno", _doserrno);
}
else
{
logloc->LogMethod("3 : Dispatch Thread CREATED");
DispatchThreadCreated= TRUE;
//Espera que a thread termine
WaitForSingleObject( hDispThread3, INFINITE );
DispatchThreadCreated= FALSE; // 01_02_2010
logloc->LogMethod("3 : Dispatch Thread ENDED");
}
}
void DispFrontEnd(void * indArr)
{
JNIEnv *env;
JavaVM *jvm;
env = create_vm(&jvm); // return null on second call ???
}
JNIEnv* create_vm(JavaVM ** jvm) {
CString str;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options;
options.optionString = "-Djava.class.path=C:\\dispatch\\lib\\Run.jar;C:\\dispatch\\classes"; //Path to the java source code
vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates version 1.6
vm_args.nOptions = 1;
vm_args.options = &options;
vm_args.ignoreUnrecognized = 0;
int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
if(ret < 0)
{
env = NULL;
str.Format("ERROR! create JVM (%d)",ret); // show this on second call!! ?
logloc->LogMethod( str );
}
else
{
str.Format("JVM %x created Success!",env->GetVersion());
logloc->LogMethod( str );
}
return env;
}
Do you really have to start many JVM ? Could you use
jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args);
instead ?
The only thing I know is a native thread cannot attach two different JVM at the same time.