Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ RUN sh /tmp/ebv-setup/build_ffmpeg.sh work && rm -rf /tmp/ebv-setup

COPY environment/workspace/ /home/workspace/
COPY environment/prepare_media.py /root/ebv-prepare_media.py
COPY environment/check_baseline_padding.py /root/ebv-check-baseline-padding.py
RUN set -eux; \
mkdir -p /home/workspace/swscale-impl /home/workspace/media; \
ln -sfn /home/workspace /app; \
cp -a /home/workspace/scaffold/rust/. /home/workspace/swscale-impl/; \
gcc -shared -fPIC -O2 -o /home/workspace/libswscale_public_baseline.so /home/workspace/baseline_wrapper.c \
-I/usr/local/include -Wl,--whole-archive /usr/local/lib/libswscale.a -Wl,--no-whole-archive \
/usr/local/lib/libavutil.a -lm -lpthread; \
FFMPEG_BASELINE_SO=/home/workspace/libswscale_public_baseline.so \
PYTHONPATH=/home/workspace python3 /root/ebv-check-baseline-padding.py; \
rm -f /root/ebv-check-baseline-padding.py; \
python3 /root/ebv-prepare_media.py; \
rm -f /root/ebv-prepare_media.py; \
cp -a /home/workspace/media /home/workspace/swscale-impl/media; \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
"""Real FFmpeg regression. Set FFMPEG_BASELINE_SO to the compiled task shim.

Optionally set FFMPEG_PREVIOUS_BASELINE_SO for byte-for-byte legacy parity.
Run with python3 environment/check_baseline_padding.py from the task directory.
"""
import ctypes
import json
import mmap
import os
from pathlib import Path
import random
import sys
import unittest

WORKSPACE = Path(__file__).resolve().parent / "workspace"
sys.path.insert(0, str(WORKSPACE))
from pixel_formats import allocate_image, image_to_bytes, load_swscale_library

BYTE_POINTER = ctypes.POINTER(ctypes.c_uint8)
BASELINE = os.environ.get("FFMPEG_BASELINE_SO")
PREVIOUS = os.environ.get("FFMPEG_PREVIOUS_BASELINE_SO")


