FFmpeg: Handle (apply and undo) patches from an email

Step-by-Step descriptions of how to do things.
Post Reply
User avatar
^rooker
Site Admin
Posts: 1483
Joined: Fri Aug 29, 2003 8:39 pm

FFmpeg: Handle (apply and undo) patches from an email

Post by ^rooker »

There's information about submitting patches for FFmpeg in the official documentation, but I wanted to apply a patchset sent on the ffmpeg-devel mailing list.

My git-foo ain't too great, and I'm used to using the good old "GNU patch" for applying diff-patches. But it seems that using "git apply" is actually the way to go in this case.

I've read "Git tip of the week: Patches by Email (by Al Blue)" and it seemed to work fine.

This text here will describe the following:
  • how to handle a patch for FFmpeg that came by email (mostly from the FFmpeg mailing lists)
  • how to revert the patched files back to the recent git HEAD (useful for reproducing stuff...)

It might seem trivial for most developers who're working with git everyday, but I tend to forget stuff, so I better write it down :)
Jumping out of an airplane is not a basic instinct. Neither is breathing underwater. But put the two together and you're traveling through space!
User avatar
^rooker
Site Admin
Posts: 1483
Joined: Fri Aug 29, 2003 8:39 pm

Patch from email

Post by ^rooker »

Let's begin:

A) How to handle a patch for FFmpeg that came by email (mostly from the FFmpeg mailing lists)
Here's a real world example: A patch for FFv1 to switch to "ThreadFrame"

The mail looks like this:

Code: Select all

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
---
 libavcodec/ffv1.c    |   12 +++++++++---
 libavcodec/ffv1.h    |    3 ++-
 libavcodec/ffv1dec.c |   29 +++++++++++++++++------------
 libavcodec/ffv1enc.c |   16 ++++++++--------
 4 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 404b0e3..8b3d35b 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -48,8 +48,8 @@ av_cold int ffv1_common_init(AVCodecContext *avctx)
     s->avctx = avctx;
     s->flags = avctx->flags;
 
-    avcodec_get_frame_defaults(&s->picture);
-
+    s->picture.f = avcodec_alloc_frame();
+    s->last_picture.f = av_frame_alloc();
...
...
... 
@@ -1014,7 +1014,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     ff_init_range_encoder(c, pkt->data, pkt->size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
-    *p           = *pict;
+    av_frame_ref(p, pict);
     p->pict_type = AV_PICTURE_TYPE_I;
 
     if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
-- 1.7.9.5 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel 
(For a complete copy of what the original mail looked like exactly, take a look at the ffmpeg-devel archive)

Now copy the text in the mail from the first line starting with "diff --git ..." down until the "--" at the bottom, like this:

Code: Select all

diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 404b0e3..8b3d35b 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -48,8 +48,8 @@ av_cold int ffv1_common_init(AVCodecContext *avctx)
...
...
...
...
-    *p           = *pict;
+    av_frame_ref(p, pict);
     p->pict_type = AV_PICTURE_TYPE_I;
 
     if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
Copy/paste that block to a textfile and give it a meaningful name. For example, use the description from the email.
In this case I called it:
"patches/ffv1-threadframe.patch"
(I prefer to put patches in a subfolder of ffmpeg's source, called "patches" - but that's just cosmetics)

Now, in the folder where you've checked out the git-HEAD, apply the patch using "git apply":

Code: Select all

$ git apply -v patches/ffv1-threadframe.patch
If everything's fine, you should see a happy report like this:
Checking patch libavcodec/ffv1.c...
Checking patch libavcodec/ffv1.h...
Checking patch libavcodec/ffv1dec.c...
Checking patch libavcodec/ffv1enc.c...
Applied patch libavcodec/ffv1.c cleanly.
Applied patch libavcodec/ffv1.h cleanly.
Applied patch libavcodec/ffv1dec.c cleanly.
Applied patch libavcodec/ffv1enc.c cleanly.
Jumping out of an airplane is not a basic instinct. Neither is breathing underwater. But put the two together and you're traveling through space!
User avatar
^rooker
Site Admin
Posts: 1483
Joined: Fri Aug 29, 2003 8:39 pm

Re: FFmpeg: Handle (apply and undo) patches from an email

Post by ^rooker »

B) how to revert the patched files back to the recent git HEAD (useful for reproducing stuff...)
This is nice for comparing different patches on the same source.

After applying the above patchset, running "git status" shows you which files got touched:

Code: Select all

$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: libavcodec/ffv1.c
# modified: libavcodec/ffv1.h
# modified: libavcodec/ffv1dec.c
# modified: libavcodec/ffv1enc.c
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# patches/
no changes added to commit (use "git add" and/or "git commit -a")
(You also see the "patches" directory, which was manually added)

"git status" is so nice to already tell you what to do, if you want to discard changes in your working directory.
In our case, I'd do it like this:

Code: Select all

$ git checkout -- libavcodec/ffv1*.[ch]
(If everything went fine, that command returns nothing. So don't worry about its silence)

Now your sourcecode should be reset to its previous version (git HEAD in most cases) - ready to receive other patches :)
Jumping out of an airplane is not a basic instinct. Neither is breathing underwater. But put the two together and you're traveling through space!
Post Reply