You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+183Lines changed: 183 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -698,3 +698,186 @@ But to make sure that I'm not lying to you. You can use the amazing site/tool [g
698
698
As you can see it has a single `mdat` atom/box, **this is place where the video and audio frames are**. Now load the fragmented mp4 to see which how it spreads the `mdat` boxes.
> #### TLDR; show me the [code](/3_transcoding.c) and execution.
705
+
> ```bash
706
+
> $ make run_transcoding
707
+
>```
708
+
> We'll skip some details, but don't worry: the [source code is available at github](/3_transcoding.c).
709
+
710
+
711
+
712
+
In this chapter, we're going to create a minimalist transcoder, written in C, that can convert videos coded in H264 to H265 using **FFmpeg/libav** library specifically [libavcodec](https://ffmpeg.org/libavcodec.html), libavformat, and libavutil.
> _Just a quick recap:_ **AVFormatContext** is the abstraction for the format of the media file, aka container (ex: MKV, MP4, Webm, TS), the **AVStream** represents each type of data for a given format (ex: audio, video, subtitle, metadata), **AVPacket** is a slice of compressed data obtained from the AVStream that can be decoded by an **AVCodec** (ex: av1, h264, vp9, hevc) generating a raw data called **AVFrame**.
716
+
717
+
### Transmuxing
718
+
719
+
Let's start with the simple transmuxing operation and then we can build upon this code, the first step is to **load the input file**.
// Read packets of a media file to get stream information.
727
+
avformat_find_stream_info(avfc, NULL);
728
+
```
729
+
730
+
Now we're going to set up the decoder, the `AVFormatContext` will give us access to all the `AVStream` components and for each one of them, we can get their `AVCodec` and create the respective `AVCodecContext` and finally we can open the given codec so we can proceed to the decode process.
731
+
`
732
+
> The **AVCodecContext** holds data about media configuration such as bit rate, frame rate, sample rate, channels, height, and many others.
We need to prepare the output media file for transmuxing as well, we first **allocate memory** for the output `AVFormatContext`. We create **each stream** in the output format. In order to pack the stream properly, we **copy the codec parameters** from the decoder.
746
+
747
+
We **set the flag**`AV_CODEC_FLAG_GLOBAL_HEADER` which tells the encoder that it can use the global headers and finally we open the output **file for write** and persist the headers.
We're getting the `AVPacket`'s from the decoder, adjusting the timestamps, and write the packet properly to the output file. Even though the function `av_interleaved_write_frame` says "write frame" we are storing the packet. We finish the transmuxing process by writing the stream trailer to the file.
764
+
765
+
```c
766
+
AVFrame *input_frame = av_frame_alloc();
767
+
AVPacket *input_packet = av_packet_alloc();
768
+
769
+
while (av_read_frame(decoder_avfc, input_packet) >= 0)
The previous section showed a simple transmuxer program, now we're going to add the capability to encode files, specifically we're going to enable it to transcode videos from `h264` to `h265`.
781
+
782
+
After we prepared the decoder but before we prepare the output media file we're going to set up the encoder.
783
+
784
+
* Create the video `AVStream` in the encoder,
785
+
* Use the `AVCodec` called `libx265`,
786
+
* Create the `AVCodecContext` based in the created codec,
787
+
* Set up basic attributes for the transcoding session, and
788
+
* Open the codec and copy parameters from the context to the stream.
0 commit comments