331 return FatalError("Could not open video codec %s", g_pVCodec->long_name); |
331 return FatalError("Could not open video codec %s", g_pVCodec->long_name); |
332 |
332 |
333 g_pVFrame = av_frame_alloc(); |
333 g_pVFrame = av_frame_alloc(); |
334 if (!g_pVFrame) |
334 if (!g_pVFrame) |
335 return FatalError("Could not allocate frame"); |
335 return FatalError("Could not allocate frame"); |
|
336 av_frame_unref(g_pVFrame); |
336 |
337 |
337 g_pVFrame->width = g_Width; |
338 g_pVFrame->width = g_Width; |
338 g_pVFrame->height = g_Height; |
339 g_pVFrame->height = g_Height; |
339 g_pVFrame->format = AV_PIX_FMT_YUV420P; |
340 g_pVFrame->format = AV_PIX_FMT_YUV420P; |
340 g_pVFrame->linesize[0] = g_Width; |
341 |
341 g_pVFrame->linesize[1] = g_Width/2; |
342 return avcodec_default_get_buffer2(g_pVideo, g_pVFrame, 0); |
342 g_pVFrame->linesize[2] = g_Width/2; |
|
343 g_pVFrame->linesize[3] = 0; |
|
344 return 0; |
|
345 } |
343 } |
346 |
344 |
347 static int WriteFrame(AVFrame* pFrame) |
345 static int WriteFrame(AVFrame* pFrame) |
348 { |
346 { |
349 double AudioTime, VideoTime; |
347 double AudioTime, VideoTime; |
416 |
414 |
417 return 1; |
415 return 1; |
418 } |
416 } |
419 } |
417 } |
420 |
418 |
421 AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) |
419 AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t *buf) |
422 { |
420 { |
423 g_pVFrame->data[0] = pY; |
421 int x, y, stride = g_Width * 4; |
424 g_pVFrame->data[1] = pCb; |
422 uint8_t *data[3]; |
425 g_pVFrame->data[2] = pCr; |
423 |
|
424 // copy pointers, prepare source |
|
425 memcpy(data, g_pVFrame->data, sizeof(data)); |
|
426 buf += (g_Height - 1) * stride; |
|
427 |
|
428 // convert to YUV 4:2:0 |
|
429 for (y = 0; y < g_Height; y++) { |
|
430 for (x = 0; x < g_Width; x++) { |
|
431 int r = buf[x * 4 + 0]; |
|
432 int g = buf[x * 4 + 1]; |
|
433 int b = buf[x * 4 + 2]; |
|
434 |
|
435 int luma = (int)(0.299f * r + 0.587f * g + 0.114f * b); |
|
436 data[0][x] = av_clip_uint8(luma); |
|
437 |
|
438 if (!(x & 1) && !(y & 1)) { |
|
439 int r = (buf[x * 4 + 0] + buf[(x + 1) * 4 + 0] + |
|
440 buf[x * 4 + 0 + stride] + buf[(x + 1) * 4 + 0 + stride]) / 4; |
|
441 int g = (buf[x * 4 + 1] + buf[(x + 1) * 4 + 1] + |
|
442 buf[x * 4 + 1 + stride] + buf[(x + 1) * 4 + 1 + stride]) / 4; |
|
443 int b = (buf[x * 4 + 2] + buf[(x + 1) * 4 + 2] + |
|
444 buf[x * 4 + 2 + stride] + buf[(x + 1) * 4 + 2 + stride]) / 4; |
|
445 |
|
446 int cr = (int)(-0.14713f * r - 0.28886f * g + 0.436f * b); |
|
447 int cb = (int)( 0.615f * r - 0.51499f * g - 0.10001f * b); |
|
448 data[1][x / 2] = av_clip_uint8(128 + cr); |
|
449 data[2][x / 2] = av_clip_uint8(128 + cb); |
|
450 } |
|
451 } |
|
452 buf += -stride; |
|
453 data[0] += g_pVFrame->linesize[0]; |
|
454 if (y & 1) { |
|
455 data[1] += g_pVFrame->linesize[1]; |
|
456 data[2] += g_pVFrame->linesize[2]; |
|
457 } |
|
458 } |
|
459 |
426 return WriteFrame(g_pVFrame); |
460 return WriteFrame(g_pVFrame); |
427 } |
461 } |
428 |
462 |
429 AVWRAP_DECL int AVWrapper_Init( |
463 AVWRAP_DECL int AVWrapper_Init( |
430 void (*pAddFileLogRaw)(const char*), |
464 void (*pAddFileLogRaw)(const char*), |