Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Regular Contributor
prathipa84
Posts: 55
Registered: ‎03-14-2012
My Device: RDJ21WW

Reg :video capture using camera_start_video_viewfinder()

Hello,

I am trying to capture the video frames using the method camea_start_video_viewfinder(),because need to capture the  raw frames. I have attached the code which i tried to capture and write it to a file. while playing that file, i got only some green images. not getting the proper frames. May i know anything i am doing wrong? what should I do?

 

static void videoviewfinder_callback(camera_handle_t handle, camera_buffer_t* buf, void* arg)
{
if (buf->frametype == CAMERA_FRAMETYPE_NV12)
{
static int frame_count = 1;
if (out == NULL)
out = fopen("/accounts/1000/shared/camera/filename1.nv12","wb");
int index = 0;

fprintf(stderr, "videoviewfinder_callback - width : %d,height : %d,frame_size : %Lu, frame_type : %d\n", buf->framedesc.nv12.width, buf->framedesc.nv12.height, buf->framesize, buf->frametype);
while(index < (int)buf->framedesc.nv12.width*buf->framedesc.nv12.height)
{
//int rc = write((int)out, &buf->framebuf[index], (size_t)buf->framedesc.nv12.width*buf->framedesc.nv12.height-index);
int rc = fwrite(buf->framebuf, 1, (buf->framedesc.nv12.width * buf->framedesc.nv12.height * 1.5),out);
qDebug() << "videoviewfinder_callback : rc :"<<rc;
frame_count++;
if (rc > 0)
{
index += rc;
}
else if (rc == -1)
{
if ((errno == EAGAIN) || (errno == EINTR))
continue;
break;
}
}
}
}

 

Thanks.

 

BlackBerry Development Advisor (Retired)
smacmartin
Posts: 499
Registered: ‎05-07-2012
My Device: developer

Re: Reg :video capture using camera_start_video_viewfinder()

I assume you've looked at the camera samples

http://supportforums.blackberry.com/t5/Native-Development/Camera-Sample-Code/td-p/1744325/highlight/...

 

I'd suggest first making the code more defensive and easier to debug.  I haven't had the opportunity to play with the camera sample or the camera functionality yet, but here are my early thoughts.

 

- how often is this routine called?   A qDebug() at the start might be useful.  (Are there multi-threading collisions?)

- qDebug() when the frametype is something else might help

- did out successfully open?   Adding check here would help

- does buf->framedesc.nv12.height and width change during the call?  (Hopefully not)

   Assigning to variables width and height would help clarify the code

   Assigning w * h to numPixels would reduce the number of multiplications and make the code more maintainable

 

- What is the magic number 1.5 -- presumably the 12 bits per pixel

- Is w * h divisible by 2?

- Is the intent to write w * h * 1.5 bytes to the file, and only loop (possibly infinitely) if you get an error?

- what is the size of the file when you are done?

  Does this match the #bytes written?

- Is it safe to ignore stride?

- Is it safe to ignore frameSize?

 

If you post more code, please use code blocks (the clipboard with the "C")

 

Stuart

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Reg :video capture using camera_start_video_viewfinder()

1. you will only be able to save a couple of frames per second due to flash write latencies.  That shouldn't be a problem though.  Your callback function will simply adapt to run at whatever rate it can keep up with and frames will be dropped accordingly.  At 1080p, for example, you will be writing approximately 3MB per frame, so your framerate is going to be somewhere in the low single digits (3fps max maybe?)

 

2. you are writing width*height*1.5 bytes to disk.  if you read up on the NV12 frame descriptors, you will find that subsequent horizontal scanlines are not contiguous in memory, but are separated by "stride" bytes.  so the correct way to write the full data out to disk is something like:

width = buf->framedesc.nv12.width;
height = buf->framedesc.nv12.height;
stride = buf->framedesc.nv12.stride;
uv_offset = buf->framedesc.nv12.uv_offset;  // if this is not present in 10.0.4, you can set it to height*stride for the time being.

// write out the Y plane and de-stride the scanlines
for (i=0; i<height; i++) {
    fwrite(&buf->framebuf[stride * i], width, out);
}
// then write out the UV plane
for (i=0; i<height/2; i++) {
    fwrite(&buf->framebuf[uv_offset + stride * i], width, out);
}

 3. about the "green frames".  how are you trying to open the file?  are you converting it to some viewable format later?  Whenever I have to dump NV12 frames for debugging, I usually write them out as .pgm files.  You just need to append a header before writing the data.  Try this:

char header[100];
int len = sprintf(header, "P5\n%d %d\n255\n", width, height*3/2);
fwrite(header, len, out);

Then you should be able to open the file in a .pgm viewer (I use one called ToyViewer on the mac).  It will look like a grayscale image of the scene (Y), and below it, a squashed ghost-ish image of the same scene representing the chroma values (UV).

 

4. in the code you posted, it looks like you are opening a single file for writing and then trying to append all frames to that one file?  I can't think of any sort of player or viewer that is going to be able to understand that.  I suggest you change your code to save one frame per file instead and just keep incrementing the counter in your filename.

 

 

5. what's your use case?  just curious.

 

 

Cheers,

Sean