<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>FFmpeg | Haksung</title><link>https://haksungjang.github.io/en/tags/ffmpeg/</link><description>Haksung Jang — Open Source Program Manager at SK telecom</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Fri, 20 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://haksungjang.github.io/en/tags/ffmpeg/index.xml" rel="self" type="application/rss+xml"/><item><title>Rockchip and FFmpeg: A License Dispute Case Study</title><link>https://haksungjang.github.io/en/blog/2026/02/20/rockchip-and-ffmpeg-a-license-dispute-case-study/</link><pubDate>Fri, 20 Feb 2026 00:00:00 +0000</pubDate><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Haksung Jang</dc:creator><guid>https://haksungjang.github.io/en/blog/2026/02/20/rockchip-and-ffmpeg-a-license-dispute-case-study/</guid><description> This article was written using Claude Code, and the key facts cited were cross-verified against primary sources.
Notice This article reflects the author&amp;rsquo;s personal analysis and summary, and does not constitute legal advice. The facts cited have been verified based on publicly available sources, but legal determinations such as whether infringement has occurred are matters that can be disputed, so please have specific matters reviewed by an attorney or other expert.</description><content:encoded>&lt;![CDATA[<div class="alert alert-info" role="alert"><p>This article was written using Claude Code, and the key facts cited were cross-verified against primary sources.</p></div><div class="alert alert-warning" role="alert"><div class="h4 alert-heading" role="heading">Notice</div><p>This article reflects the author&rsquo;s personal analysis and summary, and does not constitute legal advice. The facts cited have been verified based on publicly available sources, but legal determinations such as whether infringement has occurred are matters that can be disputed, so please have specific matters reviewed by an attorney or other expert.</p></div><p>Hello.</p><p>I have put together a summary of the Rockchip and FFmpeg license dispute, which became a hot topic in the embedded Linux industry.
I first wrote this article in December 2025, when the repository was taken down. Since then, Rockchip has taken action and the repository was restored. I have thoroughly revised the article to reflect these developments, and replaced the evidence with the actual code that became available for review once the repository reopened.</p><p>This case is not just about one company&rsquo;s mistake. It also shows the kind of supply chain risk that comes with taking an SDK or BSP provided by a hardware vendor and using it as-is, and how a misunderstanding of licensing can inflate a simple fix into a two-year-long task.</p><p><img src="/blog/2026/02/20/rockchip%EA%B3%BC-ffmpeg%EC%9D%98-%EB%9D%BC%EC%9D%B4%EC%84%A0%EC%8A%A4-%EB%B6%84%EC%9F%81-%EC%82%AC%EB%A1%80/featured-image.jpg" alt="An illustration symbolizing the Rockchip and FFmpeg license dispute"/><h2 id="1-overview-of-the-incident">1. Overview of the Incident</h2><p>In December 2025, Rockchip&rsquo;s GitHub repository<code>rockchip-linux/mpp</code> (Media Process Platform) was disabled. This was in response to a DMCA (Digital Millennium Copyright Act) takedown notice filed by an FFmpeg contributor.</p><p>Rockchip has provided a middleware library called<code>mpp</code> for hardware video acceleration on its chipsets (such as the RK3588). The problem is that this library&rsquo;s stream header parser code came from FFmpeg&rsquo;s<code>libavcodec</code>. Simply taking the code was not, by itself, the problem; the compliance violation arose from three overlapping acts. Rockchip deleted the original copyright notices, rewrote the headers to make it appear that Rockchip was the author, and redistributed code that had been LGPL 2.1 under Apache-2.0.</p><p>The notice specified exactly these three acts, and stated as grounds for infringement that this is &ldquo;evident from the identical code structure and comments, including commented-out calls to FFmpeg internal functions retained under their original names.&rdquo;</p><h3 id="timeline">Timeline</h3><p><img src="/blog/2026/02/20/rockchip%EA%B3%BC-ffmpeg%EC%9D%98-%EB%9D%BC%EC%9D%B4%EC%84%A0%EC%8A%A4-%EB%B6%84%EC%9F%81-%EC%82%AC%EB%A1%80/dispute-timeline-en.png" alt="The timeline from FFmpeg’s public callout in February 2024, which went uncorrected for about 22 months, through the DMCA notice in December 2025 that took the repository down, to its restoration roughly 10 weeks later in early March 2026"/><p><strong>Figure 1.</strong> Dispute timeline<em>(Source: DMCA notice, MPP commit history, Issues 530 and 73, Internet Archive. Verified 2026-07-23.)</em></p><p>The exact date the repository reopened was not publicly disclosed. Internet Archive snapshots returned HTTP 451 (Unavailable for Legal Reasons) through March 6, 2026, and new forks began appearing starting March 11, so the reopening is estimated to have occurred sometime in between. The repository was inactive for roughly 10 weeks.</p><p>One point worth noting about the DMCA process: it is commonly said that a platform must take content down within a set time after receiving a notice, but 17 U.S.C. §512(c)(1)(C) of the US Copyright Act only uses the term &ldquo;expeditiously,&rdquo; with no specific deadline. As a matter of operating policy, GitHub gives repository owners roughly one business day to self-correct when a notice identifies specific files, before taking the repository down.</p><h2 id="2-what-was-copied">2. What Was Copied</h2><p>The notice identified 12 infringing files: 4 related to AV1, 3 related to H.265, and 5 related to VP9. With the repository restored, it became possible to pull the commit as it stood at the time infringement was alleged and compare it directly against the FFmpeg original. Below are the results of that comparison.</p><h3 id="copyright-header-replacement">Copyright Header Replacement</h3><p>The header from FFmpeg&rsquo;s<code>libavcodec/vpx_rac.h</code>:</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">/*</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * Copyright (C) 2006 Aurelien Jacobs &lt;aurel@gnuage.org&gt;</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> *</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * This file is part of FFmpeg.</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> *</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * FFmpeg is free software; you can redistribute it and/or</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * modify it under the terms of the GNU Lesser General Public</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * License as published by the Free Software Foundation; either</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * version 2.1 of the License, or (at your option) any later version.</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">...</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">*/</span></span></span></code></pre></div><p>The same location in MPP&rsquo;s<code>mpp/codec/dec/vp9/vpx_rac.h</code>:</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">/*</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">*</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">* Copyright 2015 Rockchip Electronics Co. LTD</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">*</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">* Licensed under the Apache License, Version 2.0 (the "License");</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">* you may not use this file except in compliance with the License.</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">...</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">*/</span></span></span></code></pre></div><p>The name of the original author, Aurelien Jacobs, the LGPL terms, and any reference to FFmpeg all disappeared, replaced with an Apache-2.0 header under Rockchip&rsquo;s name. The original authors of<code>vpx_rac.c</code>, Fiona Glaser, and of<code>vp9data.h</code>, Ronald S. Bultje and Clément Bœsch, likewise vanished without a trace.</p><h3 id="matching-function-bodies">Matching Function Bodies</h3><p>Let&rsquo;s compare the core function of the VP9 range coder.</p><p>FFmpeg<code>libavcodec/vpx_rac.h</code>:</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">static</span><span style="color:#000">av_always_inline</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">vpx_rac_get_prob</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">VPXRangeCoder</span><span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">c</span><span style="color:#000;font-weight:bold">,</span><span style="color:#204a87;font-weight:bold">uint8_t</span><span style="color:#000">prob</span><span style="color:#000;font-weight:bold">)</span></span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">unsigned</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">vpx_rac_renorm</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">c</span><span style="color:#000;font-weight:bold">);</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">unsigned</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">low</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#ce5c00;font-weight:bold">+</span><span style="color:#000;font-weight:bold">(((</span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">high</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">)</span><span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">prob</span><span style="color:#000;font-weight:bold">)</span><span style="color:#ce5c00;font-weight:bold">&gt;&gt;</span><span style="color:#0000cf;font-weight:bold">8</span><span style="color:#000;font-weight:bold">);</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">unsigned</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">low_shift</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">low</span><span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span><span style="color:#0000cf;font-weight:bold">16</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">bit</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">&gt;=</span><span style="color:#000">low_shift</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span/></span><span style="display:flex;"><span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">high</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">bit</span><span style="color:#ce5c00;font-weight:bold">?</span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">high</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#f57900">low</span><span style="color:#000;font-weight:bold">:</span><span style="color:#000">low</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">bit</span><span style="color:#ce5c00;font-weight:bold">?</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#f57900">low_shift</span><span style="color:#000;font-weight:bold">:</span><span style="color:#000">code_word</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span/></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#000">bit</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div><p>MPP<code>mpp/codec/dec/vp9/vpx_rac.c</code> (commit<code>14667441</code>, as of the time infringement was alleged):</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#000">rk_s32</span><span style="color:#000">vpx_rac_get_prob</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">VpxRangeCoder</span><span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">c</span><span style="color:#000;font-weight:bold">,</span><span style="color:#204a87;font-weight:bold">uint8_t</span><span style="color:#000">prob</span><span style="color:#000;font-weight:bold">)</span></span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">unsigned</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">vpx_rac_renorm</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">c</span><span style="color:#000;font-weight:bold">);</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">unsigned</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">low</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#ce5c00;font-weight:bold">+</span><span style="color:#000;font-weight:bold">(((</span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">high</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">)</span><span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">prob</span><span style="color:#000;font-weight:bold">)</span><span style="color:#ce5c00;font-weight:bold">&gt;&gt;</span><span style="color:#0000cf;font-weight:bold">8</span><span style="color:#000;font-weight:bold">);</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">unsigned</span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">low_shift</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">low</span><span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span><span style="color:#0000cf;font-weight:bold">16</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">int</span><span style="color:#000">bit</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">&gt;=</span><span style="color:#000">low_shift</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span/></span><span style="display:flex;"><span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">high</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">bit</span><span style="color:#ce5c00;font-weight:bold">?</span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">high</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#f57900">low</span><span style="color:#000;font-weight:bold">:</span><span style="color:#000">low</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span><span style="color:#000">c</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">bit</span><span style="color:#ce5c00;font-weight:bold">?</span><span style="color:#000">code_word</span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#f57900">low_shift</span><span style="color:#000;font-weight:bold">:</span><span style="color:#000">code_word</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span/></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#000">bit</span><span style="color:#000;font-weight:bold">;</span></span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div><p>The only changes are dropping the inline specifier and changing the return type from<code>int</code> to<code>rk_s32</code>. The function body is identical down to the whitespace, and the<code>uint8_t</code> parameter type and<code>unsigned int</code> in the body remain exactly as written in FFmpeg.</p><h3 id="traces-left-in-the-code">Traces Left in the Code</h3><p>Comments unrelated to functionality are exactly what reveal provenance. The following comments remained untouched in the MPP files.</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">// branchy variant, to be used where there's a branch based on the bit decoded</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">// rounding is different than vpx_rac_get, is vpx_rac_get wrong?</span></span></span></code></pre></div><p>The first is a word-for-word match with FFmpeg&rsquo;s<code>vpx_rac.h</code>. The second is a question the FFmpeg developer posed to themselves; the original refers to<code>vp56_rac_get</code>, and MPP simply substituted its own function name while carrying the comment over unchanged. A rhetorical question-style comment like this could not coincidentally appear as an identical sentence in independently written code.</p><p>At the top of the file, a description referring to a codec that MPP doesn&rsquo;t even support was left in place.</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">/**</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> * vp56 specific range coder implementation</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"> */</span></span></span></code></pre></div><p>In FFmpeg, this description exists because the file is shared across VP5 through VP9, but it carried straight over into MPP, which doesn&rsquo;t handle VP5 or VP6 at all. There is also a spot where an alignment macro was redefined to do nothing.</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#define DECLARE_ALIGNED(n,t,v) t v</span></span></span></code></pre></div><p>This macro name exists in both FFmpeg and libvpx, so by itself it doesn&rsquo;t establish provenance. However, where it is used tracks FFmpeg exactly. FFmpeg&rsquo;s<code>vp56.h</code> declares the first field of its motion vector struct as<code>DECLARE_ALIGNED(4, int16_t, x);</code>, and MPP&rsquo;s corresponding struct carries this line over verbatim. The equivalent struct in libvpx does not use this macro at all.</p><p>A match at this level would be unlikely to survive a substantial similarity analysis under copyright law. Changing type names or macros alone does not make a work independent. This approach is sometimes used when absorbing external open source into an internal codebase, and this case demonstrates exactly the risk that carries.</p><h3 id="the-probability-tables-are-a-somewhat-different-matter">The Probability Tables Are a Somewhat Different Matter</h3><p>The codec&rsquo;s probability tables, however, are an area where snap judgments should be avoided. These figures are constants defined in the VP9 bitstream specification, and comments like<code>/* a/l both not split */</code> next to the values are not expressions FFmpeg created either. The same wording already appears in libvpx (Google, BSD-family license), the reference implementation of VP9. FFmpeg, too, should be understood as having taken these from libvpx.</p><p>So the fact that the comments match does not by itself tell us where they were taken from. Placing the three codebases side by side, the point where they diverge is not the wording but the formatting.</p><p>libvpx:</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span><span style="color:#0000cf;font-weight:bold">222</span><span style="color:#000;font-weight:bold">,</span><span style="color:#0000cf;font-weight:bold">34</span><span style="color:#000;font-weight:bold">,</span><span style="color:#0000cf;font-weight:bold">30</span><span style="color:#000;font-weight:bold">},</span><span style="color:#8f5902;font-style:italic">// a/l both not split</span></span></span></code></pre></div><p>FFmpeg:</p><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span><span style="color:#0000cf;font-weight:bold">222</span><span style="color:#000;font-weight:bold">,</span><span style="color:#0000cf;font-weight:bold">34</span><span style="color:#000;font-weight:bold">,</span><span style="color:#0000cf;font-weight:bold">30</span><span style="color:#000;font-weight:bold">}</span><span style="color:#8f5902;font-style:italic">/* a/l both not split */</span><span style="color:#000;font-weight:bold">,</span></span></span></code></pre></div><p>libvpx places a comma and then attaches a<code>//</code> comment, while FFmpeg places a<code>/* */</code> comment before the comma and aligns the numbers to two-character width. MPP&rsquo;s version matches FFmpeg&rsquo;s format byte-for-byte. While the values and wording trace back to libvpx, the formatting fits the conclusion that the actual copying source was the FFmpeg version.</p><p>The reason this distinction matters is clear. In areas where implementing the same algorithm naturally produces similar code, similarity by itself is not grounds for infringement. One has to pin down which version&rsquo;s specific traces were followed.</p><h2 id="3-why-it-took-22-months">3. Why It Took 22 Months</h2><p>This is the part of the case with the most to learn from. The issue was first made public on February 23, 2024. FFmpeg&rsquo;s official account posted the callout on X, and on the same day, the developer maintaining the<code>ffmpeg-rockchip</code> fork opened Issue 530 on the MPP repository to relay it. It took 22 months from there to the DMCA notice.</p><p>Contrary to what is commonly assumed, Rockchip did not stay silent. The person in charge issued a public apology in February 2024, and continued to respond afterward with statements such as &ldquo;it&rsquo;s delayed,&rdquo; &ldquo;it&rsquo;s in progress,&rdquo; and &ldquo;the refactor is on hold.&rdquo; This was a case of responding without correcting.</p><p>Rockchip later revealed the reason for the delay.</p><pre tabindex="0"><code>But after studying the license details, we realised that simply restoring
the LGPL headers would convert the entire MPP library to LGPL-licensed code.
While this is acceptable for dynamically linked libraries, it would mandate
that any project statically linking MPP also adopt the LGPL license.
To avoid this mixed-license scenario, we decided to develop a brand-new parser.</code></pre><p>Rockchip&rsquo;s reasoning was that restoring the LGPL headers would make all of MPP LGPL-licensed, forcing even customer projects that statically link MPP to adopt the LGPL as well. To avoid that outcome, they decided to write a new parser from scratch — but they underestimated the amount of work involved, and progress stalled as it was crowded out by day-to-day work.</p><p>This reasoning is only half right. The first part has a basis. If FFmpeg code was incorporated into MPP, MPP becomes a &ldquo;work based on the Library&rdquo; as that term is used in LGPL 2.1, and Section 2(c) requires that the entire work be licensed under the terms of the LGPL.</p><p>The second part is different. Section 6 provides an exception for combined works, including those using static linking.</p><pre tabindex="0"><code>6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, ...</code></pre><p>A combined work can be distributed under terms of the distributor&rsquo;s choosing. The conditions are that customers must be permitted to modify it for their own use, reverse engineering for debugging must be permitted, and either a re-linkable form must be provided or a shared library mechanism must be used. A customer company that statically links MPP is not required to release its own product under the LGPL.</p><p>Because the license clause was misread, a task that would have ended with restoring the headers instead inflated into a full parser rewrite, and because that task was heavy, it sat neglected for nearly two years. Distribution in a state of violation continued the entire time. This is the kind of way costs balloon when a compliance judgment is wrong.</p><h2 id="4-rockchips-response-and-remaining-issues">4. Rockchip&rsquo;s Response and Remaining Issues</h2><p>After the DMCA notice, Rockchip moved quickly. Within a little over ten days of the notice, it restored the LGPL headers on the 12 identified files, and then went on to replace the VP9, AV1, and H.265 parsers in turn. In mid-February 2026, it announced that it had &ldquo;removed all FFmpeg LGPL code&rdquo; and requested review.</p><p>A substantial portion of this was actually carried out. Eight of the 12 identified files disappeared from the repository, and the range coder was replaced with an implementation with an entirely different function naming scheme and structure. Scanning all 778 source files in the repository for FFmpeg-specific identifiers such as<code>ff_vp9_</code>,<code>av_always_inline</code>,<code>AVCodecContext</code>, and<code>libavcodec</code> turned up none. No source file mentions the LGPL either. The only trace left is the title of the restoration commit in the changelog document.</p><p>Still, a few things remain.</p><p>The identified file<code>vp9data.h</code> was not deleted; it was renamed to<code>vp9d_codec.c</code>. In the commit history, this file&rsquo;s status is shown as a rename, not a deletion. In the process, the header was changed again. The FFmpeg copyright notice and LGPL terms that the LGPL-restoration commit had added were removed, reverting to sole Rockchip copyright with an Apache-2.0 notice. The two commits were made the same day, three hours apart. Of 1,299 lines, 1,045 remain unchanged, and the probability tables and comments also remain in the FFmpeg formatting seen earlier.</p><p>Files not listed in the notice were left untouched. In the hardware abstraction layer&rsquo;s<code>hal_vp9d_com.c</code>, the VP9 probability tables discussed earlier remain in FFmpeg&rsquo;s exact formatting. This bears out the caveat the notice attached before its file list: &ldquo;(and possibly others).&rdquo;</p><p>Whether this portion constitutes infringement is hard to say definitively. Since the values and comment wording trace back to libvpx and the specification document, the scope of copyright protection itself is open to dispute.</p><p>Above all, there is no public record that FFmpeg has reviewed or accepted this state of affairs. Issue 530 was closed on April 1, 2026, but it was closed by the third-party fork maintainer who had opened it, not by the FFmpeg project. That is not the same as a release from the rights holder. Neither side has stated a policy on how already-distributed past versions will be handled.</p><h2 id="5-why-license-laundering-is-dangerous">5. Why License Laundering Is Dangerous</h2><p>It is easy to assume that &ldquo;code released under Apache-2.0 is safe.&rdquo; This case shows that Apache-2.0 code with an opaque copyright provenance can actually be a greater risk. This is because it is the code&rsquo;s actual origin, not its stated license, that determines the obligations that attach to it.</p><p>Mapping each violation to the relevant clause looks like this.</p><table><thead><tr><th style="text-align: left">Act</th><th style="text-align: left">Relevant LGPL 2.1 Section</th></tr></thead><tbody><tr><td style="text-align: left">Deleting copyright notices</td><td style="text-align: left">Section 1 — keep intact the notices concerning the license and disclaimer of warranty</td></tr><tr><td style="text-align: left">Failing to disclose modifications</td><td style="text-align: left">Section 2(b) — mark modified files with a notice stating that they were changed, along with the date</td></tr><tr><td style="text-align: left">Not licensing the entire work</td><td style="text-align: left">Section 2(c) — license the entire work under the terms of this license</td></tr><tr><td style="text-align: left">Relicensing under Apache-2.0</td><td style="text-align: left">Section 3 (permits conversion to the GPL only) and Section 8 (any other disposition is void; rights terminate automatically)</td></tr></tbody></table><p>Falsely altering attribution is treated differently depending on the country. In Korea and France, this constitutes infringement of the right of attribution, one of the moral rights of authors. US copyright law has no general moral rights regime; the Visual Artists Rights Act (VARA) applies only, and narrowly, to works of visual art.</p><h3 id="what-the-correct-structure-looks-like">What the Correct Structure Looks Like</h3><p>The Linux kernel provides a standard interface called V4L2 (Video for Linux 2) for hardware acceleration. In this structure, FFmpeg is left unmodified in user space, and hardware-dependent code is kept separate in the kernel driver.</p><p><img src="/blog/2026/02/20/rockchip%EA%B3%BC-ffmpeg%EC%9D%98-%EB%9D%BC%EC%9D%B4%EC%84%A0%EC%8A%A4-%EB%B6%84%EC%9F%81-%EC%82%AC%EB%A1%80/architecture-comparison-en.png" alt="In the problematic structure, an application reaches the hardware through the MPP library, which embeds copied FFmpeg code, whereas in the standards-compliant structure, unmodified FFmpeg calls the same hardware through the kernel’s V4L2 interface"/><p><strong>Figure 2.</strong> Comparison of hardware acceleration integration structures</p><p>Because FFmpeg and the kernel driver are cleanly separated into user space and kernel space, there is no longer any reason for a vendor to tear apart and redistribute FFmpeg code itself.</p><p>Progress in this direction was led not by Rockchip but by Collabora. Decoder support for the RK3588&rsquo;s VDPU381 and the RK3576&rsquo;s VDPU383 was merged into mainline in February 2026 and landed in Linux 7.0 (April 2026). The current scope covers H.264 and H.265, while AV1, VP9, and multi-core decoding remain as follow-up work.</p><p>One point of caution: the<code>nyanmisaka/ffmpeg-rockchip</code> fork, commonly mentioned by developers using Rockchip hardware as an alternative, does not replace MPP. This project is an FFmpeg fork that implements hardware acceleration by calling MPP and librga, so it does not avoid MPP&rsquo;s provenance problem. To escape the dependency on MPP, one must use the mainline V4L2 path.</p><h2 id="6-the-allwinner-case-ten-years-earlier">6. The Allwinner Case, Ten Years Earlier</h2><p>There is a history of embedded chip vendors repeating the same mistake with multimedia codec licenses. The closest precedent is Allwinner&rsquo;s CedarX from 2015.</p><table><thead><tr><th style="text-align: left">Point of Comparison</th><th style="text-align: left">Allwinner CedarX (2015)</th><th style="text-align: left">Rockchip MPP (2025-2026)</th></tr></thead><tbody><tr><td style="text-align: left">Distribution form</td><td style="text-align: left">Centered on binary blobs</td><td style="text-align: left">Source released</td></tr><tr><td style="text-align: left">Nature of violation</td><td style="text-align: left">Included code derived from FFmpeg&rsquo;s<code>libavcodec</code> in the user-space CedarX library without releasing source</td><td style="text-align: left">Copied FFmpeg code, then removed copyright notices, changed attribution to Rockchip, and relicensed under Apache-2.0</td></tr><tr><td style="text-align: left">Response</td><td style="text-align: left">Community reverse-engineered the Cedrus driver, later merged upstream</td><td style="text-align: left">DMCA takedown, repository disabled, parser rewritten, V4L2 driver pursued on a separate track</td></tr><tr><td style="text-align: left">Lesson</td><td style="text-align: left">Binary distribution makes violations easy to hide, but they eventually surface through symbol analysis</td><td style="text-align: left">Even with source released, erasing provenance and relicensing is still a violation — and it leaves clearer evidence behind</td></tr></tbody></table><p>In March 2015, Allwinner put out an &ldquo;LGPL release,&rdquo; but in practice it amounted to no more than an API layer wrapping a closed binary. The eventual resolution was that a Cedrus driver, reverse-engineered by the community, was merged upstream. This is structurally similar to how, in the Rockchip case, the V4L2 driver work was led by Collabora.</p><p>There are also cases where a license violation led to actual monetary liability. On February 14, 2024, the Paris Court of Appeal ordered damages of 800,000 euros in the lawsuit Entr&rsquo;ouvert brought against Orange. This consisted of 500,000 euros in economic damages, 150,000 euros for infringement of moral rights, and 150,000 euros in restitution of unjust enrichment, with 60,000 euros in litigation costs added separately. This was the conclusion reached 13 years after the suit was filed in 2011, following a first-instance trial, an appeal, and a remand from the Court of Cassation. This ruling matters because it treated the open source license violation as copyright infringement rather than as a breach of contract.</p><p>In Germany, the Hamburg Regional Court held in the 2013 Fantec case that &ldquo;a supplier&rsquo;s assurance of license compliance alone does not provide a defense; the distributor must verify it independently.&rdquo; This applies directly to any company that takes a BSP from an SoC vendor and incorporates it into a product.</p><h2 id="7-what-companies-should-check">7. What Companies Should Check</h2><p>The same problem may be hiding in an SDK or BSP provided by a vendor. Here are three things to check.</p><p>First, a supply-chain license audit. You need to verify that a vendor-supplied library — especially code related to multimedia, graphics, or AI acceleration — retains the original author&rsquo;s license. Even if a vendor claims Apache-2.0 or MIT, if the internal code came from a GPL or LGPL project, the entire product is exposed to risk. Scanning vendor-supplied code with a source code analysis tool such as Black Duck or FOSSID can surface original license notices or copyright markings left inside. As this case shows, the decisive clue is often found in comments unrelated to functionality.</p><p>Second, check whether the vendor&rsquo;s driver is upstream in the mainline kernel. Code merged into mainline has gone through review and license scrutiny by multiple developers, giving it higher reliability than a vendor&rsquo;s own self-managed repository. That said, being mainlined and being feature-complete are separate questions, so you should check the scope of support alongside it.</p><p>Third, internal development rules. When bringing in external open source, committing changes that delete the copyright header at the top of a file or change it to the company&rsquo;s own name should never be permitted. This can be read as willful infringement and becomes damaging evidence in any later dispute. If integration is needed, prefer a linking approach, and make it a standing rule to always preserve the original author&rsquo;s license and copyright notice.</p><h2 id="summary">Summary</h2><p>The Rockchip case shows that releasing source and complying with an open source license are two different things. LGPL code cannot be relicensed under something like Apache-2.0 without the copyright holder&rsquo;s consent, and deleting copyright notices and changing attribution are infringements in themselves.</p><p>The more practical lesson lies in how the delay came about. Because the license clause was misread, a task that should have ended with restoring the headers instead became a full parser rewrite, and its weight left it neglected for nearly two years. License determinations should be made together with legal or compliance teams, and the larger the apparent cost of a remedy looks, the more that determination needs to be double-checked.</p><p>Rather than simply trusting software as delivered by a vendor, it is necessary to periodically check, using a source code analysis tool, what licenses and copyright notices are present, and to have a process in place for using those results to sort out the division of responsibility with the vendor.</p><h2 id="references">References</h2><ul><li><a href="https://github.com/github/dmca/blob/master/2025/12/2025-12-18-ffmpeg.md">FFmpeg DMCA Notice on GitHub (2025-12-18)</a></li><li><a href="https://github.com/rockchip-linux/mpp/issues/530">rockchip-linux/mpp Issue #530 — LGPL license violation reported by upstream FFmpeg</a></li><li><a href="https://github.com/HermanChen/mpp/issues/73">HermanChen/mpp Issue #73 — Official explanation from Rockchip</a></li><li><a href="https://github.com/rockchip-linux/mpp">rockchip-linux/mpp repository</a></li><li><a href="https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt">GNU LGPL 2.1, original text</a></li><li><a href="https://www.law.cornell.edu/uscode/text/17/512">17 U.S.C. §512 (Cornell LII)</a></li><li><a href="https://hackaday.com/2026/01/05/github-disables-rockchips-linux-mpp-repository-after-dmca-request/">Hackaday: GitHub Disables Rockchip&rsquo;s Linux MPP Repository After DMCA Request</a></li><li><a href="https://www.tomshardware.com/software/chinese-semiconductor-outfit-has-linux-mpp-repository-on-github-disabled-after-a-dmca-takedown-request-ffmpeg-team-accuses-it-of-using-libavcodec-code-without-attribution">Tom&rsquo;s Hardware: Rockchip Repository Disabled</a></li><li><a href="https://www.collabora.com/news-and-blog/news-and-events/rk3588-and-rk3576-video-decoders-support-merged-in-the-upstream-linux-kernel.html">Collabora: RK3588 and RK3576 video decoders support merged in the upstream Linux Kernel</a></li><li><a href="https://github.com/webmproject/libvpx">libvpx (VP9 reference implementation)</a></li><li><a href="https://www.cnx-software.com/2015/02/26/allwinners-new-media-codec-library-cedarx-may-infringe-on-open-source-licenses-and-copyrtights/">CNX Software: Allwinner&rsquo;s CedarX May Infringe on Open Source Licenses (2015-02-26)</a></li><li><a href="https://www.cnx-software.com/2015/03/23/allwinner-cedarx-media-codec-library-gpl-lgpl-compliance-update/">CNX Software: Allwinner CedarX GPL/LGPL Compliance Update (2015-03-23)</a></li><li><a href="https://github.com/nyanmisaka/ffmpeg-rockchip">nyanmisaka/ffmpeg-rockchip</a></li></ul><p><em>Revised on July 23, 2026 to reflect subsequent developments.</em></p>
]]></content:encoded></item></channel></rss>