Changeset 7509 in vbox for trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture
- Timestamp:
- Mar 20, 2008 4:03:43 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 28975
- Location:
- trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp
r7485 r7509 92 92 93 93 LogFlow(("Creating FFmpegFB object %p, width=%lu, height=%lu\n", 94 this, width,height));94 this, (unsigned long) width, (unsigned long) height)); 95 95 Assert(width % 2 == 0 && height % 2 == 0); 96 96 /* For temporary RGB frame we allocate enough memory to deal with … … 154 154 av_write_trailer(mpFormatContext); 155 155 /* free the streams */ 156 for( inti = 0; i < mpFormatContext->nb_streams; i++) {156 for(unsigned i = 0; i < mpFormatContext->nb_streams; i++) { 157 157 av_freep(&mpFormatContext->streams[i]->codec); 158 158 av_freep(&mpFormatContext->streams[i]); … … 211 211 avpicture_fill((AVPicture *) mFrame, mYUVBuffer, PIX_FMT_YUV420P, 212 212 mFrameWidth, mFrameHeight); 213 /* Fill in the AVPicture structure describing the MPEG frame214 framebuffer - in fact another representation of the same data */215 avpicture_fill(&mFramePicture, mYUVBuffer, PIX_FMT_YUV420P,216 mFrameWidth, mFrameHeight);217 213 /* Set the initial framebuffer size to the mpeg frame dimensions */ 218 214 BOOL finished; … … 256 252 if (!width) 257 253 return E_POINTER; 258 LogFlow(("FFmpeg::COMGETTER(Width): returning width %lu\n", mGuestWidth)); 254 LogFlow(("FFmpeg::COMGETTER(Width): returning width %lu\n", 255 (unsigned long) mGuestWidth)); 259 256 *width = mGuestWidth; 260 257 return S_OK; … … 271 268 if (!height) 272 269 return E_POINTER; 273 LogFlow(("FFmpeg::COMGETTER(Height): returning height %lu\n", mGuestHeight)); 270 LogFlow(("FFmpeg::COMGETTER(Height): returning height %lu\n", 271 (unsigned long) mGuestHeight)); 274 272 *height = mGuestHeight; 275 273 return S_OK; … … 292 290 *bitsPerPixel = mBitsPerPixel; 293 291 LogFlow(("FFmpeg::COMGETTER(BitsPerPixel): returning depth %lu\n", 294 *bitsPerPixel));292 (unsigned long) *bitsPerPixel)); 295 293 return S_OK; 296 294 } … … 306 304 if (!bytesPerLine) 307 305 return E_POINTER; 308 LogFlow(("FFmpeg::COMGETTER(BytesPerLine): returning line size %lu\n", mBytesPerLine)); 306 LogFlow(("FFmpeg::COMGETTER(BytesPerLine): returning line size %lu\n", 307 (unsigned long) mBytesPerLine)); 309 308 *bytesPerLine = mBytesPerLine; 310 309 return S_OK; … … 321 320 if (!pixelFormat) 322 321 return E_POINTER; 323 LogFlow(("FFmpeg::COMGETTER(PixelFormat): returning pixel format: % d\n",324 mPixelFormat));322 LogFlow(("FFmpeg::COMGETTER(PixelFormat): returning pixel format: %lu\n", 323 (unsigned long) mPixelFormat)); 325 324 *pixelFormat = mPixelFormat; 326 325 return S_OK; … … 338 337 return E_POINTER; 339 338 LogFlow(("FFmpeg::COMGETTER(UsesGuestVRAM): uses guest VRAM? %d\n", 340 FALSE));341 *usesGuestVRAM = mRGBBuffer == NULL;339 mRGBBuffer == NULL)); 340 *usesGuestVRAM = (mRGBBuffer == NULL); 342 341 return S_OK; 343 342 } … … 418 417 419 418 LogFlow(("FFmpeg::NotifyUpdate called: x=%lu, y=%lu, w=%lu, h=%lu\n", 420 x, y, w, h)); 419 (unsigned long) x, (unsigned long) y, (unsigned long) w, 420 (unsigned long) h)); 421 421 if (!finished) 422 422 return E_POINTER; … … 500 500 if (!finished) 501 501 return E_POINTER; 502 LogFlow(("FFmpeg::RequestResize called: pixelFormat=% d, vram=%lu, "502 LogFlow(("FFmpeg::RequestResize called: pixelFormat=%lu, vram=%lu, " 503 503 "bpp=%lu bpl=%lu, w=%lu, h=%lu\n", 504 pixelFormat, vram, bitsPerPixel, bytesPerLine, w, h)); 504 (unsigned long) pixelFormat, (unsigned long) vram, 505 (unsigned long) bitsPerPixel, (unsigned long) bytesPerLine, 506 (unsigned long) w, (unsigned long) h)); 505 507 /* For now, we are doing things synchronously */ 506 508 *finished = true; … … 550 552 mBitsPerPixel = bitsPerPixel; 551 553 mRGBBuffer = 0; 552 Log2(("FFmpeg::RequestResize: setting mBufferAddress to vram and mLineSize to %lu\n", mBytesPerLine)); 554 Log2(("FFmpeg::RequestResize: setting mBufferAddress to vram and mLineSize to %lu\n", 555 (unsigned long) mBytesPerLine)); 553 556 } 554 557 else … … 563 566 mRGBBuffer = reinterpret_cast<uint8_t *>(RTMemAlloc(mBytesPerLine * h)); 564 567 AssertReturn(mRGBBuffer != 0, E_OUTOFMEMORY); 565 Log2(("FFmpeg::RequestResize: alloc'ing mBufferAddress and mRGBBuffer to %p and mBytesPerLine to %lu\n", mBufferAddress,566 mB ytesPerLine));568 Log2(("FFmpeg::RequestResize: alloc'ing mBufferAddress and mRGBBuffer to %p and mBytesPerLine to %lu\n", 569 mBufferAddress, (unsigned long) mBytesPerLine)); 567 570 mBufferAddress = mRGBBuffer; 568 571 } 569 572 570 /* Fill in the structure describing the (intermediate) guest571 framebuffer so that ffmpeg can copy correctly between the two */572 avpicture_fill(&mGuestPicture, mTempRGBBuffer, mFFMPEGPixelFormat,573 mFrameWidth, mFrameHeight);574 573 /* Blank out the intermediate frame framebuffer */ 575 574 memset(mTempRGBBuffer, 0, mFrameWidth * mFrameHeight * 4); … … 847 846 { 848 847 Log2(("FFmpegFB::copy_to_intermediate_buffer: x=%lu, y=%lu, w=%lu, h=%lu\n", 849 x, y, w,h));848 (unsigned long) x, (unsigned long) y, (unsigned long) w, (unsigned long) h)); 850 849 /* Perform clipping and calculate the destination co-ordinates */ 851 850 ULONG destX, destY, bpp; … … 924 923 HRESULT FFmpegFB::do_rgb_to_yuv_conversion() 925 924 { 926 int rc = img_convert(&mFramePicture, PIX_FMT_YUV420P, 927 &mGuestPicture, mFFMPEGPixelFormat, 928 mFrameWidth, mFrameHeight); 929 AssertMsg(rc >= 0, ("img_convert() failed. rc=%d, mFFMPEGPixelFormat=%d\n" 930 "mFrameWidth=%u, mFrameHeight=%u\n", rc, 931 mFFMPEGPixelFormat, mFrameWidth, mFrameHeight)); 932 if (rc < 0) 933 return E_UNEXPECTED; 925 switch (mFFMPEGPixelFormat) 926 { 927 case PIX_FMT_RGBA32: 928 if (!FFmpegWriteYUV420p<FFmpegBGRA32Iter>(mFrameWidth, mFrameHeight, 929 mYUVBuffer, mTempRGBBuffer)) 930 return E_UNEXPECTED; 931 break; 932 case PIX_FMT_RGB24: 933 if (!FFmpegWriteYUV420p<FFmpegBGR24Iter>(mFrameWidth, mFrameHeight, 934 mYUVBuffer, mTempRGBBuffer)) 935 return E_UNEXPECTED; 936 break; 937 case PIX_FMT_RGB565: 938 if (!FFmpegWriteYUV420p<FFmpegBGR565Iter>(mFrameWidth, mFrameHeight, 939 mYUVBuffer, mTempRGBBuffer)) 940 return E_UNEXPECTED; 941 break; 942 default: 943 return E_UNEXPECTED; 944 } 934 945 return S_OK; 935 946 } … … 991 1002 png_structp png_ptr; 992 1003 png_infop info_ptr; 993 AVPicture libPNGPicture;994 1004 uint8_t *PNGBuffer; 995 int rc;996 1005 /* Work out the new file name - for some reason, we can't use 997 1006 the com::Utf8Str() directly, but have to copy it */ … … 1036 1045 if (row_pointers == 0) 1037 1046 goto av_malloc_pointers_failed; 1038 avpicture_fill(&libPNGPicture, PNGBuffer, PIX_FMT_RGB24, 1039 mFrameWidth, mFrameHeight); 1040 rc = img_convert(&libPNGPicture, PIX_FMT_RGB24, 1041 &mGuestPicture, mFFMPEGPixelFormat, 1042 mFrameWidth, mFrameHeight); 1043 if (rc < 0) 1044 goto setjmp_exception; 1047 switch (mFFMPEGPixelFormat) 1048 { 1049 case PIX_FMT_RGBA32: 1050 if (!FFmpegWriteRGB24<FFmpegBGRA32Iter>(mFrameWidth, mFrameHeight, 1051 PNGBuffer, mTempRGBBuffer)) 1052 goto setjmp_exception; 1053 break; 1054 case PIX_FMT_RGB24: 1055 if (!FFmpegWriteRGB24<FFmpegBGR24Iter>(mFrameWidth, mFrameHeight, 1056 PNGBuffer, mTempRGBBuffer)) 1057 goto setjmp_exception; 1058 break; 1059 case PIX_FMT_RGB565: 1060 if (!FFmpegWriteRGB24<FFmpegBGR565Iter>(mFrameWidth, mFrameHeight, 1061 PNGBuffer, mTempRGBBuffer)) 1062 goto setjmp_exception; 1063 break; 1064 default: 1065 goto setjmp_exception; 1066 } 1045 1067 /* libpng exception handling */ 1046 1068 if (setjmp(png_jmpbuf(png_ptr))) -
trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h
r7485 r7509 156 156 /** Information for ffmpeg describing the current frame */ 157 157 AVFrame *mFrame; 158 /** An AVPicture structure containing information about the159 * guest framebuffer */160 AVPicture mGuestPicture;161 158 /** ffmpeg pixel format of guest framebuffer */ 162 159 int mFFMPEGPixelFormat; 163 /** An AVPicture structure containing information about the164 * MPEG frame framebuffer */165 AVPicture mFramePicture;166 160 /** Since we are building without exception support, we use this 167 161 to signal allocation failure in the constructor */ … … 186 180 }; 187 181 182 /** 183 * Iterator class for running through an BGRA32 image buffer and converting 184 * it to RGB. 185 */ 186 class FFmpegBGRA32Iter 187 { 188 private: 189 enum { PIX_SIZE = 4 }; 190 public: 191 FFmpegBGRA32Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuffer) 192 { 193 mPos = 0; 194 mSize = aWidth * aHeight * PIX_SIZE; 195 mBuffer = aBuffer; 196 } 197 /** 198 * Convert the next pixel to RGB. 199 * @returns true on success, false if we have reached the end of the buffer 200 * @param aRed where to store the red value 201 * @param aGreen where to store the green value 202 * @param aBlue where to store the blue value 203 */ 204 bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue) 205 { 206 bool rc = false; 207 if (mPos + PIX_SIZE <= mSize) 208 { 209 *aRed = mBuffer[mPos + 2]; 210 *aGreen = mBuffer[mPos + 1]; 211 *aBlue = mBuffer[mPos]; 212 mPos += PIX_SIZE; 213 rc = true; 214 } 215 return rc; 216 } 217 218 /** 219 * Skip forward by a certain number of pixels 220 * @param aPixels how many pixels to skip 221 */ 222 void skip(unsigned aPixels) 223 { 224 mPos += PIX_SIZE * aPixels; 225 } 226 private: 227 /** Size of the picture buffer */ 228 unsigned mSize; 229 /** Current position in the picture buffer */ 230 unsigned mPos; 231 /** Address of the picture buffer */ 232 uint8_t *mBuffer; 233 }; 234 235 /** 236 * Iterator class for running through an BGR24 image buffer and converting 237 * it to RGB. 238 */ 239 class FFmpegBGR24Iter 240 { 241 private: 242 enum { PIX_SIZE = 3 }; 243 public: 244 FFmpegBGR24Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuffer) 245 { 246 mPos = 0; 247 mSize = aWidth * aHeight * PIX_SIZE; 248 mBuffer = aBuffer; 249 } 250 /** 251 * Convert the next pixel to RGB. 252 * @returns true on success, false if we have reached the end of the buffer 253 * @param aRed where to store the red value 254 * @param aGreen where to store the green value 255 * @param aBlue where to store the blue value 256 */ 257 bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue) 258 { 259 bool rc = false; 260 if (mPos + PIX_SIZE <= mSize) 261 { 262 *aRed = mBuffer[mPos + 2]; 263 *aGreen = mBuffer[mPos + 1]; 264 *aBlue = mBuffer[mPos]; 265 mPos += PIX_SIZE; 266 rc = true; 267 } 268 return rc; 269 } 270 271 /** 272 * Skip forward by a certain number of pixels 273 * @param aPixels how many pixels to skip 274 */ 275 void skip(unsigned aPixels) 276 { 277 mPos += PIX_SIZE * aPixels; 278 } 279 private: 280 /** Size of the picture buffer */ 281 unsigned mSize; 282 /** Current position in the picture buffer */ 283 unsigned mPos; 284 /** Address of the picture buffer */ 285 uint8_t *mBuffer; 286 }; 287 288 /** 289 * Iterator class for running through an BGR565 image buffer and converting 290 * it to RGB. 291 */ 292 class FFmpegBGR565Iter 293 { 294 private: 295 enum { PIX_SIZE = 2 }; 296 public: 297 FFmpegBGR565Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuffer) 298 { 299 mPos = 0; 300 mSize = aWidth * aHeight * PIX_SIZE; 301 mBuffer = aBuffer; 302 } 303 /** 304 * Convert the next pixel to RGB. 305 * @returns true on success, false if we have reached the end of the buffer 306 * @param aRed where to store the red value 307 * @param aGreen where to store the green value 308 * @param aBlue where to store the blue value 309 */ 310 bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue) 311 { 312 bool rc = false; 313 if (mPos + PIX_SIZE <= mSize) 314 { 315 unsigned uFull = (((unsigned) mBuffer[mPos + 1]) << 8) 316 | ((unsigned) mBuffer[mPos]); 317 *aRed = (uFull >> 8) & ~7; 318 *aGreen = (uFull >> 3) & ~3 & 0xff; 319 *aBlue = (uFull << 3) & ~7 & 0xff; 320 mPos += PIX_SIZE; 321 rc = true; 322 } 323 return rc; 324 } 325 326 /** 327 * Skip forward by a certain number of pixels 328 * @param aPixels how many pixels to skip 329 */ 330 void skip(unsigned aPixels) 331 { 332 mPos += PIX_SIZE * aPixels; 333 } 334 private: 335 /** Size of the picture buffer */ 336 unsigned mSize; 337 /** Current position in the picture buffer */ 338 unsigned mPos; 339 /** Address of the picture buffer */ 340 uint8_t *mBuffer; 341 }; 342 343 344 /** 345 * Convert an image to YUV420p format 346 * @returns true on success, false on failure 347 * @param aWidth width of image 348 * @param aHeight height of image 349 * @param aDestBuf an allocated memory buffer large enough to hold the 350 * destination image (i.e. width * height * 12bits) 351 * @param aSrcBuf the source image as an array of bytes 352 */ 353 template <class T> 354 inline bool FFmpegWriteYUV420p(unsigned aWidth, unsigned aHeight, uint8_t *aDestBuf, 355 uint8_t *aSrcBuf) 356 { 357 AssertReturn(0 == (aWidth & 1), false); 358 AssertReturn(0 == (aHeight & 1), false); 359 bool rc = true; 360 T iter1(aWidth, aHeight, aSrcBuf); 361 T iter2 = iter1; 362 iter2.skip(aWidth); 363 unsigned cPixels = aWidth * aHeight; 364 unsigned offY = 0; 365 unsigned offU = cPixels; 366 unsigned offV = cPixels + cPixels / 4; 367 for (unsigned i = 0; (i < aHeight / 2) && rc; ++i) 368 { 369 for (unsigned j = 0; (j < aWidth / 2) && rc; ++j) 370 { 371 unsigned red, green, blue, u, v; 372 rc = iter1.getRGB(&red, &green, &blue); 373 if (rc) 374 { 375 aDestBuf[offY] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16; 376 u = (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4; 377 v = (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4; 378 rc = iter1.getRGB(&red, &green, &blue); 379 } 380 if (rc) 381 { 382 aDestBuf[offY + 1] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16; 383 u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4; 384 v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4; 385 rc = iter2.getRGB(&red, &green, &blue); 386 } 387 if (rc) 388 { 389 aDestBuf[offY + aWidth] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16; 390 u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4; 391 v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4; 392 rc = iter2.getRGB(&red, &green, &blue); 393 } 394 if (rc) 395 { 396 aDestBuf[offY + aWidth + 1] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16; 397 u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4; 398 v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4; 399 aDestBuf[offU] = u; 400 aDestBuf[offV] = v; 401 offY += 2; 402 ++offU; 403 ++offV; 404 } 405 } 406 if (rc) 407 { 408 iter1.skip(aWidth); 409 iter2.skip(aWidth); 410 offY += aWidth; 411 } 412 } 413 return rc; 414 } 415 416 417 /** 418 * Convert an image to RGB24 format 419 * @returns true on success, false on failure 420 * @param aWidth width of image 421 * @param aHeight height of image 422 * @param aDestBuf an allocated memory buffer large enough to hold the 423 * destination image (i.e. width * height * 12bits) 424 * @param aSrcBuf the source image as an array of bytes 425 */ 426 template <class T> 427 inline bool FFmpegWriteRGB24(unsigned aWidth, unsigned aHeight, uint8_t *aDestBuf, 428 uint8_t *aSrcBuf) 429 { 430 enum { PIX_SIZE = 3 }; 431 bool rc = true; 432 AssertReturn(0 == (aWidth & 1), false); 433 AssertReturn(0 == (aHeight & 1), false); 434 T iter(aWidth, aHeight, aSrcBuf); 435 unsigned cPixels = aWidth * aHeight; 436 for (unsigned i = 0; (i < cPixels) && rc; ++i) 437 { 438 unsigned red, green, blue; 439 rc = iter.getRGB(&red, &green, &blue); 440 if (rc) 441 { 442 aDestBuf[i * PIX_SIZE] = red; 443 aDestBuf[i * PIX_SIZE + 1] = green; 444 aDestBuf[i * PIX_SIZE + 2] = blue; 445 } 446 } 447 return rc; 448 } 188 449 189 450 #endif /* !_H_FFMPEGFB */
Note:
See TracChangeset
for help on using the changeset viewer.