Some more progress on the deinterlacing code.

pull/49/head
Kfir Itzhak 2012-02-09 12:33:54 +02:00
parent f27b424503
commit a6c7acd02a
3 changed files with 225 additions and 18 deletions

View File

@ -2943,11 +2943,11 @@ void Image::Deinterlace_4Field(const Image* next_image, unsigned int threshold)
{ {
/* Motion detection */ /* Motion detection */
for (unsigned int y = 1; y < height; y += 2) { for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width)); pcurrent = buffer + (y * width);
pncurrent = next_image->buffer + ((y * width)); pncurrent = next_image->buffer + (y * width);
pabove = buffer + (((y-1) * width)); pabove = buffer + ((y-1) * width);
pnabove = next_image->buffer + (((y-1) * width)); pnabove = next_image->buffer + ((y-1) * width);
pdelta = delta_buffer + (((y>>1) * width)); pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) { for (unsigned int x = 0; x < width; x++) {
*pdelta = abs(*pnabove++ - *pabove++); *pdelta = abs(*pnabove++ - *pabove++);
*pdelta |= abs(*pncurrent++ - *pcurrent++); *pdelta |= abs(*pncurrent++ - *pcurrent++);
@ -2957,10 +2957,10 @@ void Image::Deinterlace_4Field(const Image* next_image, unsigned int threshold)
/* Check if pixels meet threshold */ /* Check if pixels meet threshold */
for (unsigned int y = 1; y < (height-1); y += 2) { for (unsigned int y = 1; y < (height-1); y += 2) {
pcurrent = buffer + ((y * width)); pcurrent = buffer + (y * width);
pabove = buffer + (((y-1) * width)); pabove = buffer + ((y-1) * width);
pbelow = buffer + (((y+1) * width)); pbelow = buffer + ((y+1) * width);
pdelta = delta_buffer + (((y>>1) * width)); pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) { for (unsigned int x = 0; x < width; x++) {
if(*pdelta++ >= threshold) { if(*pdelta++ >= threshold) {
pcurrent[x] = (pabove[x] + pbelow[x]) >> 1; pcurrent[x] = (pabove[x] + pbelow[x]) >> 1;
@ -2970,14 +2970,212 @@ void Image::Deinterlace_4Field(const Image* next_image, unsigned int threshold)
/* Special case for the last line */ /* Special case for the last line */
pcurrent = buffer + ((height-1) * width); pcurrent = buffer + ((height-1) * width);
pabove = buffer + ((height-2) * width); pabove = buffer + ((height-2) * width);
pdelta = delta_buffer + ((((height>>1)-1) * width)); pdelta = delta_buffer + (((height>>1)-1) * width);
for (unsigned int x = 0; x < width; x++) { for (unsigned int x = 0; x < width; x++) {
if(*pdelta++ >= threshold) { if(*pdelta++ >= threshold) {
pcurrent[x] = pabove[x]; pcurrent[x] = pabove[x];
} }
} }
}
else if ( colours == ZM_COLOUR_RGB24 )
{
/* Motion detection */
if ( subpixelorder == ZM_SUBPIX_ORDER_BGR ) {
unsigned int b, g, r;
for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width) * 3);
pncurrent = next_image->buffer + ((y * width) * 3);
pabove = buffer + (((y-1) * width) * 3);
pnabove = next_image->buffer + (((y-1) * width) * 3);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
b = abs(*pnabove++ - *pabove++);
g = abs(*pnabove++ - *pabove++);
r = abs(*pnabove++ - *pabove++);
*pdelta = (r + r + b + g + g + g + g + g)>>3;
b = abs(*pncurrent++ - *pcurrent++);
g = abs(*pncurrent++ - *pcurrent++);
r = abs(*pncurrent++ - *pcurrent++);
*pdelta |= (r + r + b + g + g + g + g + g)>>3;
pdelta++;
}
}
} else {
unsigned int r, g, b;
for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width) * 3);
pncurrent = next_image->buffer + ((y * width) * 3);
pabove = buffer + (((y-1) * width) * 3);
pnabove = next_image->buffer + (((y-1) * width) * 3);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
r = abs(*pnabove++ - *pabove++);
g = abs(*pnabove++ - *pabove++);
b = abs(*pnabove++ - *pabove++);
*pdelta = (r + r + b + g + g + g + g + g)>>3;
r = abs(*pncurrent++ - *pcurrent++);
g = abs(*pncurrent++ - *pcurrent++);
b = abs(*pncurrent++ - *pcurrent++);
*pdelta |= (r + r + b + g + g + g + g + g)>>3;
pdelta++;
}
}
}
/* Check if pixels meet threshold */
for (unsigned int y = 1; y < (height-1); y += 2) {
pcurrent = buffer + ((y * width) * 3);
pabove = buffer + (((y-1) * width) * 3);
pbelow = buffer + (((y+1) * width) * 3);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
if(*pdelta++ >= threshold) {
pcurrent[(x*3)+0] = (pabove[(x*3)+0] + pbelow[(x*3)+0]) >> 1;
pcurrent[(x*3)+1] = (pabove[(x*3)+1] + pbelow[(x*3)+1]) >> 1;
pcurrent[(x*3)+2] = (pabove[(x*3)+2] + pbelow[(x*3)+2]) >> 1;
}
}
}
/* Special case for the last line */
pcurrent = buffer + (((height-1) * width) * 3);
pabove = buffer + (((height-2) * width) * 3);
pdelta = delta_buffer + (((height>>1)-1) * width);
for (unsigned int x = 0; x < width; x++) {
if(*pdelta++ >= threshold) {
pcurrent[(x*3)+0] = pabove[(x*3)+0];
pcurrent[(x*3)+1] = pabove[(x*3)+1];
pcurrent[(x*3)+2] = pabove[(x*3)+2];
}
}
}
else if ( colours == ZM_COLOUR_RGB32 )
{
/* Motion detection */
if ( subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
unsigned int b, g, r;
for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width) << 2);
pncurrent = next_image->buffer + ((y * width) << 2);
pabove = buffer + (((y-1) * width) << 2);
pnabove = next_image->buffer + (((y-1) * width) << 2);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
b = abs(pnabove[0] - pabove[0]);
g = abs(pnabove[1] - pabove[1]);
r = abs(pnabove[2] - pabove[2]);
*pdelta = (r + r + b + g + g + g + g + g)>>3;
b = abs(pncurrent[0] - pcurrent[0]);
g = abs(pncurrent[1] - pcurrent[1]);
r = abs(pncurrent[2] - pcurrent[2]);
*pdelta |= (r + r + b + g + g + g + g + g)>>3;
pnabove += 4;
pabove += 4;
pncurrent += 4;
pcurrent += 4;
pdelta++;
}
}
} else if ( subpixelorder == ZM_SUBPIX_ORDER_ARGB ) {
/*unsigned int r, g, b;
for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width) * 3);
pncurrent = next_image->buffer + ((y * width) * 3);
pabove = buffer + (((y-1) * width) * 3);
pnabove = next_image->buffer + (((y-1) * width) * 3);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
r = abs(*pnabove++ - *pabove++);
g = abs(*pnabove++ - *pabove++);
b = abs(*pnabove++ - *pabove++);
*pdelta = (r + r + b + g + g + g + g + g)>>3;
r = abs(*pncurrent++ - *pcurrent++);
g = abs(*pncurrent++ - *pcurrent++);
b = abs(*pncurrent++ - *pcurrent++);
*pdelta |= (r + r + b + g + g + g + g + g)>>3;
pdelta++;
}
}*/
Error("This type of deinterlacing is not implemented yet");
} else if ( subpixelorder == ZM_SUBPIX_ORDER_ABGR ) {
/*unsigned int r, g, b;
for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width) * 3);
pncurrent = next_image->buffer + ((y * width) * 3);
pabove = buffer + (((y-1) * width) * 3);
pnabove = next_image->buffer + (((y-1) * width) * 3);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
r = abs(*pnabove++ - *pabove++);
g = abs(*pnabove++ - *pabove++);
b = abs(*pnabove - *pabove);
pnabove += 2;
pabove += 2;
*pdelta = (r + r + b + g + g + g + g + g)>>3;
r = abs(*pncurrent++ - *pcurrent++);
g = abs(*pncurrent++ - *pcurrent++);
b = abs(*pncurrent - *pcurrent);
pncurrent += 2;
pcurrent += 2;
*pdelta |= (r + r + b + g + g + g + g + g)>>3;
pdelta++;
}
}*/
Error("This type of deinterlacing is not implemented yet");
} else {
unsigned int r, g, b;
for (unsigned int y = 1; y < height; y += 2) {
pcurrent = buffer + ((y * width) << 2);
pncurrent = next_image->buffer + ((y * width) << 2);
pabove = buffer + (((y-1) * width) << 2);
pnabove = next_image->buffer + (((y-1) * width) << 2);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
r = abs(pnabove[0] - pabove[0]);
g = abs(pnabove[1] - pabove[1]);
b = abs(pnabove[2] - pabove[2]);
*pdelta = (r + r + b + g + g + g + g + g)>>3;
r = abs(pncurrent[0] - pcurrent[0]);
g = abs(pncurrent[1] - pcurrent[1]);
b = abs(pncurrent[2] - pcurrent[2]);
*pdelta |= (r + r + b + g + g + g + g + g)>>3;
pnabove += 4;
pabove += 4;
pncurrent += 4;
pcurrent += 4;
pdelta++;
}
}
}
/* Check if pixels meet threshold */
for (unsigned int y = 1; y < (height-1); y += 2) {
pcurrent = buffer + ((y * width) << 2);
pabove = buffer + (((y-1) * width) << 2);
pbelow = buffer + (((y+1) * width) << 2);
pdelta = delta_buffer + ((y>>1) * width);
for (unsigned int x = 0; x < width; x++) {
if(*pdelta++ >= threshold) {
pcurrent[(x<<2)+0] = (pabove[(x<<2)+0] + pbelow[(x<<2)+0]) >> 1;
pcurrent[(x<<2)+1] = (pabove[(x<<2)+1] + pbelow[(x<<2)+1]) >> 1;
pcurrent[(x<<2)+2] = (pabove[(x<<2)+2] + pbelow[(x<<2)+2]) >> 1;
pcurrent[(x<<2)+3] = (pabove[(x<<2)+3] + pbelow[(x<<2)+3]) >> 1;
}
}
}
/* Special case for the last line */
pcurrent = buffer + (((height-1) * width) << 2);
pabove = buffer + (((height-2) * width) << 2);
pdelta = delta_buffer + (((height>>1)-1) * width);
for (unsigned int x = 0; x < width; x++) {
if(*pdelta++ >= threshold) {
pcurrent[(x<<2)+0] = pabove[(x<<2)+0];
pcurrent[(x<<2)+1] = pabove[(x<<2)+1];
pcurrent[(x<<2)+2] = pabove[(x<<2)+2];
pcurrent[(x<<2)+3] = pabove[(x<<2)+3];
}
}
} else { } else {
Error("Unimplemented yet"); Error("Not implemented yet");
} }
/* Free the delta buffer */ /* Free the delta buffer */

