/* * @DEC_COPYRIGHT@ */ /* * HISTORY * $Log: slib_video.c,v $ * Revision 1.1.6.13 1996/12/13 18:19:11 Hans_Graves * Added initialization of VideoPTimeBase. * [1996/12/13 18:07:51 Hans_Graves] * * Revision 1.1.6.12 1996/12/10 19:22:01 Hans_Graves * Made calculate video positions more accurate using slibFrameToTime100(). * [1996/12/10 19:16:24 Hans_Graves] * * Revision 1.1.6.11 1996/11/18 23:07:40 Hans_Graves * Make use of presentation timestamps. Make seeking time-based. * [1996/11/18 22:48:05 Hans_Graves] * * Revision 1.1.6.10 1996/11/11 18:21:11 Hans_Graves * Moved setting of VideoMainStream to slib_api.c * [1996/11/11 18:02:11 Hans_Graves] * * Revision 1.1.6.9 1996/11/08 21:51:09 Hans_Graves * Added AC3 support. Better seperation of stream types. * [1996/11/08 21:28:03 Hans_Graves] * * Revision 1.1.6.8 1996/10/28 17:32:36 Hans_Graves * MME-1402, 1431, 1435: Timestamp related changes. * [1996/10/28 17:23:11 Hans_Graves] * * Revision 1.1.6.7 1996/10/12 17:18:59 Hans_Graves * Seperated TYPE_MPEG2_SYSTEMS into TRANSPORT and PROGRAM. * [1996/10/12 17:03:19 Hans_Graves] * * Revision 1.1.6.6 1996/09/29 22:19:45 Hans_Graves * Added Stride support. YUY2 fixups. * [1996/09/29 21:32:24 Hans_Graves] * * Revision 1.1.6.5 1996/09/25 19:16:51 Hans_Graves * Fix up support for YUY2. Add SLIB_INTERNAL define. * [1996/09/25 19:01:18 Hans_Graves] * * Revision 1.1.6.4 1996/09/23 18:04:06 Hans_Graves * Add reallocation of ScaleBuf if width/height changes. * [1996/09/23 17:58:27 Hans_Graves] * * Revision 1.1.6.3 1996/09/18 23:47:25 Hans_Graves * Added MPEG2 YUV 4:2:2 handling * [1996/09/18 22:04:18 Hans_Graves] * * Revision 1.1.6.2 1996/05/07 19:56:25 Hans_Graves * Added HUFF_SUPPORT. * [1996/05/07 17:21:23 Hans_Graves] * * Revision 1.1.4.7 1996/05/02 17:10:37 Hans_Graves * Reject a data type when header info is not found. Fixes MME-01234 * [1996/05/02 17:09:53 Hans_Graves] * * Revision 1.1.4.6 1996/04/22 15:04:56 Hans_Graves * Renamed slibVerifyVideoParams() to slibValidateVideoParams() * [1996/04/22 14:44:29 Hans_Graves] * * Revision 1.1.4.5 1996/04/19 21:52:28 Hans_Graves * Fix Height and Width checking for H261 * [1996/04/19 21:46:27 Hans_Graves] * * Revision 1.1.4.4 1996/04/01 19:07:58 Hans_Graves * And some error checking * [1996/04/01 19:04:42 Hans_Graves] * * Revision 1.1.4.3 1996/03/29 22:21:37 Hans_Graves * Added MPEG/JPEG/H261_SUPPORT ifdefs * [1996/03/29 21:57:04 Hans_Graves] * * Added MPEG-I Systems encoding support * [1996/03/27 21:56:00 Hans_Graves] * * Revision 1.1.4.2 1996/03/08 18:46:51 Hans_Graves * Added slibVerifyVideoParams() * [1996/03/08 18:36:51 Hans_Graves] * * Revision 1.1.2.12 1996/02/19 18:04:00 Hans_Graves * Fixed a number of MPEG related bugs * [1996/02/19 17:57:50 Hans_Graves] * * Revision 1.1.2.11 1996/02/07 23:24:01 Hans_Graves * Added SEEK_EXACT. Fixed most frame counting problems. * [1996/02/07 23:20:39 Hans_Graves] * * Revision 1.1.2.10 1996/02/02 17:36:06 Hans_Graves * Enhanced audio info. Cleaned up API * [1996/02/02 17:29:51 Hans_Graves] * * Revision 1.1.2.9 1996/01/30 22:23:10 Hans_Graves * Added AVI YUV support * [1996/01/30 22:21:45 Hans_Graves] * * Revision 1.1.2.8 1996/01/15 16:26:33 Hans_Graves * No video if SLIB_TYPE_MPEG1_AUDIO or SLIB_TYPE_WAVE * [1996/01/15 15:47:40 Hans_Graves] * * Revision 1.1.2.7 1996/01/11 16:17:36 Hans_Graves * Added MPEG II Systems decode support * [1996/01/11 16:12:41 Hans_Graves] * * Revision 1.1.2.6 1996/01/08 16:41:35 Hans_Graves * Added MPEG II decoding support * [1996/01/08 15:53:10 Hans_Graves] * * Revision 1.1.2.5 1995/12/08 20:01:24 Hans_Graves * Added H.261 compression support. * [1995/12/08 20:00:52 Hans_Graves] * * Revision 1.1.2.4 1995/12/07 19:31:37 Hans_Graves * Added JPEG Decoding and MPEG encoding support * [1995/12/07 18:30:12 Hans_Graves] * * Revision 1.1.2.3 1995/11/09 23:14:08 Hans_Graves * Added GetVideoTime() * [1995/11/09 23:09:19 Hans_Graves] * * Revision 1.1.2.2 1995/11/06 18:47:57 Hans_Graves * First time under SLIB * [1995/11/06 18:36:05 Hans_Graves] * * $EndLog$ */ /***************************************************************************** ** Copyright (c) Digital Equipment Corporation, 1995 ** ** ** ** All Rights Reserved. Unpublished rights reserved under the copyright ** ** laws of the United States. ** ** ** ** The software contained on this media is proprietary to and embodies ** ** the confidential technology of Digital Equipment Corporation. ** ** Possession, use, duplication or dissemination of the software and ** ** media is authorized only pursuant to a valid written license from ** ** Digital Equipment Corporation. ** ** ** ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. ** ** Government is subject to restrictions as set forth in Subparagraph ** ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. ** ******************************************************************************/ /* #define _SLIBDEBUG_ */ #define SLIB_INTERNAL #include "slib.h" #include "mpeg.h" #include "h261.h" #include "h263.h" #include "jpeg.h" #include "avi.h" #ifdef _SLIBDEBUG_ #define _DEBUG_ 1 /* detailed debuging statements */ #define _VERBOSE_ 1 /* show progress */ #define _VERIFY_ 1 /* verify correct operation */ #define _WARN_ 1 /* warnings about strange behavior */ #endif int slibCalcBits(unsigned dword fourcc, int currentbits) { switch (fourcc) { case BI_DECMPEGDIB: case BI_DECH261DIB: case BI_MSH261DIB: case BI_DECH263DIB: case BI_MSH263DIB: case JPEG_DIB: return(24); case MJPG_DIB: case BI_YU12SEP: /* YUV 4:1:1 Planar */ return(24); case BI_DECYUVDIB: /* YUV 4:2:2 Packed */ case BI_YUY2: /* YUV 4:2:2 Packed */ return(16); case BI_YU16SEP: /* YUV 4:2:2 Planar */ return(24); case BI_YVU9SEP: /* YUV 16:1:1 Planar */ return(24); } return(currentbits); } static unsigned dword slibCalcImageSize(unsigned dword fourcc, int bits, int width, int height) { unsigned dword imagesize=0; if (width<0) width=-width; if (height<0) height=-height; switch (fourcc) { case BI_YVU9SEP: /* YUV 16:1:1 Planar */ imagesize = (width*height*5)/4; break; case BI_YU12SEP: /* YUV 4:1:1 Planar */ imagesize = (width*height*3)/2; break; case BI_DECYUVDIB: /* YUV 4:2:2 Packed */ case BI_YUY2: /* YUV 4:2:2 Packed */ case BI_YU16SEP: /* YUV 4:2:2 Planar */ imagesize = width*height*2; break; #ifndef WIN32 case BI_DECXIMAGEDIB: imagesize = width*height*(bits==24 ? 4 : 1); break; #endif /* !WIN32 */ case BI_RGB: case BI_BITFIELDS: imagesize = width*height*(bits/8); break; default: imagesize = width*height; } return(imagesize); } static dword slibFOURCCtoVideoType(dword *fourcc) { switch (*fourcc) { case BI_DECH261DIB: case BI_MSH261DIB: *fourcc=BI_DECH261DIB; return(SLIB_TYPE_H261); case BI_DECH263DIB: case BI_MSH263DIB: *fourcc=BI_DECH263DIB; return(SLIB_TYPE_H263); case JPEG_DIB: return(SLIB_TYPE_JPEG); case MJPG_DIB: return(SLIB_TYPE_MJPG); case BI_DECYUVDIB: /* YUV 4:2:2 Packed */ case BI_YUY2: /* YUV 4:2:2 Packed */ case BI_YU16SEP: /* YUV 4:2:2 Planar */ case BI_YU12SEP: /* YUV 4:1:1 Planar */ case BI_YVU9SEP: /* YUV 16:1:1 Planar */ return(SLIB_TYPE_YUV); default: _SlibDebug(_WARN_, printf("Unsupported AVI format\n") ); } return(0); } static void slibUpdateVideoFrames(SlibInfo_t *Info) { #ifdef MPEG_SUPPORT if (Info->VideoLengthKnown==FALSE && slibDataOnPin(Info, SLIB_DATA_VIDEO) && Info->FileSize>0 && Info->FileSizeOverflowSize) { if (SlibTypeIsMPEGVideo(Info->Type)) { dword frames = slibCountCodesOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), MPEG_PICTURE_START, 4, 0); if (Info->FramesPerSec) Info->VideoLength=slibFrameToTime(Info, frames); Info->VideoLengthKnown=TRUE; } } #endif /* MPEG_SUPPORT */ } void SlibUpdateVideoInfo(SlibInfo_t *Info) { int inbpp=24, outbpp=24, compformat=0, dcmpformat=0; SlibTime_t ptime; _SlibDebug(_DEBUG_, printf("SlibUpdateVideoInfo()\n") ); if (SlibTypeIsAudioOnly(Info->Type)) /* no video? */ return; if (Info->Mode == SLIB_MODE_COMPRESS) { switch (Info->Type) { #ifdef MPEG_SUPPORT case SLIB_TYPE_MPEG1_VIDEO: case SLIB_TYPE_MPEG2_VIDEO: case SLIB_TYPE_MPEG_SYSTEMS: case SLIB_TYPE_MPEG_SYSTEMS_MPEG2: compformat=BI_DECMPEGDIB; dcmpformat=BI_YU12SEP; Info->Width = SIF_WIDTH; Info->Height = SIF_HEIGHT; Info->FramesPerSec = 25.0F; Info->VideoBitRate = 1152000; break; #endif /* MPEG_SUPPORT */ #ifdef H261_SUPPORT case SLIB_TYPE_H261: case SLIB_TYPE_RTP_H261: compformat=BI_DECH261DIB; dcmpformat=BI_YU12SEP; Info->Width = CIF_WIDTH; Info->Height = CIF_HEIGHT; Info->FramesPerSec = 15.0F; Info->VideoBitRate = 352000; break; #endif /* H261_SUPPORT */ #ifdef H263_SUPPORT case SLIB_TYPE_H263: case SLIB_TYPE_RTP_H263: compformat=BI_DECH263DIB; dcmpformat=BI_YU12SEP; Info->Width = CIF_WIDTH; Info->Height = CIF_HEIGHT; Info->FramesPerSec = 30.0F; Info->VideoBitRate = 0; break; #endif /* H263_SUPPORT */ #ifdef HUFF_SUPPORT case SLIB_TYPE_SHUFF: compformat=BI_DECHUFFDIB; dcmpformat=BI_YU12SEP; Info->Width = 320; Info->Height = 240; Info->FramesPerSec = 30.0F; Info->VideoBitRate = 0; break; #endif /* HUFF_SUPPORT */ default: break; } } else if (Info->Mode == SLIB_MODE_DECOMPRESS) { unsigned char *buf; unsigned dword size; Info->VideoStreams=1; switch (Info->Type) { #ifdef MPEG_SUPPORT case SLIB_TYPE_MPEG1_VIDEO: case SLIB_TYPE_MPEG2_VIDEO: case SLIB_TYPE_MPEG_SYSTEMS: case SLIB_TYPE_MPEG_SYSTEMS_MPEG2: case SLIB_TYPE_MPEG_TRANSPORT: case SLIB_TYPE_MPEG_PROGRAM: _SlibDebug(_DEBUG_, printf("SlibUpdateVideoInfo() MPEG1 or MPEG2\n") ); if (!slibLoadPin(Info, SLIB_DATA_VIDEO)) { _SlibDebug(_DEBUG_, printf("SlibUpdateVideoInfo() No VIDEO data\n") ); Info->Type=SLIB_TYPE_UNKNOWN; Info->VideoStreams=0; return; } buf = slibSearchBuffersOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), NULL, &size, MPEG_SEQ_HEAD, MPEG_SEQ_HEAD_LEN/8, FALSE); if (buf) { const float fps[16] = { 30.0F, 23.976F, 24.0F, 25.0F, 29.97F, 30.0F, 50.0F, 59.94F, 60.0F, 30.0F, 30.0F, 30.0F, 30.0F, 30.0F, 30.0F, 30.0F }; /* ScDumpChar(buf, size, 0); */ Info->Width = ((int)buf[0])*16+(int)(buf[1]>>4); Info->Height = ((int)buf[1]&0x0F)*256+(int)buf[2]; /* must be 16x16 because of Render limitations, round up */ Info->Width += (Info->Width%16) ? 16-(Info->Width%16) : 0; Info->Height += (Info->Height%16) ? 16-(Info->Height%16) : 0; Info->FramesPerSec = fps[buf[3]&0x0F]; Info->VideoBitRate = (((dword)buf[4]&0xFF)<<10) + (((dword)buf[5])<<2) + (dword)(buf[6]>>6); Info->VideoBitRate *= 400; Info->VBVbufSize = ((int)buf[6]&0x1F)<<5 | (int)(buf[7]>>3); Info->VBVbufSize *= 2*1024; _SlibDebug(_DEBUG_, printf("VBVbufSize=%d\n", Info->VBVbufSize) ); if (Info->VideoBitRate) { qword secs=(qword)(((qword)Info->FileSize*80L) /Info->VideoBitRate); Info->VideoLength = secs*100; _SlibDebug(_DEBUG_, printf("SlibUpdateVideoInfo() VideoLength = %ld Bitrate=%ld\n", Info->VideoLength, Info->VideoBitRate) ); } } else /* invalid format */ { _SlibDebug(_DEBUG_, printf("SlibUpdateVideoInfo() Didn't find MPEG sequence header\n") ); Info->Type=SLIB_TYPE_UNKNOWN; Info->VideoStreams=0; return; } compformat=BI_DECMPEGDIB; dcmpformat=BI_YU12SEP; Info->VideoType=SLIB_TYPE_MPEG1_VIDEO; /* check to see if this is MPEG 2 */ _SlibDebug(_DEBUG_, printf("Searching for MPEG 2 extensions...\n") ); do { buf = slibSearchBuffersOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), buf, &size, MPEG_START_CODE, MPEG_START_CODE_LEN/8, FALSE); if (buf && buf[0]==MPEG_EXT_START_BASE) { _SlibDebug(_DEBUG_, printf("Found START CODE %X, ID=%d\n", buf[0], buf[1]>>4) ); if ((buf[1]>>4)==MPEG_SEQ_ID) /* has to be MPEG 2 */ { if (Info->Type==SLIB_TYPE_MPEG1_VIDEO) Info->Type=SLIB_TYPE_MPEG2_VIDEO; else if (Info->Type==SLIB_TYPE_MPEG_SYSTEMS) Info->Type=SLIB_TYPE_MPEG_SYSTEMS_MPEG2; Info->VideoType=SLIB_TYPE_MPEG2_VIDEO; switch ((buf[2]>>1)&0x03) { default: case 1: /* 4:1:1 */ dcmpformat=BI_YU12SEP; _SlibDebug(_DEBUG_, printf("4:1:1\n") ); break; case 2: /* 4:2:2 */ dcmpformat=BI_YU16SEP; _SlibDebug(_DEBUG_, printf("4:2:2\n") ); break; case 3: /* 4:4:4 */ dcmpformat=BI_YU16SEP; _SlibDebug(_DEBUG_, printf("4:4:4\n") ); break; } break; } } else break; } while (1); _SlibDebug(_DEBUG_, printf("Done searching for MPEG 2 extensions.\n") ); Info->KeySpacing=12; Info->SubKeySpacing=3; break; #endif /* MPEG_SUPPORT */ #ifdef H261_SUPPORT case SLIB_TYPE_H261: case SLIB_TYPE_RTP_H261: slibLoadPin(Info, SLIB_DATA_VIDEO); buf = slibSearchBuffersOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), NULL, &size, H261_START_CODE, H261_START_CODE_LEN/8, FALSE); if (buf) { if ((buf[0]&0xF0)==0) /* picture start code */ { if (buf[1]&0x08) { Info->Width = 352; Info->Height = 288; } else { Info->Width = 176; Info->Height = 144; } } Info->FramesPerSec = 15.0F; } compformat=BI_DECH261DIB; dcmpformat=BI_YU12SEP; Info->VideoType=SLIB_TYPE_H261; break; #endif /* H261_SUPPORT */ #ifdef H263_SUPPORT case SLIB_TYPE_H263: case SLIB_TYPE_RTP_H263: slibLoadPin(Info, SLIB_DATA_VIDEO); buf = slibSearchBuffersOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), NULL, &size, 0x000080, 3, FALSE); if (buf) { switch ((buf[1]>>2)&0x07) { case H263_SF_SQCIF: Info->Width = SQCIF_WIDTH; Info->Height = SQCIF_HEIGHT; break; case H263_SF_QCIF: Info->Width = QCIF_WIDTH; Info->Height = QCIF_HEIGHT; break; case H263_SF_4CIF: Info->Width = CIF4_WIDTH; Info->Height = CIF4_HEIGHT; break; case H263_SF_16CIF: Info->Width = CIF16_WIDTH; Info->Height = CIF16_HEIGHT; break; case H263_SF_CIF: default: Info->Width = CIF_WIDTH; Info->Height = CIF_HEIGHT; } Info->FramesPerSec = 30.0F; } compformat=BI_DECH263DIB; dcmpformat=BI_YU12SEP; Info->VideoType=SLIB_TYPE_H263; break; #endif /* H263_SUPPORT */ #ifdef HUFF_SUPPORT case SLIB_TYPE_SHUFF: slibLoadPin(Info, SLIB_DATA_VIDEO); buf=slibPeekBufferOnPin(Info, slibGetPin(Info,SLIB_DATA_VIDEO), &size, NULL); if (buf) { _SlibDebug(_DEBUG_, printf("%2X %2X %2X %2X %2X %2X\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]) ); Info->Width = ((int)buf[3]*256)+(int)buf[4]; Info->Height = ((int)buf[5]*256)+(int)buf[6]; } Info->FramesPerSec = 30.0F; Info->VideoBitRate = 0; compformat=BI_DECHUFFDIB; dcmpformat=BI_YU12SEP; Info->KeySpacing=1; Info->SubKeySpacing=1; Info->VideoType=SLIB_TYPE_SHUFF; break; #endif /* HUFF_SUPPORT */ case SLIB_TYPE_RASTER: buf=slibPeekBufferOnPin(Info, slibGetPin(Info,SLIB_DATA_COMPRESSED), &size, NULL); Info->FramesPerSec = 30.0F; if (buf) { _SlibDebug(_DEBUG_, printf("%2X %2X %2X %2X %2X %2X\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]) ); Info->Width = ((int)buf[4]<<24)+((int)buf[5]<<16)+((int)buf[6]<<8)+(int)buf[7]; Info->Height = ((int)buf[8]<<24)+((int)buf[9]<<16)+((int)buf[10]<<8)+(int)buf[11]; Info->VideoLength = slibFrameToTime(Info, (signed qword)Info->FileSize/(Info->Width*Info->Height*3)); } else Info->VideoLength = slibFrameToTime(Info, 1); Info->VideoBitRate = 0; compformat=BI_RGB; dcmpformat=BI_YU12SEP; Info->KeySpacing=1; Info->SubKeySpacing=1; Info->VideoType=SLIB_TYPE_RASTER; break; case SLIB_TYPE_BMP: buf=slibPeekBufferOnPin(Info, slibGetPin(Info,SLIB_DATA_COMPRESSED), &size, NULL); Info->FramesPerSec = 30.0F; if (buf) { _SlibDebug(_DEBUG_, printf("%2X %2X %2X %2X %2X %2X\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]) ); Info->Width = ((dword)buf[15]<<24)+((dword)buf[16]<<16)+((dword)buf[17]<<8)+(dword)buf[18]; Info->Height = ((dword)buf[19]<<24)+((dword)buf[20]<<16)+((dword)buf[21]<<8)+(dword)buf[22]; compformat=((dword)buf[30]<<24)+((dword)buf[25]<<16)+((dword)buf[26]<<8)+(dword)buf[27]; inbpp=(dword)buf[28]; Info->VideoLength = slibFrameToTime(Info, (signed qword)Info->FileSize/(Info->Width*Info->Height*3)); } else Info->VideoLength = slibFrameToTime(Info, 1); Info->VideoBitRate = 0; Info->VideoType = slibFOURCCtoVideoType(&compformat); dcmpformat=BI_YU16SEP; outbpp=slibCalcBits(dcmpformat, outbpp); Info->KeySpacing=1; Info->SubKeySpacing=1; break; case SLIB_TYPE_RIFF: case SLIB_TYPE_AVI: slibLoadPin(Info, SLIB_DATA_COMPRESSED); buf = slibSearchBuffersOnPin(Info, slibGetPin(Info,SLIB_DATA_COMPRESSED), NULL, &size, AVI_MAINHDR, 4, FALSE); if (buf) { AVI_MainHeader hdr; /* printf("%d %d %d %d\n", buf[4], buf[5], buf[6], buf[7]); */ memcpy(&hdr, buf+4, sizeof(AVI_MainHeader)); Info->Width = (short)hdr.dwWidth; Info->Height = (short)hdr.dwHeight; Info->FramesPerSec = 1000000.0F/hdr.dwMicroSecPerFrame; if (Info->FramesPerSec==0.0F) Info->FramesPerSec = 30.0F; Info->VideoLength = slibFrameToTime(Info, hdr.dwTotalFrames); Info->VideoLengthKnown = TRUE; } buf = slibSearchBuffersOnPin(Info, slibGetPin(Info,SLIB_DATA_COMPRESSED), NULL, &size, AVI_STREAMFORMAT, 4, FALSE); if (buf) { AVI_StreamHeader hdr; /* printf("%c %c %c %c\n", buf[4], buf[5], buf[6], buf[7]); */ memcpy(&hdr, buf+20, sizeof(AVI_StreamHeader)); compformat=hdr.fccType; Info->VideoType = slibFOURCCtoVideoType(&compformat); switch (Info->VideoType) { case SLIB_TYPE_JPEG: Info->Type = SLIB_TYPE_JPEG_AVI; dcmpformat=BI_YU16SEP; break; case SLIB_TYPE_MJPG: Info->Type = SLIB_TYPE_MJPG_AVI; dcmpformat=BI_YU16SEP; break; case SLIB_TYPE_YUV: Info->Type = SLIB_TYPE_YUV_AVI; dcmpformat=compformat; if (IsYUV422Packed(dcmpformat) || IsYUV422Sep(dcmpformat)) dcmpformat=BI_YU16SEP; break; default: _SlibDebug(_WARN_, printf("Unsupported AVI format\n") ); return; } inbpp=slibCalcBits(compformat, inbpp); outbpp=slibCalcBits(dcmpformat, outbpp); Info->KeySpacing=1; Info->SubKeySpacing=1; } break; #ifdef JPEG_SUPPORT case SLIB_TYPE_JPEG_QUICKTIME: case SLIB_TYPE_JFIF: /* not supported - need to know how to parse */ slibLoadPin(Info, SLIB_DATA_VIDEO); buf = slibSearchBuffersOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), NULL, &size, (JPEG_MARKER<<8)|JPEG_SOF0, 2, FALSE); if (buf) { Info->Width = ((int)buf[5]<<8) + (int)buf[6]; Info->Height = ((int)buf[3]<<8) + (int)buf[4]; Info->FramesPerSec = 30.0F; } compformat=MJPG_DIB; dcmpformat=BI_YU16SEP; Info->VideoType = SLIB_TYPE_JPEG; break; #endif /* JPEG_SUPPORT */ } slibUpdateVideoFrames(Info); } if (SlibTypeHasTimeStamps(Info->Type)) { ptime=slibGetNextTimeOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), 100*1024); if (SlibTimeIsValid(ptime)) Info->VideoPTimeBase=ptime; } if (Info->CompVideoFormat==NULL) Info->CompVideoFormat=(BITMAPINFOHEADER *)ScAlloc(sizeof(BITMAPINFOHEADER)); _SlibDebug(_VERBOSE_, printf("Width=%d Height=%d Stride=%d\n", Info->Width, Info->Height, Info->Stride) ); if (Info->CompVideoFormat!=NULL) { Info->CompVideoFormat->biSize = sizeof(BITMAPINFOHEADER); Info->CompVideoFormat->biWidth = Info->Width; Info->CompVideoFormat->biHeight = Info->Height; Info->CompVideoFormat->biPlanes = 1; Info->CompVideoFormat->biBitCount = (WORD)inbpp; Info->CompVideoFormat->biCompression = compformat; Info->CompVideoFormat->biSizeImage = 0; Info->CompVideoFormat->biXPelsPerMeter = 0; Info->CompVideoFormat->biYPelsPerMeter = 0; Info->CompVideoFormat->biClrUsed = 0; Info->CompVideoFormat->biClrImportant = 0; } if (Info->VideoFormat==NULL) Info->VideoFormat=(BITMAPINFOHEADER *)ScAlloc(sizeof(BITMAPINFOHEADER)); if (Info->VideoFormat!=NULL) { Info->VideoFormat->biSize = sizeof(BITMAPINFOHEADER); Info->VideoFormat->biWidth = Info->Width; Info->VideoFormat->biHeight = Info->Height; Info->VideoFormat->biPlanes = 1; Info->VideoFormat->biBitCount = (WORD)outbpp; Info->VideoFormat->biCompression = dcmpformat; Info->VideoFormat->biSizeImage = 0; Info->VideoFormat->biXPelsPerMeter = 0; Info->VideoFormat->biYPelsPerMeter = 0; Info->VideoFormat->biClrUsed = 0; Info->VideoFormat->biClrImportant = 0; } if (Info->CodecVideoFormat==NULL) { Info->CodecVideoFormat=(BITMAPINFOHEADER *)ScAlloc(sizeof(BITMAPINFOHEADER)); if (Info->CodecVideoFormat!=NULL) memcpy(Info->CodecVideoFormat, Info->VideoFormat, sizeof(BITMAPINFOHEADER)); } slibValidateVideoParams(Info); } SlibStatus_t slibValidateVideoParams(SlibInfo_t *Info) { dword oldimagesize, codecwidth, codecheight; SlibStatus_t status=SlibErrorNone; if (Info->CodecVideoFormat) { codecwidth=Info->CodecVideoFormat->biWidth; codecheight=Info->CodecVideoFormat->biHeight; } else { codecwidth=Info->Width; codecheight=Info->Height; } if (Info->Mode==SLIB_MODE_COMPRESS) { switch (Info->Type) { case SLIB_TYPE_H261: if (Info->Width!=CIF_WIDTH && Info->Width!=QCIF_WIDTH) status=SlibErrorImageSize; if (Info->Height!=CIF_HEIGHT && Info->Height!=QCIF_HEIGHT) status=SlibErrorImageSize; if (status!=SlibErrorNone) /* set to closest size */ { if (Info->Width<=300) { codecwidth=QCIF_WIDTH; codecheight=QCIF_HEIGHT; } else { codecwidth=CIF_WIDTH; codecheight=CIF_HEIGHT; } } break; case SLIB_TYPE_H263: if (Info->Width!=CIF_WIDTH && Info->Width!=SQCIF_WIDTH && Info->Width!=QCIF_WIDTH && Info->Width!=CIF4_WIDTH && Info->Width!=CIF16_WIDTH) status=SlibErrorImageSize; if (Info->Height!=CIF_HEIGHT && Info->Height!=SQCIF_HEIGHT && Info->Height!=QCIF_HEIGHT && Info->Height!=CIF4_HEIGHT && Info->Height!=CIF16_HEIGHT) status=SlibErrorImageSize; if (status!=SlibErrorNone) /* set to closest size */ { if (Info->Width<=168) { codecwidth=SQCIF_WIDTH; codecheight=SQCIF_HEIGHT; } else if (Info->Width<=300) { codecwidth=QCIF_WIDTH; codecheight=QCIF_HEIGHT; } else if (Info->Width<=(CIF4_WIDTH+CIF_WIDTH)/2) { codecwidth=CIF_WIDTH; codecheight=CIF_HEIGHT; } else if (Info->Width<=(CIF16_WIDTH+CIF4_WIDTH)/2) { codecwidth=CIF4_WIDTH; codecheight=CIF4_HEIGHT; } else { codecwidth=CIF16_WIDTH; codecheight=CIF16_HEIGHT; } } break; } /* height and width must be mults of 8 */ if (codecwidth%8 || codecheight%8) return(SlibErrorImageSize); if (status==SlibErrorImageSize) { if (Info->CodecVideoFormat) { Info->CodecVideoFormat->biWidth=codecwidth; Info->CodecVideoFormat->biHeight=codecheight; } if (Info->CompVideoFormat) { Info->CompVideoFormat->biWidth=codecwidth; Info->CompVideoFormat->biHeight=codecheight; } } } if (Info->VideoFormat) { oldimagesize=Info->ImageSize; Info->ImageSize=slibCalcImageSize(Info->VideoFormat->biCompression, Info->VideoFormat->biBitCount, Info->VideoFormat->biWidth, Info->VideoFormat->biHeight); if (Info->ImageSize!=oldimagesize && Info->Imagebuf) { SlibFreeBuffer(Info->Imagebuf); Info->Imagebuf=NULL; } Info->VideoFormat->biBitCount=(WORD)slibCalcBits( Info->VideoFormat->biCompression, Info->VideoFormat->biBitCount); Info->VideoFormat->biSizeImage=Info->ImageSize; } if (Info->CodecVideoFormat) { oldimagesize=Info->CodecImageSize; Info->CodecImageSize=slibCalcImageSize( Info->CodecVideoFormat->biCompression, Info->CodecVideoFormat->biBitCount, Info->CodecVideoFormat->biWidth, Info->CodecVideoFormat->biHeight); if (Info->CodecImageSize!=oldimagesize && Info->CodecImagebuf) { SlibFreeBuffer(Info->CodecImagebuf); Info->CodecImagebuf=NULL; } Info->CodecVideoFormat->biBitCount=(WORD)slibCalcBits( Info->CodecVideoFormat->biCompression, Info->CodecVideoFormat->biBitCount); Info->CodecVideoFormat->biSizeImage=Info->CodecImageSize; } if (Info->VideoFormat && Info->CodecVideoFormat) { oldimagesize=Info->IntImageSize; Info->IntImageSize=slibCalcImageSize(Info->VideoFormat->biCompression, Info->VideoFormat->biBitCount, Info->CodecVideoFormat->biWidth, Info->CodecVideoFormat->biHeight); if (Info->IntImageSize!=oldimagesize && Info->IntImagebuf) { SlibFreeBuffer(Info->IntImagebuf); Info->IntImagebuf=NULL; } } /* close format converter since formats may have changed */ if (Info->Sch) { SconClose(Info->Sch); Info->Sch=NULL; } if (Info->FramesPerSec) Info->VideoFrameDuration=slibFrameToTime100(Info, 1); return(status); }