### Install AvCpp Project with Meson Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Install the AvCpp project using the 'meson install' command. The project will be installed in the configured prefix, defaulting to /usr/local. ```bash meson install ``` -------------------------------- ### Install AvCpp Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Installs the built AvCpp library to the system after successful compilation. This command typically requires superuser privileges. ```bash sudo make install ``` -------------------------------- ### Build AvCpp Project with Meson Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Create a build directory, navigate into it, and then use Meson to configure and compile the project. Dependencies not installed via package manager will be downloaded and compiled. ```bash mkdir build cd build meson .. meson compile ``` -------------------------------- ### Install AvCpp for Packaging Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Installs AvCpp to a specified destination directory, commonly used for packaging purposes. The `DESTDIR` variable allows staging the installation. ```bash sudo make DESTDIR= install ``` -------------------------------- ### Configure AvCpp Build with Meson Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Configure the Meson build for AvCpp, with options to disable tests and samples. The install prefix can also be set. ```bash meson configure -Dbuild_tests=false meson configure -Dbuild_samples=false ``` -------------------------------- ### Install FFmpeg Packages (Debian/Ubuntu) Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Installs the necessary FFmpeg development packages on Debian, Ubuntu, and Linux Mint systems. Ensure your system meets the version requirements. ```bash sudo apt-get install libavformat-dev \ libavcodec-dev \ libavutil-dev \ libavfilter-dev \ libswscale-dev \ libswresample-dev \ libpostproc-dev \ libavdevice-dev ``` -------------------------------- ### Configure CMake with Custom Install Prefix Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Sets a custom installation prefix for AvCpp during the CMake configuration step. This allows you to control where the library and its components are installed. ```bash cmake -DCMAKE_INSTALL_PREFIX=/usr .. ``` -------------------------------- ### Decode and Encode Audio with av::AudioDecoderContext and av::AudioEncoderContext Source: https://context7.com/h4tr3d/avcpp/llms.txt Audio codec contexts mirror the video API. AudioDecoderContext::decode() returns AudioSamples; AudioEncoderContext::encode() accepts AudioSamples and returns a Packet. Examples show decoding from a packet and encoding samples. ```cpp // -- DECODE -- av::AudioDecoderContext adec(audioStream); adec.setRefCountedFrames(true); adec.open(av::Codec(), ec); av::Packet pkt = ictx.readPacket(ec); av::AudioSamples samples = adec.decode(pkt, ec); std::clog << "samples=" << samples.samplesCount() << " rate=" << samples.sampleRate() << " ch=" << samples.channelsCount() << " fmt=" << (int)samples.sampleFormat() << " layout=" << samples.channelsLayoutString() << "\n"; // -- ENCODE -- av::AudioEncoderContext aenc{av::findEncodingCodec("aac")}; aenc.setSampleRate(44100); aenc.setChannels(2); aenc.setSampleFormat(AV_SAMPLE_FMT_FLTP); aenc.setChannelLayout(AV_CH_LAYOUT_STEREO); aenc.setBitRate(128'000); aenc.open(av::Codec(), ec); av::Packet out_pkt = aenc.encode(samples, ec); if (out_pkt) std::clog << "audio pkt size=" << out_pkt.size() << "\n"; ``` -------------------------------- ### Initialization and Logging Source: https://context7.com/h4tr3d/avcpp/llms.txt Initializes the AvCpp library and configures FFmpeg's log verbosity. `av::init()` must be called once before any other AvCpp API use. `av::setFFmpegLoggingLevel()` accepts standard FFmpeg `AV_LOG_*` constants. ```APIDOC ## av::init() / av::setFFmpegLoggingLevel() ### Description Initialize the AvCpp library and configure FFmpeg's log verbosity. `av::init()` must be called once before any other AvCpp API use. `av::setFFmpegLoggingLevel()` accepts standard FFmpeg `AV_LOG_*` constants. ### Code Example ```cpp #include "avcpp/av.h" #include "avcpp/ffmpeg.h" int main() { av::init(); av::setFFmpegLoggingLevel(AV_LOG_WARNING); // suppress debug noise // ... rest of the program } ``` ``` -------------------------------- ### Build AvCpp with CMake Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Clones the AvCpp repository, initializes submodules, creates a build directory, and configures the project using CMake. Assumes FFmpeg is in a standard location. ```bash git clone --recurse-submodules https://github.com/h4tr3d/avcpp.git avcpp-git cd avcpp-git mkdir build cd build cmake .. make -j8 ``` -------------------------------- ### Initialize AvCpp and Set FFmpeg Logging Level Source: https://context7.com/h4tr3d/avcpp/llms.txt Call `av::init()` once before any other AvCpp API. Configure FFmpeg's log verbosity using `av::setFFmpegLoggingLevel()` with standard FFmpeg constants. ```cpp #include "avcpp/av.h" #include "avcpp/ffmpeg.h" int main() { av::init(); av::setFFmpegLoggingLevel(AV_LOG_WARNING); // suppress debug noise // ... rest of the program } ``` -------------------------------- ### Clone AvCpp Repository with Git Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Clone the AvCpp repository to your local machine. This is the initial step before building with Meson. ```bash git clone https://github.com/h4tr3d/avcpp.git avcpp-git cd avcpp-git ``` -------------------------------- ### Helper Function for Sample Targets Source: https://github.com/h4tr3d/avcpp/blob/master/example/api2-samples/CMakeLists.txt Defines a function to create an executable target, link it with avcpp, and add compile options. It also handles Windows-specific linking. ```cmake function(api2_sample_target target) add_executable(${target} ${target}.cpp) target_link_libraries(${target} avcpp::avcpp ) if (AVCPP_WARNING_OPTIONS) target_compile_options(${target} PRIVATE ${AVCPP_WARNING_OPTIONS}) endif() if(WIN32) target_link_libraries(${target} ws2_32) endif() endfunction() ``` -------------------------------- ### Implementing Custom I/O with av::CustomIO Source: https://context7.com/h4tr3d/avcpp/llms.txt Implement the av::CustomIO interface to read from or write to arbitrary sources like memory buffers or network sockets. Pass the custom IO object to FormatContext::openInput or openOutput. ```cpp struct MemoryIO : public av::CustomIO { std::vector data; size_t pos = 0; int read(uint8_t *buf, size_t size) override { size_t avail = std::min(size, data.size() - pos); if (avail == 0) return AVERROR_EOF; std::memcpy(buf, data.data() + pos, avail); pos += avail; return (int)avail; } int64_t seek(int64_t offset, int whence) override { if (whence == SEEK_SET) pos = offset; else if (whence == SEEK_CUR) pos += offset; else if (whence == SEEK_END) pos = data.size() + offset; else if (whence == AVSEEK_SIZE) return (int64_t)data.size(); return (int64_t)pos; } int seekable() const override { return AVIO_SEEKABLE_NORMAL; } }; MemoryIO io; // io.data = ... (fill with raw container bytes) ... av::FormatContext ctx; ctx.openInput(&io); // AvCpp does not take ownership of io ctx.findStreamInfo(); std::clog << "In-memory streams: " << ctx.streamsCount() << "\n"; ``` -------------------------------- ### Build AvCpp with Old Git Version Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Alternative cloning method for older Git versions that do not support `--recurse-submodules`. Initializes and updates submodules separately. ```bash git submodule init && git submodule update ``` -------------------------------- ### Run AvCpp Tests with Meson Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Execute the tests for the AvCpp project using the 'meson test' command. If tests were disabled during configuration, this command will do nothing. ```bash meson test ``` -------------------------------- ### Integrate AvCpp via FetchContent in CMake Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Use CMake's FetchContent module to declare and make AvCpp available. Link against the avcpp::avcpp target. CMake arguments can be set before FetchContent_MakeAvailable. ```cmake include(FetchContent) FetchContent_Declare( avcpp GIT_REPOSITORY https://github.com/h4tr3d/avcpp.git GIT_TAG v3.0.1 ) FetchContent_MakeAvailable(avcpp) ``` ```cmake target_link_libraries(prog PRIVATE avcpp::avcpp) ``` ```cmake FetchContent_Declare( avcpp ... ) set(AV_ENABLE_STATIC On) set(AV_ENABLE_SHARED Off) FetchContent_MakeAvailable(avcpp) ``` -------------------------------- ### Use AvCpp with Vcpkg Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Specify AvCpp as a dependency in your vcpkg.json file. In your CMakeLists.txt, find the package and link against avcpp::avcpp. ```json { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "dependencies": [ ... "avcpp", ... ], "name": "your-app-name", "version-string": "0.0.1" } ``` ```cmake find_package(avcpp CONFIG REQUIRED) target_link_libraries(prog PRIVATE avcpp::avcpp) ``` -------------------------------- ### List of Sample Targets Source: https://github.com/h4tr3d/avcpp/blob/master/example/api2-samples/CMakeLists.txt Defines a list of sample application targets to be built. This list can be modified by conditional checks. ```cmake set(TARGETS api2-decode api2-decode-encode-video api2-scale-video api2-decode-audio api2-decode-rasample-audio api2-decode-encode-audio api2-decode-filter-encode api2-dict-basic api2-timestamp api2-demux-seek api2-remux api2-hw-encode api2-decode-raw-h264 ) ``` -------------------------------- ### Define AvCpp Samples Project Source: https://github.com/h4tr3d/avcpp/blob/master/example/api2-samples/CMakeLists.txt Sets the minimum CMake version and defines the project name, version, and language. It also finds the avcpp package. ```cmake cmake_minimum_required (VERSION 3.19) # transcoder sources if(NOT DEFINED PROJECT_NAME) set(AVCPP_SAMPLES_NOT_SUBPROJECT ON) endif() project(AvCppSamples LANGUAGES CXX VERSION 2.4.0) if(AVCPP_SAMPLES_NOT_SUBPROJECT) find_package(avcpp REQUIRED) endif() ``` -------------------------------- ### Mux Media: Open Output, Write Header, Packets, Trailer Source: https://context7.com/h4tr3d/avcpp/llms.txt Create an output container, write a file header, flush encoded packets, and finalize with a trailer. `addStream(encoderContext)` copies codec parameters. ```cpp av::OutputFormat ofrmt; av::FormatContext octx; ofrmt.setFormat(std::string(), "output.mp4"); // auto-detect format from extension octx.setFormat(ofrmt); av::VideoEncoderContext encoder{av::findEncodingCodec(ofrmt)}; encoder.setWidth(1280); encoder.setHeight(720); encoder.setPixelFormat(AV_PIX_FMT_YUV420P); encoder.setTimeBase({1, 25}); encoder.setBitRate(2'000'000); encoder.open(av::Codec(), ec); av::Stream ost = octx.addStream(encoder); ost.setFrameRate({25, 1}); octx.openOutput("output.mp4", ec); octx.writeHeader(); // ... encode frames and call octx.writePacket(pkt) for each ... octx.writeTrailer(); ``` -------------------------------- ### Build Common Targets Source: https://github.com/h4tr3d/avcpp/blob/master/example/api2-samples/CMakeLists.txt Iterates through the list of defined targets and calls the helper function to build each sample application. ```cmake # Common targets foreach(target ${TARGETS}) api2_sample_target(${target}) endforeach() ``` -------------------------------- ### Add FFmpeg-4 PPA (Ubuntu 18.04/Mint 19.x) Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Adds the ffmpeg-4 PPA for older Ubuntu and Linux Mint versions to ensure compatibility. After adding the PPA, update your package list and upgrade. ```bash sudo add-apt-repository ppa:jonathonf/ffmpeg-4 -y sudo apt update && sudo apt upgrade ``` -------------------------------- ### FormatContext: Input Operations Source: https://context7.com/h4tr3d/avcpp/llms.txt Opens a media container for demuxing, probes stream metadata, and reads encoded packets one at a time. `openInput` accepts a URI string (file path, RTMP URL, etc.) plus optional `InputFormat` and `Dictionary` options. `readPacket()` returns an empty `Packet` at EOF. ```APIDOC ## av::FormatContext::openInput() / findStreamInfo() / readPacket() ### Description Open a media container for demuxing, probe stream metadata, and read encoded packets one at a time. `openInput` accepts a URI string (file path, RTMP URL, etc.) plus optional `InputFormat` and `Dictionary` options. `readPacket()` returns an empty `Packet` at EOF. ### Code Example ```cpp #include "avcpp/av.h" #include "avcpp/formatcontext.h" av::init(); std::error_code ec; av::FormatContext ictx; ictx.openInput("input.mp4", ec); if (ec) { std::cerr << "Open failed: " << ec.message() << "\n"; return 1; } ictx.findStreamInfo(ec); if (ec) { std::cerr << "Stream info failed: " << ec.message() << "\n"; return 1; } std::clog << "Streams: " << ictx.streamsCount() << ", Duration: " << ictx.duration().seconds() << "s\n"; while (true) { av::Packet pkt = ictx.readPacket(ec); if (ec) { std::cerr << "Read error: " << ec.message() << "\n"; break; } if (!pkt) break; // EOF std::clog << "pkt stream=" << pkt.streamIndex() << " pts=" << pkt.pts().seconds() << "s" << " size=" << pkt.size() << "\n"; } ``` ``` -------------------------------- ### Demux Media: Open Input, Find Stream Info, Read Packets Source: https://context7.com/h4tr3d/avcpp/llms.txt Open a media container for demuxing, probe stream metadata, and read encoded packets. `openInput` accepts a URI. `readPacket()` returns an empty `Packet` at EOF. Error handling uses `std::error_code`. ```cpp #include "avcpp/av.h" #include "avcpp/formatcontext.h" av::init(); std::error_code ec; av::FormatContext ictx; ictx.openInput("input.mp4", ec); if (ec) { std::cerr << "Open failed: " << ec.message() << "\n"; return 1; } ictx.findStreamInfo(ec); if (ec) { std::cerr << "Stream info failed: " << ec.message() << "\n"; return 1; } std::clog << "Streams: " << ictx.streamsCount() << ", Duration: " << ictx.duration().seconds() << "s\n"; while (true) { av::Packet pkt = ictx.readPacket(ec); if (ec) { std::cerr << "Read error: " << ec.message() << "\n"; break; } if (!pkt) break; // EOF std::clog << "pkt stream=" << pkt.streamIndex() << " pts=" << pkt.pts().seconds() << "s" << " size=" << pkt.size() << "\n"; } ``` -------------------------------- ### Encode Video Frames with av::VideoEncoderContext Source: https://context7.com/h4tr3d/avcpp/llms.txt Configure an encoder context with width, height, pixel format, time base, and bit rate; open it; then feed VideoFrame objects and collect Packets. Call encode() with no frame argument to flush the encoder at the end. ```cpp av::VideoEncoderContext encoder{av::findEncodingCodec("libx264")}; encoder.setWidth(1280); encoder.setHeight(720); encoder.setPixelFormat(AV_PIX_FMT_YUV420P); encoder.setTimeBase({1, 1000}); encoder.setBitRate(2'000'000); encoder.setGopSize(12); encoder.open(av::Codec(), ec); // Encode a frame av::VideoFrame frame(AV_PIX_FMT_YUV420P, 1280, 720); frame.setTimeBase({1, 1000}); frame.setPts({0, {1, 1000}}); av::Packet pkt = encoder.encode(frame, ec); if (pkt) std::clog << "encoded " << pkt.size() << " bytes\n"; // Flush remaining packets while (true) { av::Packet flush_pkt = encoder.encode(ec); if (!flush_pkt) break; std::clog << "flush pkt size=" << flush_pkt.size() << "\n"; } ``` -------------------------------- ### Video Filtering with av::FilterGraph Source: https://context7.com/h4tr3d/avcpp/llms.txt Build and run video filter chains using `FilterGraph`. This involves creating buffer source and sink contexts, parsing an FFmpeg-style filter string, configuring the graph, and then pushing frames to the source and pulling filtered frames from the sink. Remember to flush the graph with a null frame at the end to finalize processing, especially for palette-based codecs. ```cpp #include "avcpp/filters/filtergraph.h" #include "avcpp/filters/buffersrc.h" #include "avcpp/filters/buffersink.h" av::FilterGraph graph; // Build source args matching the decoder output std::stringstream src_args; src_args << "video_size=" << vdec.width() << "x" << vdec.height() << ":pix_fmt=" << (int)vdec.pixelFormat() << ":time_base=" << vdec.timeBase() << ":pixel_aspect=" << vdec.sampleAspectRatio(); av::FilterContext src_ctx = graph.createFilter(av::Filter{"buffer"}, "in", src_args.str(), ec); av::FilterContext sink_ctx= graph.createFilter(av::Filter{"buffersink"}, "out", "", ec); // "scale then convert to GIF palette" std::string chain = "scale=320x200:-1:flags=lanczos,split[s0][s1];" "[s0]palettegen[p]; [s1][p]paletteuse[f];"; graph.parse(chain, src_ctx, sink_ctx, ec); graph.config(ec); av::BufferSrcFilterContext src_filter{src_ctx}; av::BufferSinkFilterContext sink_filter{sink_ctx}; // Process loop src_filter.addVideoFrame(inputFrame, AV_BUFFERSRC_FLAG_KEEP_REF, ec); av::VideoFrame filtered; while (sink_filter.getVideoFrame(filtered, ec)) { av::Packet pkt = encoder.encode(filtered, ec); if (pkt) octx.writePacket(pkt, ec); } // Flush: push null frame to finalize palette-based codecs auto null_frame = av::VideoFrame::null(); src_filter.addVideoFrame(null_frame, 0, ec); while (sink_filter.getVideoFrame(filtered, ec)) { av::Packet pkt = encoder.encode(filtered, ec); if (pkt) octx.writePacket(pkt, ec); } ``` -------------------------------- ### FormatContext: Output Operations Source: https://context7.com/h4tr3d/avcpp/llms.txt Creates an output container, writes a file header, flushes encoded packets, and finalizes with a trailer. `addStream(encoderContext)` automatically copies codec parameters from the encoder into the new stream. ```APIDOC ## av::FormatContext Output: openOutput() / writeHeader() / writePacket() / writeTrailer() ### Description Create an output container, write a file header, flush encoded packets, and finalize with a trailer. `addStream(encoderContext)` automatically copies codec parameters from the encoder into the new stream. ### Code Example ```cpp av::OutputFormat ofrmt; av::FormatContext octx; ofrmt.setFormat(std::string(), "output.mp4"); // auto-detect format from extension octx.setFormat(ofrmt); av::VideoEncoderContext encoder{av::findEncodingCodec(ofrmt)}; encoder.setWidth(1280); encoder.setHeight(720); encoder.setPixelFormat(AV_PIX_FMT_YUV420P); encoder.setTimeBase({1, 25}); encoder.setBitRate(2'000'000); encoder.open(av::Codec(), ec); av::Stream ost = octx.addStream(encoder); ost.setFrameRate({25, 1}); octx.openOutput("output.mp4", ec); octx.writeHeader(); // ... encode frames and call octx.writePacket(pkt) for each ... octx.writeTrailer(); ``` ``` -------------------------------- ### Configure CMake with Non-Standard FFmpeg Path Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Configures the CMake build process when FFmpeg libraries and include directories are located in non-standard paths. Specify the paths using `-D` options. ```bash cmake -DPC_FFMPEG_LIBRARY_DIRS= -DPC_FFMPEG_INCLUDE_DIRS= .. ``` -------------------------------- ### Integrate AvCpp as Git Submodule in CMake Source: https://github.com/h4tr3d/avcpp/blob/master/README.md Add AvCpp as a Git submodule to your project and include it in your CMakeLists.txt. Link against the avcpp::avcpp target. ```sh git submodule add https://github.com/h4tr3d/avcpp.git 3rdparty/avcpp ``` ```cmake add_subdirectory(3rdparty/avcpp) ``` ```cmake target_link_libraries(prog PRIVATE avcpp::avcpp) ``` -------------------------------- ### Audio Resampling with av::AudioResampler Source: https://context7.com/h4tr3d/avcpp/llms.txt Use `AudioResampler` to convert audio frames between different sample rates, formats, and channel layouts. Push input frames and pop output frames in a loop. A single push can result in zero or multiple output frames. Ensure to flush remaining buffered samples at the end of the stream. ```cpp // Resample stereo 44100 Hz fltp → stereo 48000 Hz fltp av::AudioResampler resampler( AV_CH_LAYOUT_STEREO, 48000, AV_SAMPLE_FMT_FLTP, // dst AV_CH_LAYOUT_STEREO, 44100, AV_SAMPLE_FMT_FLTP); // src resampler.push(inputSamples, ec); // Pop with explicit sample count auto null_out = av::AudioSamples::null(); while ((null_out = resampler.pop(1024, ec))) { std::clog << "resampled " << null_out.samplesCount() << " @ " << null_out.sampleRate() << " Hz\n"; } // Flush all remaining buffered samples at stream end av::AudioSamples leftover(AV_SAMPLE_FMT_FLTP, 576, AV_CH_LAYOUT_STEREO, 48000); while (resampler.pop(leftover, /*getall=*/true, ec)) { std::clog << "flush " << leftover.samplesCount() << " samples\n"; } ``` -------------------------------- ### Seek in Media Container with av::Timestamp Source: https://context7.com/h4tr3d/avcpp/llms.txt Seek to an arbitrary position in a demuxable container using `av::Timestamp`. The timestamp is constructed from a value and a `Rational` time base. ```cpp av::FormatContext ictx; ictx.openInput("video.mp4"); ictx.findStreamInfo(); // Seek to 30 seconds ictx.seek({30, {1, 1}}); auto pkt = ictx.readPacket(); std::clog << "After seek: pts=" << pkt.pts().seconds() << "s\n"; // Seek back to the beginning ictx.seek({0, {1, 1}}); ``` -------------------------------- ### Video Encoder Context Source: https://context7.com/h4tr3d/avcpp/llms.txt The `av::VideoEncoderContext` is used to encode video frames into packets. You configure the encoder with desired parameters, open it, then feed `av::VideoFrame` objects to `encode()` and collect the resulting `av::Packet`s. ```APIDOC ## `av::VideoEncoderContext` — encode video frames Configure an encoder context with width, height, pixel format, time base, and bit rate; open it; then feed `VideoFrame` objects and collect `Packet`s. Call `encode()` with no frame argument to flush the encoder at the end. ```cpp av::VideoEncoderContext encoder{av::findEncodingCodec("libx264")}; encoder.setWidth(1280); encoder.setHeight(720); encoder.setPixelFormat(AV_PIX_FMT_YUV420P); encoder.setTimeBase({1, 1000}); encoder.setBitRate(2'000'000); encoder.setGopSize(12); encoder.open(av::Codec(), ec); // Encode a frame av::VideoFrame frame(AV_PIX_FMT_YUV420P, 1280, 720); frame.setTimeBase({1, 1000}); frame.setPts({0, {1, 1000}}); av::Packet pkt = encoder.encode(frame, ec); if (pkt) std::clog << "encoded " << pkt.size() << " bytes\n"; // Flush remaining packets while (true) { av::Packet flush_pkt = encoder.encode(ec); if (!flush_pkt) break; std::clog << "flush pkt size=" << flush_pkt.size() << "\n"; } ``` ``` -------------------------------- ### Remuxing Streams with av::FormatContext Source: https://context7.com/h4tr3d/avcpp/llms.txt Remux media files by copying streams without decoding and encoding. This involves opening input and output formats, copying codec parameters, and forwarding packets with adjusted stream indices. Ensure to handle unsupported codecs and reset codec tags for container compatibility. ```cpp av::FormatContext ictx, octx; ictx.openInput("input.mkv"); ictx.findStreamInfo(); av::OutputFormat oformat("", "output.mp4"); octx.setFormat(oformat); std::map mapping; for (size_t i = 0, outIdx = 0; i < ictx.streamsCount(); ++i) { auto ist = ictx.stream(i); auto ipar = ist.codecParameters(); auto ocodec = ipar.decodingCodec(); if (!octx.outputFormat().codecSupported(ocodec)) continue; // skip unsupported auto ost = octx.addStream(ec); ost.setCodecParameters(ipar); ost.codecParameters().codecTag(0); // reset tag for container compatibility ost.setTimeBase(ist.timeBase()); mapping[i] = outIdx++; } octx.openOutput("output.mp4"); octx.writeHeader(); while (true) { auto pkt = ictx.readPacket(); if (!pkt) break; auto it = mapping.find(pkt.streamIndex()); if (it == mapping.end()) continue; pkt.setStreamIndex(it->second); octx.writePacket(pkt); } octx.writePacket(); // flush octx.writeTrailer(); ``` -------------------------------- ### Decode Video Packets with av::VideoDecoderContext Source: https://context7.com/h4tr3d/avcpp/llms.txt Construct a VideoDecoderContext from a Stream, open the codec, and call decode(packet) to obtain a VideoFrame. An empty frame means the decoder needs more input; a non-zero error code means failure. Flush the decoder at the end. ```cpp av::FormatContext ictx; ictx.openInput("video.mp4"); ictx.findStreamInfo(); av::Stream vst; ssize_t videoStream = -1; for (size_t i = 0; i < ictx.streamsCount(); ++i) { auto st = ictx.stream(i); if (st.mediaType() == AVMEDIA_TYPE_VIDEO) { vst = st; videoStream = i; break; } } av::VideoDecoderContext vdec(vst); vdec.setRefCountedFrames(true); vdec.open(av::Codec(), ec); while (true) { av::Packet pkt = ictx.readPacket(ec); if (!pkt) break; if (pkt.streamIndex() != videoStream) continue; av::VideoFrame frame = vdec.decode(pkt, ec); if (!frame) continue; std::clog << frame.width() << "x" << frame.height() << " pts=" << frame.pts().seconds() << "s" << " keyframe=" << frame.isKeyFrame() << "\n"; } // Flush decoder while (av::VideoFrame frame = vdec.decode(av::Packet{}, ec)) { std::clog << "flush frame pts=" << frame.pts().seconds() << "\n"; } ``` -------------------------------- ### Find Decoding and Encoding Codecs Source: https://context7.com/h4tr3d/avcpp/llms.txt Look up an av::Codec object by FFmpeg AVCodecID, name string, or OutputFormat. The returned codec is passed to a codec context's open() or setCodec() methods. Used for HW encoding fallback. ```cpp // By codec ID (from stream parameters) av::Codec dec = av::findDecodingCodec(AV_CODEC_ID_H264); std::clog << dec.name() << " / " << dec.longName() << "\n"; // By name av::Codec enc_nvenc = av::findEncodingCodec("h264_nvenc"); av::Codec enc_x264 = av::findEncodingCodec("libx264"); // Fallback pattern used for HW encoding av::Codec ocodec = enc_nvenc.isNull() ? enc_x264 : enc_nvenc; // Best default encoder for an OutputFormat av::OutputFormat ofrmt("", "out.mkv"); av::Codec best = av::findEncodingCodec(ofrmt, /*isVideo=*/true); ``` -------------------------------- ### FormatContext: Seek Operation Source: https://context7.com/h4tr3d/avcpp/llms.txt Seeks to an arbitrary position in a demuxable container using `av::Timestamp`. The timestamp is constructed from a value and a `Rational` time base (`{seconds, {1,1}}`). ```APIDOC ## av::FormatContext::seek() ### Description Seek to an arbitrary position in a demuxable container using `av::Timestamp`. The timestamp is constructed from a value and a `Rational` time base (`{seconds, {1,1}}`). ### Code Example ```cpp av::FormatContext ictx; ictx.openInput("video.mp4"); ictx.findStreamInfo(); // Seek to 30 seconds ictx.seek({30, {1, 1}}); auto pkt = ictx.readPacket(); std::clog << "After seek: pts=" << pkt.pts().seconds() << "s\n"; // Seek back to the beginning ictx.seek({0, {1, 1}}); ``` ``` -------------------------------- ### Finding Decoding and Encoding Codecs Source: https://context7.com/h4tr3d/avcpp/llms.txt These functions allow you to look up an `av::Codec` object by FFmpeg `AVCodecID`, name string, or `OutputFormat`. The retrieved codec can then be used to open or set a codec context. ```APIDOC ## `av::findDecodingCodec()` / `av::findEncodingCodec()` Look up an `av::Codec` object by FFmpeg `AVCodecID`, by name string, or by `OutputFormat`. The returned codec is passed to a codec context's `open()` or `setCodec()` methods. ```cpp // By codec ID (from stream parameters) av::Codec dec = av::findDecodingCodec(AV_CODEC_ID_H264); std::clog << dec.name() << " / " << dec.longName() << "\n"; // By name av::Codec enc_nvenc = av::findEncodingCodec("h264_nvenc"); av::Codec enc_x264 = av::findEncodingCodec("libx264"); // Fallback pattern used for HW encoding av::Codec ocodec = enc_nvenc.isNull() ? enc_x264 : enc_nvenc; // Best default encoder for an OutputFormat av::OutputFormat ofrmt("", "out.mkv"); av::Codec best = av::findEncodingCodec(ofrmt, /*isVideo=*/true); ``` ``` -------------------------------- ### AvCpp Exception Handling vs. std::error_code Source: https://context7.com/h4tr3d/avcpp/llms.txt Use exception mode for simpler error handling or error_code mode for non-exception codepaths. Error-code mode requires checking the returned std::error_code after each operation. ```cpp // Exception mode (default) — throws av::Exception on error try { av::FormatContext ctx; ctx.openInput("missing.mp4"); // throws if file not found } catch (const av::Exception &e) { std::cerr << "Error: " << e.what() << "\n"; std::cerr << "Code: " << e.code() << "\n"; } ``` ```cpp // Error-code mode — no exceptions std::error_code ec; av::FormatContext ctx; ctx.openInput("missing.mp4", ec); if (ec) { std::cerr << "Category: " << ec.category().name() << "\n"; // "ffmpeg" or "avcpp" std::cerr << "Message: " << ec.message() << "\n"; } ``` ```cpp // Comparing against AvCpp-specific error conditions if (ec == av::Errors::FormatNotOpened) std::cerr << "Format was never opened\n"; if (ec == av::Errors::FormatCodecUnsupported) std::cerr << "Codec not supported by container\n"; ``` -------------------------------- ### Audio Decoder and Encoder Contexts Source: https://context7.com/h4tr3d/avcpp/llms.txt Audio codec contexts provide similar functionality to their video counterparts. `AudioDecoderContext` decodes audio packets into `AudioSamples`, while `AudioEncoderContext` encodes `AudioSamples` into `Packet`s. ```APIDOC ## `av::AudioDecoderContext` / `av::AudioEncoderContext` Audio codec contexts mirror the video API. `AudioDecoderContext::decode()` returns `AudioSamples`; `AudioEncoderContext::encode()` accepts `AudioSamples` and returns a `Packet`. ```cpp // -- DECODE -- av::AudioDecoderContext adec(audioStream); adec.setRefCountedFrames(true); adec.open(av::Codec(), ec); av::Packet pkt = ictx.readPacket(ec); av::AudioSamples samples = adec.decode(pkt, ec); std::clog << "samples=" << samples.samplesCount() << " rate=" << samples.sampleRate() << " ch=" << samples.channelsCount() << " fmt=" << (int)samples.sampleFormat() << " layout=" << samples.channelsLayoutString() << "\n"; // -- ENCODE -- av::AudioEncoderContext aenc{av::findEncodingCodec("aac")}; aenc.setSampleRate(44100); aenc.setChannels(2); aenc.setSampleFormat(AV_SAMPLE_FMT_FLTP); aenc.setChannelLayout(AV_CH_LAYOUT_STEREO); aenc.setBitRate(128'000); aenc.open(av::Codec(), ec); av::Packet out_pkt = aenc.encode(samples, ec); if (out_pkt) std::clog << "audio pkt size=" << out_pkt.size() << "\n"; ``` ``` -------------------------------- ### Set C++ Standard for Specific Target Source: https://github.com/h4tr3d/avcpp/blob/master/example/api2-samples/CMakeLists.txt Sets the C++ standard to 20 for the 'api2-decode-raw-h264' target if it is included in the build. ```cmake # Additional options if ("api2-decode-raw-h264" IN_LIST TARRGETS) set_property(TARGET api2-decode-raw-h264 PROPERTY CXX_STANDARD 20) endif() ``` -------------------------------- ### Video Decoder Context Source: https://context7.com/h4tr3d/avcpp/llms.txt The `av::VideoDecoderContext` is used to decode video packets from a stream. After construction and opening the codec, you can feed it `av::Packet` objects and receive decoded `av::VideoFrame` objects. ```APIDOC ## `av::VideoDecoderContext` — decode video packets Construct from a `Stream`, open the codec, and call `decode(packet)` to obtain a `VideoFrame`. An empty frame means the decoder needs more input; a non-zero error code means failure. ```cpp av::FormatContext ictx; ictx.openInput("video.mp4"); ictx.findStreamInfo(); av::Stream vst; ssize_t videoStream = -1; for (size_t i = 0; i < ictx.streamsCount(); ++i) { auto st = ictx.stream(i); if (st.mediaType() == AVMEDIA_TYPE_VIDEO) { vst = st; videoStream = i; break; } } av::VideoDecoderContext vdec(vst); vdec.setRefCountedFrames(true); vdec.open(av::Codec(), ec); while (true) { av::Packet pkt = ictx.readPacket(ec); if (!pkt) break; if (pkt.streamIndex() != videoStream) continue; av::VideoFrame frame = vdec.decode(pkt, ec); if (!frame) continue; std::clog << frame.width() << "x" << frame.height() << " pts=" << frame.pts().seconds() << "s" << " keyframe=" << frame.isKeyFrame() << "\n"; } // Flush decoder while (av::VideoFrame frame = vdec.decode(av::Packet{}, ec)) { std::clog << "flush frame pts=" << frame.pts().seconds() << "\n"; } ``` ``` -------------------------------- ### Conditional Target Removal Source: https://github.com/h4tr3d/avcpp/blob/master/example/api2-samples/CMakeLists.txt Removes targets from the list if specific AvCpp features are disabled or if C++20 is not supported. ```cmake if (AV_DISABLE_AVFORMAT) list(REMOVE_ITEM TARGETS api2-decode api2-decode-encode-video api2-decode-encode-audio api2-decode-filter-encode api2-hw-encode api2-decode-audio api2-remux api2-scale-video api2-decode-rasample-audio api2-demux-seek ) endif() if (AV_DISABLE_AVFILTER) list(REMOVE_ITEM TARGETS api2-decode-filter-encode ) endif() if (NOT "cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES) list(REMOVE_ITEM TARGETS api2-decode-raw-h264) endif() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.