View File

@ -536,6 +536,11 @@ Monitor::~Monitor()
Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() ); Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() );
closeEvent(); closeEvent();
if ( (deinterlacing & 0xff) == 4)
{
delete next_buffer.image;
delete next_buffer.timestamp;
}
for ( int i = 0; i < image_buffer_count; i++ ) for ( int i = 0; i < image_buffer_count; i++ )
{ {
delete image_buffer[i].image; delete image_buffer[i].image;

View File

@ -364,9 +364,11 @@ $orientations = array(
$deinterlaceopts = array( $deinterlaceopts = array(
"Disabled" => 0x00000000, "Disabled" => 0x00000000,
"Four field motion adaptive - Soft" => 0x00003204, /* 50 change */ "Four field motion adaptive - Very Soft" => 0x00003204, /* 50 change */
"Four field motion adaptive - Soft" => 0x00002804, /* 40 change */
"Four field motion adaptive - Medium" => 0x00001E04, /* 30 change */ "Four field motion adaptive - Medium" => 0x00001E04, /* 30 change */
"Four field motion adaptive - Hard" => 0x00000A04, /* 10 change */ "Four field motion adaptive - Hard" => 0x00001404, /* 20 change */
"Four field motion adaptive - Very Hard" => 0x00000A04, /* 10 change */
"Discard" => 0x00000001, "Discard" => 0x00000001,
"Linear" => 0x00000002, "Linear" => 0x00000002,
"Blend" => 0x00000003, "Blend" => 0x00000003,
@ -375,16 +377,18 @@ $deinterlaceopts = array(
$deinterlaceopts_v4l2 = array( $deinterlaceopts_v4l2 = array(
"Disabled" => 0x00000000, "Disabled" => 0x00000000,
"Four field motion adaptive - Soft" => 0x00003204, /* 50 change */ "Four field motion adaptive - Very Soft" => 0x00003204, /* 50 change */
"Four field motion adaptive - Soft" => 0x00002804, /* 40 change */
"Four field motion adaptive - Medium" => 0x00001E04, /* 30 change */ "Four field motion adaptive - Medium" => 0x00001E04, /* 30 change */
"Four field motion adaptive - Hard" => 0x00000A04, /* 10 change */ "Four field motion adaptive - Hard" => 0x00001404, /* 20 change */
"Four field motion adaptive - Very Hard" => 0x00000A04, /* 10 change */
"Discard" => 0x00000001, "Discard" => 0x00000001,
"Linear" => 0x00000002, "Linear" => 0x00000002,
"Blend" => 0x00000003, "Blend" => 0x00000003,
"Blend (25%)" => 0x00000205, "Blend (25%)" => 0x00000205,
"V4L2: Top field only" => 0x02000000, "V4L2: Capture top field only" => 0x02000000,
"V4L2: Bottom field only" => 0x03000000, "V4L2: Capture bottom field only" => 0x03000000,
"V4L2: Alternate fields" => 0x07000000, "V4L2: Alternate fields (Bob)" => 0x07000000,
"V4L2: Progressive" => 0x01000000, "V4L2: Progressive" => 0x01000000,
"V4L2: Interlaced" => 0x04000000, "V4L2: Interlaced" => 0x04000000,
); );