def convert(library, width, height, fmt, padding, color, negative_stride=False):
"""Keep only logical source pixels readable before a guard page."""
bpp = 3 if fmt in (5, 6) else 4
row_bytes = width * bpp
stride = row_bytes + padding
size = stride * height
page = mmap.PAGESIZE
readable = ((size + page - 1) // page) * page
storage = mmap.mmap(-1, readable + page, prot=mmap.PROT_READ | mmap.PROT_WRITE)
address = ctypes.addressof(ctypes.c_uint8.from_buffer(storage))
libc = ctypes.CDLL(None, use_errno=True)
libc.mprotect.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int]
libc.mprotect.restype = ctypes.c_int
if libc.mprotect(address + readable, page, 0):
raise OSError(ctypes.get_errno(), "mprotect")
first_row = address + readable - size
rng = random.Random(width * 8191 + height * 97 + fmt)
for y in range(height):
data = bytes(rng.randrange(256) for _ in range(row_bytes))
offset = first_row + y * stride
ctypes.memmove(offset, data, len(data))
if padding:
tail = (color * ((padding + len(color) - 1) // len(color)))[:padding]
ctypes.memmove(offset + row_bytes, tail, padding)
src = (BYTE_POINTER * 4)(ctypes.cast(first_row, BYTE_POINTER))
src_stride = (ctypes.c_int * 4)(stride)
if negative_stride:
src[0] = ctypes.cast(first_row + (height - 1) * stride, BYTE_POINTER)
src_stride[0] = -stride
dst, dst_stride, buffers = allocate_image(1, width, height)
ctx = library.swscale_create(width, height, fmt, width, height, 1, 1)
if not ctx:
raise RuntimeError("swscale_create failed")
try:
code = library.swscale_process(ctx, src, src_stride, dst, dst_stride)
if code:
raise RuntimeError(f"swscale_process returned {code}")
return [plane.hex() for plane in image_to_bytes(1, width, height, dst, dst_stride)]
finally:
library.swscale_destroy(ctx)


def isolated_conversion(library, *args, **kwargs):
"""A native fault becomes an assertion result instead of killing the suite."""
import resource

rd, wr = os.pipe()
child = os.fork()
if child == 0:
os.close(rd)
resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
try:
value = {"planes": convert(library, *args, **kwargs)}
except Exception as exc:
value = {"error": str(exc)}
os.write(wr, json.dumps(value).encode())
os._exit(0)
os.close(wr)
with os.fdopen(rd, "rb") as pipe:
payload = pipe.read()
_, status = os.waitpid(child, 0)
if os.WIFSIGNALED(status):
return {"signal": os.WTERMSIG(status)}
if os.WEXITSTATUS(status):
return {"exit_code": os.WEXITSTATUS(status)}
return json.loads(payload)


@unittest.skipUnless(BASELINE and hasattr(os, "fork"), "requires FFMPEG_BASELINE_SO and POSIX")
class ReferencePaddingTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.library = load_swscale_library(BASELINE)
cls.previous = load_swscale_library(PREVIOUS) if PREVIOUS else None

def assert_success(self, result):
self.assertIn("planes", result, result)
return result["planes"]

def test_tight_odd_inputs_and_padding_independence(self):
for fmt in (5, 6, 7, 8):
for width in (3, 7, 17, 129):
for height in (1, 3, 7):
with self.subTest(fmt=fmt, width=width, height=height):
expected = self.assert_success(isolated_conversion(
self.library, width, height, fmt, 64, b"\0"
))
for padding, color in ((0, b"\0"), (32, b"\xff\0\0"), (32, b"\0\0\xff")):
actual = self.assert_success(isolated_conversion(
self.library, width, height, fmt, padding, color
))
self.assertEqual(actual, expected)

def test_negative_stride(self):
for fmt in (5, 6, 7, 8):
with self.subTest(fmt=fmt):
expected = self.assert_success(isolated_conversion(
self.library, 17, 3, fmt, 64, b"\0", negative_stride=True
))
actual = self.assert_success(isolated_conversion(
self.library, 17, 3, fmt, 0, b"\0", negative_stride=True
))
self.assertEqual(actual, expected)

def test_legacy_even_width_parity(self):
if not self.previous:
self.skipTest("requires FFMPEG_PREVIOUS_BASELINE_SO")
for fmt in (5, 6, 7, 8):
for width in (4, 8, 18, 130):
for height in (1, 3):
with self.subTest(fmt=fmt, width=width, height=height):
before = self.assert_success(isolated_conversion(
self.previous, width, height, fmt, 64, b"\0"
))
after = self.assert_success(isolated_conversion(
self.library, width, height, fmt, 64, b"\0"
))
self.assertEqual(after, before)

def test_legacy_zero_padded_odd_parity(self):
if not self.previous:
self.skipTest("requires FFMPEG_PREVIOUS_BASELINE_SO")
for fmt in (5, 6, 7, 8):
for width in (3, 7, 17, 129):
for height in (1, 3):
with self.subTest(fmt=fmt, width=width, height=height):
before = self.assert_success(isolated_conversion(
self.previous, width, height, fmt, 64, b"\0"
))
after = self.assert_success(isolated_conversion(
self.library, width, height, fmt, 64, b"\0"
))
self.assertEqual(after, before)


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@

#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include <libswscale/swscale.h>
#include <libavutil/pixfmt.h>
#include <libavutil/imgutils.h>
#include <libavutil/mem.h>

/* ── Format mapping (SWS_PIXFMT_* → AVPixelFormat) ─────────────────────── */

Expand Down Expand Up @@ -50,6 +54,9 @@ typedef struct {
struct SwsContext *sws;
int src_h;
int dst_h;
int src_row_bytes;
uint8_t *padded_src[4];
int padded_stride[4];
} BaselineCtx;

/* ── Exported API ──────────────────────────────────────────────────────── */
Expand All @@ -61,6 +68,9 @@ void *swscale_create(int src_w, int src_h, int src_fmt,
enum AVPixelFormat av_dst = map_pixfmt(dst_fmt);
if (av_src == AV_PIX_FMT_NONE || av_dst == AV_PIX_FMT_NONE)
return NULL;
if (src_w <= 0 || src_w == INT_MAX || src_h <= 0 ||
dst_w <= 0 || dst_h <= 0)
return NULL;

struct SwsContext *sws = sws_getContext(
src_w, src_h, av_src,
Expand All @@ -69,14 +79,32 @@ void *swscale_create(int src_w, int src_h, int src_fmt,
if (!sws)
return NULL;

BaselineCtx *ctx = malloc(sizeof(BaselineCtx));
BaselineCtx *ctx = calloc(1, sizeof(BaselineCtx));
if (!ctx) {
sws_freeContext(sws);
return NULL;
}
ctx->sws = sws;
ctx->src_h = src_h;
ctx->dst_h = dst_h;
/* Scalar packed-RGB chroma conversion reads pairs, including a partner
* beyond odd-width rows. Supply a zero-valued partner from owned storage.
* Allocate once per context; common even-width inputs keep the direct path.
*/
if ((src_w & 1) &&
(av_src == AV_PIX_FMT_RGB24 || av_src == AV_PIX_FMT_BGR24 ||
av_src == AV_PIX_FMT_RGBA || av_src == AV_PIX_FMT_BGRA)) {
ctx->src_row_bytes = av_image_get_linesize(av_src, src_w, 0);
int size = av_image_alloc(ctx->padded_src, ctx->padded_stride,
src_w + 1, src_h, av_src, 32);
if (ctx->src_row_bytes < 0 || size < 0) {
av_freep(&ctx->padded_src[0]);
sws_freeContext(sws);
free(ctx);
return NULL;
}
memset(ctx->padded_src[0], 0, size);
}
return ctx;
}

Expand All @@ -88,6 +116,19 @@ int swscale_process(void *opaque,
BaselineCtx *ctx = (BaselineCtx *)opaque;
if (!ctx || !ctx->sws)
return -1;
if (ctx->padded_src[0]) {
if (!src_data || !src_stride || !src_data[0] ||
(src_stride[0] > -ctx->src_row_bytes &&
src_stride[0] < ctx->src_row_bytes))
return -1;
for (int y = 0; y < ctx->src_h; y++) {
memcpy(ctx->padded_src[0] + (ptrdiff_t)y * ctx->padded_stride[0],
src_data[0] + (ptrdiff_t)y * src_stride[0],
ctx->src_row_bytes);
}
src_data = (const uint8_t *const *)ctx->padded_src;
src_stride = ctx->padded_stride;
}
int ret = sws_scale(ctx->sws,
src_data, src_stride,
0, ctx->src_h,
Expand All @@ -100,5 +141,6 @@ void swscale_destroy(void *opaque) {
if (!ctx) return;
if (ctx->sws)
sws_freeContext(ctx->sws);
av_freep(&ctx->padded_src[0]);
free(ctx);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*
* linesize[i] gives the byte stride of plane i (may be larger than the
* minimum row size due to alignment padding).
* For odd-width packed RGB, the scalar baseline completes the last chroma
* pair with a zero-valued pixel, independently of source alignment padding.
*/

#ifndef SWSCALE_API_H
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ COPY environment/workspace/pixel_formats.py environment/workspace/baseline_wrapp
environment/workspace/run_dev_bench.py /opt/tests/
COPY environment/workspace/pixel_formats.py environment/workspace/baseline_wrapper.c /judge/
COPY judge/run.sh judge/eval.sh judge/grade.py /judge/
COPY environment/check_baseline_padding.py /root/ebv-check-baseline-padding.py
RUN set -eux; \
chmod +x /opt/tests/*.sh; \
chmod 755 /judge/run.sh /judge/eval.sh; \
Expand All @@ -39,6 +40,9 @@ RUN set -eux; \
gcc -shared -fPIC -O2 -o /verifier-data/libswscale_baseline.so /judge/baseline_wrapper.c \
-I/usr/local/include -Wl,--whole-archive /usr/local/lib/libswscale.a -Wl,--no-whole-archive \
/usr/local/lib/libavutil.a -lm -lpthread; \
FFMPEG_BASELINE_SO=/verifier-data/libswscale_baseline.so \
PYTHONPATH=/judge python3 /root/ebv-check-baseline-padding.py; \
rm -f /root/ebv-check-baseline-padding.py; \
cp /verifier-data/libswscale_baseline.so /home/workspace/libswscale_public_baseline.so; \
sha256sum /verifier-data/libswscale_baseline.so | awk '{print $1}' > /verifier-data/baseline_hash.txt

Expand Down
2 changes: 1 addition & 1 deletion edgebench/tasks/ffmpeg_swscale_reimplementation/task.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name = "Ffmpeg Swscale Reimplementation"
category = "Systems & Software Engineering"
language = "C++" # as in v1 tasks.jsonl; the deliverable is Rust (or Zig), see NOTES.md
description = "Reimplement FFmpeg's libswscale pixel-format conversion and scaling library in Rust, handling multiple pixel formats and scaling algorithms. A correctness-passing scaffold is provided; the agent must optimize for speed via SIMD."
version = "1.0.0"
version = "1.1.0"
status = "migrated"

[environment]
Expand Down