--- a/hedgewars/avwrapper/avwrapper.c Sun Mar 20 01:16:11 2016 -0400
+++ b/hedgewars/avwrapper/avwrapper.c Sun Mar 20 03:08:51 2016 -0400
@@ -333,15 +333,13 @@
g_pVFrame = av_frame_alloc();
if (!g_pVFrame)
return FatalError("Could not allocate frame");
+ av_frame_unref(g_pVFrame);
g_pVFrame->width = g_Width;
g_pVFrame->height = g_Height;
g_pVFrame->format = AV_PIX_FMT_YUV420P;
- g_pVFrame->linesize[0] = g_Width;
- g_pVFrame->linesize[1] = g_Width/2;
- g_pVFrame->linesize[2] = g_Width/2;
- g_pVFrame->linesize[3] = 0;
- return 0;
+
+ return avcodec_default_get_buffer2(g_pVideo, g_pVFrame, 0);
}
static int WriteFrame(AVFrame* pFrame)
@@ -418,11 +416,47 @@
}
}
-AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr)
+AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t *buf)
{
- g_pVFrame->data[0] = pY;
- g_pVFrame->data[1] = pCb;
- g_pVFrame->data[2] = pCr;
+ int x, y, stride = g_Width * 4;
+ uint8_t *data[3];
+
+ // copy pointers, prepare source
+ memcpy(data, g_pVFrame->data, sizeof(data));
+ buf += (g_Height - 1) * stride;
+
+ // convert to YUV 4:2:0
+ for (y = 0; y < g_Height; y++) {
+ for (x = 0; x < g_Width; x++) {
+ int r = buf[x * 4 + 0];
+ int g = buf[x * 4 + 1];
+ int b = buf[x * 4 + 2];
+
+ int luma = (int)(0.299f * r + 0.587f * g + 0.114f * b);
+ data[0][x] = av_clip_uint8(luma);
+
+ if (!(x & 1) && !(y & 1)) {
+ int r = (buf[x * 4 + 0] + buf[(x + 1) * 4 + 0] +
+ buf[x * 4 + 0 + stride] + buf[(x + 1) * 4 + 0 + stride]) / 4;
+ int g = (buf[x * 4 + 1] + buf[(x + 1) * 4 + 1] +
+ buf[x * 4 + 1 + stride] + buf[(x + 1) * 4 + 1 + stride]) / 4;
+ int b = (buf[x * 4 + 2] + buf[(x + 1) * 4 + 2] +
+ buf[x * 4 + 2 + stride] + buf[(x + 1) * 4 + 2 + stride]) / 4;
+
+ int cr = (int)(-0.14713f * r - 0.28886f * g + 0.436f * b);
+ int cb = (int)( 0.615f * r - 0.51499f * g - 0.10001f * b);
+ data[1][x / 2] = av_clip_uint8(128 + cr);
+ data[2][x / 2] = av_clip_uint8(128 + cb);
+ }
+ }
+ buf += -stride;
+ data[0] += g_pVFrame->linesize[0];
+ if (y & 1) {
+ data[1] += g_pVFrame->linesize[1];
+ data[2] += g_pVFrame->linesize[2];
+ }
+ }
+
return WriteFrame(g_pVFrame);
}