Comparison of original usage vs agent-improved versions.
It may have multiple (or zero) inputs, potentially of different types (audio or video), each of which receiving data either from a decoder or another complex filtergraph’s output. It also has one or more outputs that feed either an encoder or another complex filtergraph’s input.
The following example diagram represents a complex filtergraph with 3 inputs and 2 outputs (all video): ┌─────────────────────────────────────────────────┐ │ complex filtergraph │ ╞═════════════════════════════════════════════════╡ frames ├───────┐ ┌─────────┐ ┌─────────┐ ┌────────┤ frames ─────────►│input 0├─►│ overlay ├─────►│ overlay ├─►│output 0├────────► ├───────┘ │ │ │ │ └────────┤ frames ├───────┐╭►│ │ ╭►│ │ │ ─────────►│input 1├╯ └─────────┘ │ └─────────┘ │ ├───────┘ │ │ frames ├───────┐ ┌─────┐ ┌─────┬─╯ ┌────────┤ frames ─────────►│input 2├►│scale├►│split├───────────────►│output 1├────────► ├───────┘ └─────┘ └─────┘ └────────┤ └─────────────────────────────────────────────────┘ Frames from second input are overlaid over those from the first. Frames from the third input are rescaled, then the duplicated into two identical streams. One of them is overlaid over the combined first two inputs, with the result exposed as the filtergraph’s first output. The other duplicate ends up being the filtergraph’s second output.
Any supported file format and protocol can serve as input to ffmpeg: Examples: - You can use YUV files as input:
ffmpeg -i /tmp/test%d.Y /tmp/out.mpg
It will use the files:
/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V, /tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
The Y files use twice the resolution of the U and V files. They are raw files, without header. They can be generated by all decent video decoders. You must specify the size of the image with the -s option if ffmpeg cannot guess it.
ffmpeg -i /tmp/test.yuv /tmp/out.avi
test.yuv is a file containing raw YUV planar data. Each frame is composed of the Y plane followed by the U and V planes at half vertical and horizontal resolution.
ffmpeg -i mydivx.avi hugefile.yuv
ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
Converts the audio file a.wav and the raw YUV video file a.yuv to MPEG file a.mpg.
ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2
Converts a.wav to MPEG audio at 22050 Hz sample rate.
A complex filtergraph may consist of multiple, varied inputs (audio or video) and multiple outputs. Inputs can stem from a decoder or another filtergraph, and outputs can lead to an encoder or another filtergraph.
Example: A complex filtergraph with 3 inputs and 2 outputs (all video):
┌─────────────────────────────────────────────────┐
│ Complex Filtergraph │
╞═════════════════════════════════════════════════╡
frames ├───────┐ ┌─────────┐ ┌─────────┐ ┌────────┤ frames
─────────►│input 0├─►│ overlay ├─────►│ overlay ├─►│output 0├────────►
├───────┘ │ │ │ │ └────────┤
frames ├───────┐╭►│ │ ╭►│ │ │
─────────►│input 1├╯ └─────────┘ │ └─────────┘ │
├───────┘ │ │
frames ├───────┐ ┌─────┐ ┌─────┬─╯ ┌────────┤ frames
─────────►│input 2├►│scale├►│split├───────────────►│output 1├────────►
├───────┘ └─────┘ └─────┘ └────────┤
└─────────────────────────────────────────────────┘
Encoders transform raw audio, video, or subtitles into compressed packets. They commonly introduce lossy compression for size reduction. Encoders get input from filtergraph outputs or directly from decoders for subtitles, and their outputs are linked to muxers.
bash
ffmpeg -i /tmp/test%d.Y /tmp/out.mpg
This command processes raw YUV files like /tmp/test0.Y, /tmp/test0.U, /tmp/test0.V.
bash
ffmpeg -i /tmp/test.yuv /tmp/out.avi
bash
ffmpeg -i mydivx.avi hugefile.yuv
bash
ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
Converts audio from a.wav and video from a.yuv to a.mpg.
bash
ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2
Converts a.wav to MPEG audio at a 22050 Hz sample rate.
Transplant a series of commits onto a different starting point. You can also use git rebase to reorder or combine commits: see INTERACTIVE MODE below for how to do that.
git rebase
For example, imagine that you have been working on the topic branch in this history, and you want to "catch up" to the work done on the master branch.
A---B---C topic / D---E---F---G master
You want to transplant the commits you made on topic since it diverged from master (i.e. A, B, and C), on top of the current master. You can do this by running git rebase master while the topic branch is checked out. If you want to rebase topic while on another branch, git rebase master topic is a shortcut for git checkout topic && git rebase master.
A'--B'--C' topic / D---E---F---G master
If there is a merge conflict during this process, git rebase will stop at the first problematic commit and leave conflict markers. If this happens, you can do one of these things:
Resolve the conflict. You can use git diff to find the markers (<<<<<<) and make edits to resolve the conflict. For each file you edit, you need to tell Git that the conflict has been resolved. You can mark the conflict as resolved with git add git rebase --continue.
Stop the git rebase and return your branch to its original state with git rebase --abort.
Skip the commit that caused the merge conflict with git rebase --skip.
Rebasing interactively means that you have a chance to edit the commits which are rebased. You can reorder the commits, and you can remove them (weeding out bad or otherwise unwanted patches). The interactive mode is meant for this type of workflow: 1. have a wonderful idea 2. hack on the code 3. prepare a series for submission 4. submit
where point 2. consists of several instances of a) regular use 1. finish something worthy of a commit 2. commit
b) independent fixup 1. realize that something does not work 2. fix that 3. commit it
Sometimes the thing fixed in b.2. cannot be amended to the not-quite perfect commit it fixes, because that commit is buried deeply in a patch series. That is exactly what interactive rebase is for: use it after plenty of "a"s and "b"s, by rearranging and editing commits, and squashing multiple commits into one. Start it with the last commit you want to retain as-is:
git rebase -i <after-this-commit>
An editor will be fired up with all the commits in your current branch (ignoring merge commits), which come after the given commit. You can reorder the commits in this list to your heart’s content, and you can remove them. The list looks more or less like this:
pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...
The oneline descriptions are purely for your pleasure; git rebase will not look at them but at the commit names ("deadbee" and "fa1afe1" in this example), so do not delete or edit the names. By replacing the command "pick" with the command "edit", you can tell git rebase to stop after applying that commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing.
Git rebase transplants a series of commits onto a different starting point, such as aligning your feature branch with updates in the main branch.
git rebase master
For example, if you have a branch topic diverging from master, and you want to align topic with the latest master:
Before Rebase
A---B---C topic
/
D---E---F---G master
Run:
git checkout topic
git rebase master
After Rebase
D---E---F---G---A'---B'---C' topic
During a rebase, if conflicts arise:
<<<<<<) to identify conflict areas.Edit files, resolve the issues, and mark them resolved:
bash
git add <filename>
git rebase --continue
Abort Rebase:
Cancel the rebase and return the branch to its original state:
bash
git rebase --abort
Skip Commit:
bash
git rebase --skipInteractive rebase allows editing commit history, enabling actions like reordering, squashing, or dropping commits.
git rebase -i <after-this-commit>
Example of command script in the editor:
pick deadbee Commit message one
pick fa1afe1 Commit message two
pick with edit to modify the commit message or content.Example:
edit deadbee Fix a typo in commit one
pick fa1afe1 Improve logging in commit two
This instructs Git to pause for changes after applying each marked commit. To proceed:
# Make changes
git add <files>
git commit --amend
git rebase --continue
Interactive rebase is beneficial for maintaining a clean commit history before submission or sharing.
A Pod (as in a pod of whales or pea pod) is a group of one or more containers, with shared storage and network resources, and a specification for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific "logical host": it contains one or more application containers which are relatively tightly coupled.
Pods in a Kubernetes cluster are used in two main ways: - Pods that run a single container. The "one-container-per-Pod" model is the most common Kubernetes use case; in this case, you can think of a Pod as a wrapper around a single container; Kubernetes manages Pods rather than managing the containers directly. - Pods that run multiple containers that need to work together. A Pod can encapsulate an application composed of multiple co-located containers that are tightly coupled and need to share resources. These co-located containers form a single cohesive unit.
Grouping multiple co-located and co-managed containers in a single Pod is a relatively advanced use case. You should use this pattern only in specific instances in which your containers are tightly coupled.
The following is an example of a Pod which consists of a container running the image nginx:1.14.2.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
To create the Pod shown above, run the following command:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
Pods are generally not created directly and are created using workload resources. See Working with Pods for more information on how Pods are used with workload resources.
A Pod is a group of one or more containers with shared storage and network resources. Pods act as "logical hosts" and ensure co-located and co-scheduled execution in a shared context. There are two primary Pod models in Kubernetes:
Single-Container Pods: The most common usage, where a Pod encapsulates a single container, allowing Kubernetes to manage the Pod instead of the container directly.
Multi-Container Pods: These encapsulate tightly coupled, co-located containers that share resources, forming a single cohesive unit. Use this advanced pattern when containers need to work together closely.
Example YAML for a Pod with an Nginx container:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Create the Pod with the following command:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
Pods are commonly created through workload resources; direct creation of Pods SHOULD be avoided for most use cases. For more detailed usage, reference the "Working with Pods" documentation.
CFS stands for “Completely Fair Scheduler,” and is the “desktop” process scheduler implemented by Ingo Molnar and merged in Linux 2.6.23. When originally merged, it was the replacement for the previous vanilla scheduler’s SCHED_OTHER interactivity code. Nowadays, CFS is making room for EEVDF.
80% of CFS’s design can be summed up in a single sentence: CFS basically models an “ideal, precise multi-tasking CPU” on real hardware.
“Ideal multi-tasking CPU” is a (non-existent :-)) CPU that has 100% physical power and which can run each task at precise equal speed, in parallel, each at 1/nr_running speed. For example: if there are 2 tasks running, then it runs each at 50% physical power --- i.e., actually in parallel.
On real hardware, we can run only a single task at once, so we have to introduce the concept of “virtual runtime.” The virtual runtime of a task specifies when its next timeslice would start execution on the ideal multi-tasking CPU described above. In practice, the virtual runtime of a task is its actual runtime normalized to the total number of running tasks.
In CFS the virtual runtime is expressed and tracked via the per-task p->se.vruntime (nanosec-unit) value. This way, it’s possible to accurately timestamp and measure the “expected CPU time” a task should have gotten.
Small detail: on “ideal” hardware, at any time all tasks would have the same p->se.vruntime value --- i.e., tasks would execute simultaneously and no task would ever get “out of balance” from the “ideal” share of CPU time.
CFS’s task picking logic is based on this p->se.vruntime value and it is thus very simple: it always tries to run the task with the smallest p->se.vruntime value (i.e., the task which executed least so far). CFS always tries to split up CPU time between runnable tasks as close to “ideal multitasking hardware” as possible.
Most of the rest of CFS’s design just falls out of this really simple concept, with a few add-on embellishments like nice levels, multiprocessing and various algorithm variants to recognize sleepers.
CFS (Completely Fair Scheduler), introduced by Ingo Molnar in Linux 2.6.23, replaced the prior scheduler’s SCHED_OTHER interactivity code, now evolving towards EEVDF. CFS aims to model an "ideal multi-tasking CPU," an imaginary system where all tasks run in parallel at equal speeds.
Given physical constraints, real hardware can only execute one task at a time. CFS uses "virtual runtime" to simulate this ideal scheduling, normalizing a task's actual runtime based on the total number of active tasks.
CFS tracks virtual runtime per task using p->se.vruntime (measured in nanoseconds). This enables precise tracking of the "expected CPU time" each task should receive.
p->se.vruntime value to run next.Goal: Achieve an "ideal multitasking" environment by distributing CPU time as evenly as possible among runnable tasks.
Task Balancing:
Ideal hardware would show equal p->se.vruntime values for all tasks, implying simultaneous execution with balanced CPU shares.
Additional Features:
To illustrate, consider a scenario with three tasks: A, B, and C, each having different priorities:
// Pseudo-setup of tasks and priorities
set_nice_value(TaskA, 0); // Normal priority
set_nice_value(TaskB, 10); // Lower priority
set_nice_value(TaskC, -10); // Higher priority
// Scheduler selects based on virtual runtime
while (tasks_exist) {
Task *next_task = get_task_with_lowest_vruntime();
execute_task(next_task);
}
CFS ensures that tasks are scheduled in accordance with set priorities and available CPU share, demonstrating its commitment to fair scheduling practices.
The EVP library provides a high-level interface to cryptographic functions.
The EVP_SealXXX and EVP_OpenXXX functions provide public key encryption and decryption to implement digital "envelopes".
The EVP_DigestSignXXX and EVP_DigestVerifyXXX functions implement digital signatures and Message Authentication Codes (MACs). Also see the older EVP_SignXXX and EVP_VerifyXXX functions.
Symmetric encryption is available with the EVP_EncryptXXX functions. The EVP_DigestXXX functions provide message digests.
The EVP_PKEYXXX functions provide a high-level interface to asymmetric algorithms. To create a new EVP_PKEY see EVP_PKEY_new(3). EVP_PKEYs can be associated with a private key of a particular algorithm by using the functions described on the EVP_PKEY_fromdata(3) page, or new keys can be generated using EVP_PKEY_keygen(3). EVP_PKEYs can be compared using EVP_PKEY_eq(3), or printed using EVP_PKEY_print_private(3). EVP_PKEY_todata(3) can be used to convert a key back into an OSSL_PARAM(3) array.
The EVP_PKEY functions support the full range of asymmetric algorithm operations: - For key agreement see EVP_PKEY_derive(3) - For signing and verifying see EVP_PKEY_sign(3), EVP_PKEY_verify(3) and EVP_PKEY_verify_recover(3). However, note that these functions do not perform a digest of the data to be signed. Therefore, normally you would use the EVP_DigestSignInit(3) functions for this purpose. - For encryption and decryption see EVP_PKEY_encrypt(3) and EVP_PKEY_decrypt(3) respectively. However, note that these functions perform encryption and decryption only. As public key encryption is an expensive operation, normally you would wrap an encrypted message in a "digital envelope" using the EVP_SealInit(3) and EVP_OpenInit(3) functions.
The EVP_BytesToKey(3) function provides some limited support for password based encryption. Careful selection of the parameters will provide a PKCS#5 PBKDF1 compatible implementation. However, new applications should not typically use this (preferring, for example, PBKDF2 from PCKS#5).
The EVP_EncodeXXX and EVP_DecodeXXX functions implement base64 encoding and decoding.
The EVP library offers a high-level interface for cryptographic functions:
EVP_SealXXX and EVP_OpenXXX for creating "digital envelopes".EVP_DigestSignXXX and EVP_DigestVerifyXXX. Older alternatives include EVP_SignXXX and EVP_VerifyXXX.EVP_EncryptXXX functions.EVP_DigestXXX functions.EVP_PKEY_new(3). Associate keys via EVP_PKEY_fromdata(3) or generate new ones with EVP_PKEY_keygen(3).EVP_PKEY_eq(3).EVP_PKEY_print_private(3).Conversion: EVP_PKEY_todata(3) for OSSL_PARAM(3) arrays.
Operations Supported:
EVP_PKEY_derive(3)EVP_PKEY_sign(3), EVP_PKEY_verify(3), and EVP_PKEY_verify_recover(3). For digesting data, use EVP_DigestSignInit(3).EVP_PKEY_encrypt(3) and EVP_PKEY_decrypt(3). These operate without data digest; use EVP_SealInit(3) and EVP_OpenInit(3) for "digital envelopes".Password-Based Encryption: EVP_BytesToKey(3) is available but typically, prefer PBKDF2 (PKCS#5).
Base64 Encoding/Decoding: EVP_EncodeXXX and EVP_DecodeXXX functions handle these operations.
// Encrypt using an EVP_PKEY and EVP_Seal functions
EVP_PKEY *pkey;
EVP_PKEY_encrypt_init(ctx);
EVP_PKEY_encrypt(ctx, output, &outlen, input, inlen);
// Sign data using EVP_DigestSign functions
EVP_MD_CTX *mdctx;
EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey);
EVP_DigestSignUpdate(mdctx, data, data_len);
EVP_DigestSignFinal(mdctx, signature, &siglen);