### General Compilation Steps for dav2d Source: https://github.com/videolan/dav2d/blob/main/README.md Follow these steps to compile the dav2d project. Ensure Meson, Ninja, and nasm are installed. Configuration can be modified for static linking. ```bash mkdir build && cd build meson setup .. ninja ``` -------------------------------- ### Cross-Compilation for Windows with dav2d Source: https://github.com/videolan/dav2d/blob/main/README.md Configure meson for cross-compiling to Windows targets (64-bit or 32-bit). mingw-w64 must be installed on the build machine. ```bash meson setup .. --cross-file=../package/crossfiles/x86_64-w64-mingw32.meson ``` ```bash meson setup .. --cross-file=../package/crossfiles/i686-w64-mingw32.meson ``` -------------------------------- ### Query dav2d Library Version String Source: https://context7.com/videolan/dav2d/llms.txt Use `dav2d_version()` to get the human-readable version string of the linked library. This is useful for runtime version checks against the version used during compilation. ```c #include "dav2d/dav2d.h" #include #include // Check that the runtime library matches the compile-time version int check_version(void) { const char *runtime_version = dav2d_version(); printf("dav2d runtime version: %s\n", runtime_version); // DAV2D_VERSION is defined at compile time via config.h / vcs_version.h if (strcmp(runtime_version, DAV2D_VERSION) != 0) { fprintf(stderr, "Version mismatch: library=%s, headers=%s\n", runtime_version, DAV2D_VERSION); return -1; } return 0; } ``` -------------------------------- ### Retrieve Decode Error Data Properties Source: https://context7.com/videolan/dav2d/llms.txt Call this function after a decoding error to get metadata about the problematic input packet. Ensure error_code is negative and not EAGAIN. ```c #include "dav2d/dav2d.h" #include #include void handle_decode_error(Dav2dContext *c, int error_code) { fprintf(stderr, "Decode error: %s\n", strerror(-error_code)); Dav2dDataProps props; int res = dav2d_get_decode_error_data_props(c, &props); if (res == 0) { fprintf(stderr, " Failed packet: ts=% ``` -------------------------------- ### dav2d_get_event_flags Source: https://context7.com/videolan/dav2d/llms.txt Retrieves and clears a bitmask of `Dav2dEventFlags` that have occurred since the last call. It can indicate events like a new sequence starting or operating parameters changing within the current sequence. ```APIDOC ## dav2d_get_event_flags — Query decoder event flags ### Description Retrieves and clears a bitmask of `Dav2dEventFlags` generated since the last invocation. Currently supported flags include `DAV2D_EVENT_FLAG_NEW_SEQUENCE` (signifying the start of a new coded sequence or a decoder flush) and `DAV2D_EVENT_FLAG_NEW_OP_PARAMS_INFO` (indicating that operating parameters have been updated within the current sequence). All pending flags are cleared upon calling this function. ### Method C Function Call ### Parameters - **c** (*Dav2dContext* *) - Pointer to the Dav2d context. - **flags** (*enum Dav2dEventFlags* *) - Pointer to an enum where the event flags will be stored. ### Return Value - **0** on success. - A negative error code on failure. ### Request Example ```c #include "dav2d/dav2d.h" #include void check_events(Dav2dContext *c, Dav2dPicture *last_pic) { enum Dav2dEventFlags flags; int res = dav2d_get_event_flags(c, &flags); if (res < 0) { fprintf(stderr, "dav2d_get_event_flags: %s\n", strerror(-res)); return; } if (flags & DAV2D_EVENT_FLAG_NEW_SEQUENCE) { // last_pic->seq_hdr contains the new sequence header printf("New sequence: %dx%d\n", last_pic->seq_hdr->max_width, last_pic->seq_hdr->max_height); // Reallocate output surfaces, update display pipeline, etc. } if (flags & DAV2D_EVENT_FLAG_NEW_OP_PARAMS_INFO) { printf("Operating parameters updated\n"); // Update HRD buffer model, bitrate display, etc. } } ``` ``` -------------------------------- ### Build Documentation for dav2d Source: https://github.com/videolan/dav2d/blob/main/README.md Enable documentation generation during meson configuration and build the docs using ninja. Doxygen and Graphviz are required. ```bash meson setup .. -Denable_docs=true ninja doc/html ``` -------------------------------- ### Run Tests for dav2d Source: https://github.com/videolan/dav2d/blob/main/README.md Fetch test data, configure meson with the test data option, and run tests. Ensure the test data repository is cloned into the correct location. ```bash git clone https://code.videolan.org/videolan/dav2d-test-data.git tests/dav2d-test-data meson test -v ``` -------------------------------- ### Initialize dav2d Settings to Defaults Source: https://context7.com/videolan/dav2d/llms.txt Use `dav2d_default_settings()` to populate a `Dav2dSettings` struct with safe defaults. Always call this before modifying individual fields to ensure compatibility with future library versions. ```c #include "dav2d/dav2d.h" // Default values set by dav2d_default_settings: // n_threads = 0 (auto: number of logical CPU cores) // max_frame_delay = 0 (auto: ceil(sqrt(n_threads))) // apply_grain = 1 (film grain applied on output) // operating_point = 0 // all_layers = 1 // frame_size_limit = 0 (unlimited) // inloop_filters = DAV2D_INLOOPFILTER_ALL // decode_frame_type = DAV2D_DECODEFRAMETYPE_ALL // strict_std_compliance = 0 // output_invisible_frames = 0 void configure_settings(Dav2dSettings *s) { dav2d_default_settings(s); // Override for a 4-thread, low-latency decode pipeline s->n_threads = 4; s->max_frame_delay = 1; // minimize output delay // Disable film grain application (e.g., handled externally by GPU) s->apply_grain = 0; // Limit maximum decoded frame size to 1920x1080 = 2,073,600 pixels s->frame_size_limit = 1920 * 1080; // Skip chroma loop filters for a speed/quality trade-off s->inloop_filters = DAV2D_INLOOPFILTER_DEBLOCK | DAV2D_INLOOPFILTER_CDEF; } ``` -------------------------------- ### Cross-Compilation for 32-bit Linux with dav2d Source: https://github.com/videolan/dav2d/blob/main/README.md Configure meson for cross-compiling to a 32-bit Linux target. Ensure the appropriate cross-file is available. ```bash meson setup .. --cross-file=../package/crossfiles/i686-linux32.meson ``` -------------------------------- ### dav2d_default_settings Source: https://context7.com/videolan/dav2d/llms.txt Initializes a `Dav2dSettings` struct with safe default values. This function should be called before customizing individual settings to ensure forward compatibility. ```APIDOC ## dav2d_default_settings ### Description Fills a `Dav2dSettings` struct with default values before customization. Always call this before modifying individual fields to ensure forward compatibility with new reserved fields. ### Method C Function ### Endpoint N/A ### Parameters - **s** (`Dav2dSettings*`) - Output - Pointer to the `Dav2dSettings` struct to be initialized. ### Request Example ```c #include "dav2d/dav2d.h" // Default values set by dav2d_default_settings: // n_threads = 0 (auto: number of logical CPU cores) // max_frame_delay = 0 (auto: ceil(sqrt(n_threads))) // apply_grain = 1 (film grain applied on output) // operating_point = 0 // all_layers = 1 // frame_size_limit = 0 (unlimited) // inloop_filters = DAV2D_INLOOPFILTER_ALL // decode_frame_type = DAV2D_DECODEFRAMETYPE_ALL // strict_std_compliance = 0 // output_invisible_frames = 0 void configure_settings(Dav2dSettings *s) { dav2d_default_settings(s); // Override for a 4-thread, low-latency decode pipeline s->n_threads = 4; s->max_frame_delay = 1; // minimize output delay // Disable film grain application (e.g., handled externally by GPU) s->apply_grain = 0; // Limit maximum decoded frame size to 1920x1080 = 2,073,600 pixels s->frame_size_limit = 1920 * 1080; // Skip chroma loop filters for a speed/quality trade-off s->inloop_filters = DAV2D_INLOOPFILTER_DEBLOCK | DAV2D_INLOOPFILTER_CDEF; } ``` ### Response #### Success Response None (modifies the provided struct in-place). ``` -------------------------------- ### Custom GPU Picture Allocator for Zero-Copy Source: https://context7.com/videolan/dav2d/llms.txt Implement Dav2dPicAllocator to decode directly into GPU-mapped memory, avoiding CPU-GPU copies. Both alloc_picture_callback and release_picture_callback are required. The allocator must handle alignment requirements. ```c #include "dav2d/dav2d.h" #include #include #include typedef struct GpuAllocCtx { /* GPU device handle, pool, etc. */ } GpuAllocCtx; static int gpu_alloc_pic(Dav2dPicture *pic, void *cookie) { GpuAllocCtx *gpu = cookie; int w = pic->p.w; int h = pic->p.h; int bpc = pic->p.bpc; // Round up to 128-pixel alignment required by dav2d int aligned_w = (w + 127) & ~127; int aligned_h = (h + 127) & ~127; int bytes_pp = (bpc > 8) ? 2 : 1; ptrdiff_t y_stride = aligned_w * bytes_pp; ptrdiff_t uv_stride = (pic->p.layout != DAV2D_PIXEL_LAYOUT_I444) ? (aligned_w / 2) * bytes_pp : y_stride; // Allocate GPU-mapped memory (simplified) uint8_t *y_plane = aligned_alloc(DAV2D_PICTURE_ALIGNMENT, y_stride * aligned_h + DAV2D_PICTURE_ALIGNMENT); uint8_t *uv_planes = aligned_alloc(DAV2D_PICTURE_ALIGNMENT, uv_stride * aligned_h + DAV2D_PICTURE_ALIGNMENT); if (!y_plane || !uv_planes) { free(y_plane); free(uv_planes); return -1; } pic->data[0] = y_plane; pic->data[1] = uv_planes; pic->data[2] = uv_planes + uv_stride * (aligned_h / 2); pic->stride[0] = y_stride; pic->stride[1] = uv_stride; pic->allocator_data = uv_planes; // stash for release return 0; } static void gpu_release_pic(Dav2dPicture *pic, void *cookie) { (void)cookie; free(pic->data[0]); free(pic->allocator_data); } Dav2dContext *open_decoder_with_gpu_allocator(GpuAllocCtx *gpu) { Dav2dSettings s; dav2d_default_settings(&s); s.apply_grain = 0; // apply grain on GPU separately if needed s.allocator = (Dav2dPicAllocator) { .cookie = gpu, .alloc_picture_callback = gpu_alloc_pic, .release_picture_callback = gpu_release_pic, }; Dav2dContext *c = NULL; if (dav2d_open(&c, &s) < 0) return NULL; return c; } ``` -------------------------------- ### Open Dav2d Decoder Context Source: https://context7.com/videolan/dav2d/llms.txt Allocates and opens a decoder instance. Ensure to free the context with `dav2d_close()`. Custom logging can be configured via `s.logger`. ```c #include "dav2d/dav2d.h" #include Dav2dContext *open_decoder(void) { Dav2dSettings s; dav2d_default_settings(&s); s.n_threads = 0; // auto-detect // Custom logger: redirect dav2d log output to stderr s.logger.cookie = NULL; s.logger.callback = NULL; // NULL = default stderr logging Dav2dContext *c = NULL; int res = dav2d_open(&c, &s); if (res < 0) { fprintf(stderr, "dav2d_open failed: %s\n", strerror(-res)); return NULL; } printf("Decoder opened, frame delay = %d\n", dav2d_get_frame_delay(&s)); // Decoder opened, frame delay = 2 (example with 4 threads) return c; } ``` -------------------------------- ### dav2d_open Source: https://context7.com/videolan/dav2d/llms.txt Allocates and opens a decoder instance. The returned Dav2dContext must be freed with dav2d_close(). Returns 0 on success or a negative error code on failure. ```APIDOC ## dav2d_open — Allocate and open a decoder context ### Description Allocates all internal state and opens a decoder instance. The returned `Dav2dContext *` must be freed with `dav2d_close()` when decoding is complete. Returns 0 on success or a negative `DAV2D_ERR()` code on failure. ### Usage Example ```c #include "dav2d/dav2d.h" #include Dav2dContext *open_decoder(void) { Dav2dSettings s; dav2d_default_settings(&s); s.n_threads = 0; // auto-detect // Custom logger: redirect dav2d log output to stderr s.logger.cookie = NULL; s.logger.callback = NULL; // NULL = default stderr logging Dav2dContext *c = NULL; int res = dav2d_open(&c, &s); if (res < 0) { fprintf(stderr, "dav2d_open failed: %s\n", strerror(-res)); return NULL; } printf("Decoder opened, frame delay = %d\n", dav2d_get_frame_delay(&s)); // Decoder opened, frame delay = 2 (example with 4 threads) return c; } ``` ``` -------------------------------- ### Custom Picture Allocator (Dav2dPicAllocator) Source: https://context7.com/videolan/dav2d/llms.txt Allows replacing dav2d's default memory allocator with a custom one, enabling zero-copy GPU integration by decoding directly into GPU-mapped memory. ```APIDOC ## Custom Picture Allocator (`Dav2dPicAllocator`) — Zero-copy GPU integration ### Description The `Dav2dPicAllocator` allows replacing dav2d's default `malloc`-based picture allocator with a custom one — for example, to decode directly into GPU-mapped memory and avoid a CPU→GPU copy. Both callbacks are required. `alloc_picture_callback` must fill `pic->data[0..2]`, `pic->stride[0..1]`, and optionally `pic->allocator_data`. `release_picture_callback` is called from any thread when the frame is no longer needed. ### Usage Example ```c #include "dav2d/dav2d.h" #include #include #include typedef struct GpuAllocCtx { /* GPU device handle, pool, etc. */ } GpuAllocCtx; static int gpu_alloc_pic(Dav2dPicture *pic, void *cookie) { GpuAllocCtx *gpu = cookie; int w = pic->p.w; int h = pic->p.h; int bpc = pic->p.bpc; // Round up to 128-pixel alignment required by dav2d int aligned_w = (w + 127) & ~127; int aligned_h = (h + 127) & ~127; int bytes_pp = (bpc > 8) ? 2 : 1; ptrdiff_t y_stride = aligned_w * bytes_pp; ptrdiff_t uv_stride = (pic->p.layout != DAV2D_PIXEL_LAYOUT_I444) ? (aligned_w / 2) * bytes_pp : y_stride; // Allocate GPU-mapped memory (simplified) uint8_t *y_plane = aligned_alloc(DAV2D_PICTURE_ALIGNMENT, y_stride * aligned_h + DAV2D_PICTURE_ALIGNMENT); uint8_t *uv_planes = aligned_alloc(DAV2D_PICTURE_ALIGNMENT, uv_stride * aligned_h + DAV2D_PICTURE_ALIGNMENT); if (!y_plane || !uv_planes) { free(y_plane); free(uv_planes); return -1; } pic->data[0] = y_plane; pic->data[1] = uv_planes; pic->data[2] = uv_planes + uv_stride * (aligned_h / 2); pic->stride[0] = y_stride; pic->stride[1] = uv_stride; pic->allocator_data = uv_planes; // stash for release return 0; } static void gpu_release_pic(Dav2dPicture *pic, void *cookie) { (void)cookie; free(pic->data[0]); free(pic->allocator_data); } Dav2dContext *open_decoder_with_gpu_allocator(GpuAllocCtx *gpu) { Dav2dSettings s; dav2d_default_settings(&s); s.apply_grain = 0; // apply grain on GPU separately if needed s.allocator = (Dav2dPicAllocator) { .cookie = gpu, .alloc_picture_callback = gpu_alloc_pic, .release_picture_callback = gpu_release_pic, }; Dav2dContext *c = NULL; if (dav2d_open(&c, &s) < 0) return NULL; return c; } ``` ``` -------------------------------- ### Attach User Data to Dav2dData Source: https://context7.com/videolan/dav2d/llms.txt Wraps user-provided metadata into a reference-counted object attached to a `Dav2dData` packet. This metadata is propagated to the output picture. ```c #include "dav2d/dav2d.h" #include #include typedef struct MyFrameCtx { int frame_id; double wall_time; } MyFrameCtx; static void free_ctx(const uint8_t *user_data, void *cookie) { (void)cookie; free((void *)user_data); } int attach_context(Dav2dData *data, int frame_id, double wall_time) { MyFrameCtx *ctx = malloc(sizeof(*ctx)); if (!ctx) return -1; ctx->frame_id = frame_id; ctx->wall_time = wall_time; return dav2d_data_wrap_user_data(data, (const uint8_t *)ctx, free_ctx, NULL); // ctx will be accessible in the output picture as: // (MyFrameCtx *)pic.m.user_data.data } ``` -------------------------------- ### dav2d_version_api Source: https://context7.com/videolan/dav2d/llms.txt Queries the numeric API version as a packed 32-bit integer. Use provided macros to unpack major, minor, and patch components for compatibility checks. ```APIDOC ## dav2d_version_api ### Description Returns a packed 32-bit integer encoding the API version as `0x00XXYYZZ` (major, minor, patch). Use the `DAV2D_API_MAJOR()`, `DAV2D_API_MINOR()`, and `DAV2D_API_PATCH()` macros to unpack the components. ### Method C Function ### Endpoint N/A ### Parameters None ### Request Example ```c #include "dav2d/dav2d.h" #include void print_api_version(void) { unsigned v = dav2d_version_api(); printf("API version: %u.%u.%u\n", DAV2D_API_MAJOR(v), DAV2D_API_MINOR(v), DAV2D_API_PATCH(v)); // Output: API version: 1.0.0 // Require at least API 1.0.0 if (DAV2D_API_MAJOR(v) < 1) { fprintf(stderr, "dav2d API too old\n"); } } ``` ### Response #### Success Response - **unsigned int**: A packed 32-bit integer representing the API version (major, minor, patch). ``` -------------------------------- ### Query dav2d Numeric API Version Source: https://context7.com/videolan/dav2d/llms.txt Retrieve the API version as a packed 32-bit integer using `dav2d_version_api()`. Use the provided macros to extract major, minor, and patch components for version comparisons. ```c #include "dav2d/dav2d.h" #include void print_api_version(void) { unsigned v = dav2d_version_api(); printf("API version: %u.%u.%u\n", DAV2D_API_MAJOR(v), DAV2D_API_MINOR(v), DAV2D_API_PATCH(v)); // Output: API version: 1.0.0 // Require at least API 1.0.0 if (DAV2D_API_MAJOR(v) < 1) { fprintf(stderr, "dav2d API too old\n"); } } ``` -------------------------------- ### Apply Film Grain Manually with dav2d_apply_grain Source: https://context7.com/videolan/dav2d/llms.txt Use this function when `Dav2dSettings.apply_grain` was set to 0. It applies AV2 film grain synthesis to a decoded picture. Ensure the context was opened with `apply_grain = 0`; otherwise, film grain will be applied twice. ```c #include "dav2d/dav2d.h" #include int apply_grain_manually(Dav2dContext *c, const Dav2dPicture *src, Dav2dPicture *dst) { // c must have been opened with apply_grain = 0 int res = dav2d_apply_grain(c, dst, src); if (res < 0) { fprintf(stderr, "dav2d_apply_grain failed: %s\n", strerror(-res)); return res; } // dst now holds a new reference with film grain applied. // src reference is unchanged; caller still owns it. printf("Grain applied: %dx%d\n", dst->p.w, dst->p.h); dav2d_picture_unref(dst); return 0; } ``` -------------------------------- ### dav2d_version Source: https://context7.com/videolan/dav2d/llms.txt Queries the human-readable version string of the linked dav2d library. This is useful for runtime version mismatch checks between a compiled application and the dynamically loaded library. ```APIDOC ## dav2d_version ### Description Returns the human-readable version string of the linked dav2d library. Useful for version mismatch checks between a compiled application and the dynamically loaded library at runtime. ### Method C Function ### Endpoint N/A ### Parameters None ### Request Example ```c #include "dav2d/dav2d.h" #include #include // Check that the runtime library matches the compile-time version int check_version(void) { const char *runtime_version = dav2d_version(); printf("dav2d runtime version: %s\n", runtime_version); // DAV2D_VERSION is defined at compile time via config.h / vcs_version.h if (strcmp(runtime_version, DAV2D_VERSION) != 0) { fprintf(stderr, "Version mismatch: library=%s, headers=%s\n", runtime_version, DAV2D_VERSION); return -1; } return 0; } ``` ### Response #### Success Response - **string**: The version string of the dav2d library. ``` -------------------------------- ### Wrap Existing Buffer in Dav2dData Source: https://context7.com/videolan/dav2d/llms.txt Wraps a caller-owned buffer into a `Dav2dData` object without copying. A `free_callback` is used to release the buffer when the library no longer references it. ```c #include "dav2d/dav2d.h" #include #include static void my_free(const uint8_t *buf, void *cookie) { (void)cookie; free((void *)buf); } int wrap_demuxed_packet(Dav2dData *data, uint8_t *pkt_buf, size_t pkt_sz, int64_t pts) { int res = dav2d_data_wrap(data, pkt_buf, pkt_sz, my_free, NULL); if (res < 0) { fprintf(stderr, "dav2d_data_wrap failed: %s\n", strerror(-res)); free(pkt_buf); return res; } data->m.timestamp = pts; return 0; } ``` -------------------------------- ### dav2d_data_create Source: https://context7.com/videolan/dav2d/llms.txt Allocates a new reference-counted data buffer of the specified size. Returns a pointer to the writable byte buffer or NULL on allocation failure. The caller is responsible for writing bitstream data into this buffer. ```APIDOC ## dav2d_data_create — Allocate an input data buffer ### Description Allocates a new reference-counted data buffer of the given size. Returns a pointer to the writable byte buffer, or NULL on allocation failure. The caller writes the AV2 OBU bitstream data into this buffer before calling `dav2d_send_data()`. ### Usage Example ```c #include "dav2d/dav2d.h" #include #include int read_packet_into_dav2d(FILE *fp, Dav2dData *data, size_t packet_size) { uint8_t *buf = dav2d_data_create(data, packet_size); if (!buf) { fprintf(stderr, "Failed to allocate %zu bytes for input packet\n", packet_size); return -1; } size_t n = fread(buf, 1, packet_size, fp); if (n != packet_size) { dav2d_data_unref(data); return -1; } // Attach timestamp metadata (optional, will be propagated to output picture) data->m.timestamp = 12345; data->m.duration = 1001; // e.g., for 1000/30000 timebase return 0; } ``` ``` -------------------------------- ### Custom Logger (Dav2dLogger) Source: https://context7.com/videolan/dav2d/llms.txt Allows intercepting all internal dav2d diagnostic messages by providing a custom callback function within `Dav2dSettings`. ```APIDOC ## Custom Logger (`Dav2dLogger`) — Redirect internal log output ### Description The `Dav2dLogger` embedded in `Dav2dSettings` lets the application intercept all internal dav2d diagnostic messages. Set `callback` to NULL to suppress all logging, or provide a `vprintf`-compatible function to route messages to a custom sink. ### Usage Example ```c #include "dav2d/dav2d.h" #include #include static void my_logger(void *cookie, const char *fmt, va_list ap) { FILE *log_file = (FILE *)cookie; fprintf(log_file, "[dav2d] "); vfprintf(log_file, fmt, ap); } Dav2dContext *open_with_custom_log(FILE *log_file) { Dav2dSettings s; dav2d_default_settings(&s); s.logger.cookie = log_file; // passed as first arg to callback s.logger.callback = my_logger; // NULL = disable all logging Dav2dContext *c = NULL; dav2d_open(&c, &s); return c; } ``` ``` -------------------------------- ### dav2d_get_picture Source: https://context7.com/videolan/dav2d/llms.txt Dequeues the next decoded Dav2dPicture from the decoder. The caller takes ownership and must call dav2d_picture_unref() when done. Returns 0 on success, DAV2D_ERR(EAGAIN) if no picture is ready, and DAV2D_EOF when draining is complete. ```APIDOC ## dav2d_get_picture ### Description Retrieves a decoded output frame. Dequeues the next decoded `Dav2dPicture` from the decoder. Returns 0 on success with a fully populated picture. The caller takes ownership of the returned picture and must call `dav2d_picture_unref()` when done. Returns `DAV2D_ERR(EAGAIN)` when no picture is ready yet, and `DAV2D_EOF` when the draining sequence is complete. ### Method ```c int dav2d_get_picture(Dav2dContext *c, Dav2dPicture *pic) ``` ### Parameters - **c** (`Dav2dContext *`) - Pointer to the Dav2d decoder context. - **pic** (`Dav2dPicture *`) - Pointer to a `Dav2dPicture` structure to be filled with decoded frame data. ``` -------------------------------- ### Flush Decoder State for Seeking with dav2d_flush Source: https://context7.com/videolan/dav2d/llms.txt Call `dav2d_flush` before seeking to discard buffered frames and reset decoder state. After flushing, a Sequence Header OBU must be sent via `dav2d_send_data` to resume decoding. ```c #include "dav2d/dav2d.h" void seek_to(Dav2dContext *c, DemuxerContext *demux, int64_t target_pts) { // 1. Flush all buffered state dav2d_flush(c); // 2. Seek the demuxer to the nearest keyframe demux_seek(demux, target_pts); // 3. Resume feeding from the new position; the first OBU must be // a Sequence Header for decoding to restart. Dav2dData data = { 0 }; while (input_read(demux, &data) == 0) { int res = dav2d_send_data(c, &data); if (res < 0 && res != DAV2D_ERR(EAGAIN)) break; // ... get pictures as usual ... } } ``` -------------------------------- ### Create and Read into Dav2d Data Buffer Source: https://context7.com/videolan/dav2d/llms.txt Allocates a reference-counted data buffer for input bitstream data. The caller is responsible for writing data into the buffer and unreferencing it on failure. ```c #include "dav2d/dav2d.h" #include #include int read_packet_into_dav2d(FILE *fp, Dav2dData *data, size_t packet_size) { uint8_t *buf = dav2d_data_create(data, packet_size); if (!buf) { fprintf(stderr, "Failed to allocate %zu bytes for input packet\n", packet_size); return -1; } size_t n = fread(buf, 1, packet_size, fp); if (n != packet_size) { dav2d_data_unref(data); return -1; } // Attach timestamp metadata (optional, will be propagated to output picture) data->m.timestamp = 12345; data->m.duration = 1001; // e.g., for 1000/30000 timebase return 0; } ``` -------------------------------- ### Send Compressed Data to Decoder Source: https://context7.com/videolan/dav2d/llms.txt Submits AV2 OBU packets to the decoder. On success, ownership of `*in` is transferred. Returns `DAV2D_ERR(EAGAIN)` if the internal queue is full, requiring draining via `dav2d_get_picture()` first. Passing `in = NULL` signals end-of-stream. ```c #include "dav2d/dav2d.h" #include #include int send_packet(Dav2dContext *c, Dav2dData *data) { int res = dav2d_send_data(c, data); if (res == 0) { // data ownership transferred; do not call dav2d_data_unref(data) return 0; } else if (res == DAV2D_ERR(EAGAIN)) { // Decoder full — must call dav2d_get_picture() before retrying. // data->sz is preserved; retry sending the same packet later. return EAGAIN; } else { // Real error: ownership was NOT transferred fprintf(stderr, "dav2d_send_data error: %s\n", strerror(-res)); dav2d_data_unref(data); return res; } } ``` -------------------------------- ### dav2d_data_wrap Source: https://context7.com/videolan/dav2d/llms.txt Wraps an existing caller-owned byte buffer into a reference-counted Dav2dData object without copying. A provided free_callback is invoked when the library drops its last reference. ```APIDOC ## dav2d_data_wrap — Wrap an existing buffer without copy ### Description Wraps a caller-owned byte buffer in a `Dav2dData` reference-counted object without copying. The provided `free_callback` is invoked when the library drops its last reference to the data. ### Usage Example ```c #include "dav2d/dav2d.h" #include #include static void my_free(const uint8_t *buf, void *cookie) { (void)cookie; free((void *)buf); } int wrap_demuxed_packet(Dav2dData *data, uint8_t *pkt_buf, size_t pkt_sz, int64_t pts) { int res = dav2d_data_wrap(data, pkt_buf, pkt_sz, my_free, NULL); if (res < 0) { fprintf(stderr, "dav2d_data_wrap failed: %s\n", strerror(-res)); free(pkt_buf); return res; } data->m.timestamp = pts; return 0; } ``` ``` -------------------------------- ### dav2d_apply_grain Source: https://context7.com/videolan/dav2d/llms.txt Applies AV2 film grain synthesis to a decoded picture. This function should only be called if `Dav2dSettings.apply_grain` was set to 0 during context initialization, as calling it otherwise would apply the grain twice. ```APIDOC ## dav2d_apply_grain — Apply film grain to a decoded picture ### Description Applies AV2 film grain synthesis to a previously decoded picture. This function is intended to be used when film grain was not applied during the initial decoding process (i.e., when `Dav2dSettings.apply_grain` was 0). If the picture lacks film grain metadata, a new reference is returned without modification. Calling this function after grain has already been applied by `dav2d_get_picture()` will result in the grain being applied twice. ### Method C Function Call ### Parameters - **c** (*Dav2dContext* *) - Pointer to the Dav2d context. - **src** (*const Dav2dPicture* *) - Pointer to the source picture (input). - **dst** (*Dav2dPicture* *) - Pointer to the destination picture (output), where the film grain will be applied. ### Return Value - **0** on success. - A negative error code on failure. ### Request Example ```c #include "dav2d/dav2d.h" #include int apply_grain_manually(Dav2dContext *c, const Dav2dPicture *src, Dav2dPicture *dst) { // c must have been opened with apply_grain = 0 int res = dav2d_apply_grain(c, dst, src); if (res < 0) { fprintf(stderr, "dav2d_apply_grain failed: %s\n", strerror(-res)); return res; } // dst now holds a new reference with film grain applied. // src reference is unchanged; caller still owns it. printf("Grain applied: %dx%d\n", dst->p.w, dst->p.h); dav2d_picture_unref(dst); return 0; } ``` ``` -------------------------------- ### Query Decoder Event Flags with dav2d_get_event_flags Source: https://context7.com/videolan/dav2d/llms.txt Retrieve and clear `Dav2dEventFlags` using `dav2d_get_event_flags`. Flags indicate events like `DAV2D_EVENT_FLAG_NEW_SEQUENCE` or `DAV2D_EVENT_FLAG_NEW_OP_PARAMS_INFO`. All pending flags are cleared after retrieval. ```c #include "dav2d/dav2d.h" #include void check_events(Dav2dContext *c, Dav2dPicture *last_pic) { enum Dav2dEventFlags flags; int res = dav2d_get_event_flags(c, &flags); if (res < 0) { fprintf(stderr, "dav2d_get_event_flags: %s\n", strerror(-res)); return; } if (flags & DAV2D_EVENT_FLAG_NEW_SEQUENCE) { // last_pic->seq_hdr contains the new sequence header printf("New sequence: %dx%d\n", last_pic->seq_hdr->max_width, last_pic->seq_hdr->max_height); // Reallocate output surfaces, update display pipeline, etc. } if (flags & DAV2D_EVENT_FLAG_NEW_OP_PARAMS_INFO) { printf("Operating parameters updated\n"); // Update HRD buffer model, bitrate display, etc. } } ``` -------------------------------- ### Release Dav2dPicture Reference Source: https://context7.com/videolan/dav2d/llms.txt Releases the caller's reference to a decoded `Dav2dPicture`. The underlying frame memory is returned to the allocator when the reference count drops to zero. Must be called for every picture successfully returned by `dav2d_get_picture()` or `dav2d_apply_grain()`. ```c #include "dav2d/dav2d.h" void consume_picture(Dav2dPicture *pic) { // ... process pic->data[0..2] ... // Check HDR metadata if present if (pic->content_light) { printf("MaxCLL=%u MaxFALL=%u\n", pic->content_light->max_content_light_level, pic->content_light->max_frame_average_light_level); } if (pic->mastering_display) { printf("MaxLuminance=%.4f cd/m²\n", pic->mastering_display->max_luminance / 256.0); } dav2d_picture_unref(pic); // pic->data[0..2] are now invalid; do not read after this call } ``` -------------------------------- ### Custom Logger for Internal Log Output Source: https://context7.com/videolan/dav2d/llms.txt Intercept dav2d's internal diagnostic messages by providing a custom logger callback in Dav2dSettings. Set callback to NULL to disable logging. ```c #include "dav2d/dav2d.h" #include #include static void my_logger(void *cookie, const char *fmt, va_list ap) { FILE *log_file = (FILE *)cookie; fprintf(log_file, "[dav2d] "); vfprintf(log_file, fmt, ap); } Dav2dContext *open_with_custom_log(FILE *log_file) { Dav2dSettings s; dav2d_default_settings(&s); s.logger.cookie = log_file; // passed as first arg to callback s.logger.callback = my_logger; // NULL = disable all logging Dav2dContext *c = NULL; dav2d_open(&c, &s); return c; } ``` -------------------------------- ### Parse Sequence Header OBU with dav2d_parse_sequence_header Source: https://context7.com/videolan/dav2d/llms.txt Use `dav2d_parse_sequence_header` to parse stream parameters like resolution and bit depth without an active `Dav2dContext`. This is useful for probing stream information before allocating a decoder or during seeking. ```c #include "dav2d/dav2d.h" #include #include void probe_stream(const uint8_t *buf, size_t sz) { Dav2dSequenceHeader seq; int res = dav2d_parse_sequence_header(&seq, buf, sz); if (res == DAV2D_ERR(ENOENT)) { printf("No Sequence Header OBU found in buffer\n"); return; } else if (res < 0) { fprintf(stderr, "Parse error: %s\n", strerror(-res)); return; } // Pixel layouts: I400=mono, I420, I422, I444 const char *layouts[] = { "I400", "I420", "I422", "I444" }; int bpc_table[] = { 8, 10, 12 }; printf("Profile=%d Max=%dx%d Layout=%s BPC=%d FilmGrain=%d\n", seq.profile, seq.max_width, seq.max_height, layouts[seq.layout], bpc_table[seq.hbd], seq.film_grain_present); // Example output: // Profile=0 Max=3840x2160 Layout=I420 BPC=10 FilmGrain=1 } ``` -------------------------------- ### dav2d_send_data Source: https://context7.com/videolan/dav2d/llms.txt Submits one or more AV2 OBU packets to the decoder. On success, ownership of the data is transferred to the library. Returns DAV2D_ERR(EAGAIN) if the internal queue is full, requiring the caller to drain pictures first. Passing NULL signals end-of-stream. ```APIDOC ## dav2d_send_data ### Description Feeds compressed OBU data to the decoder. Submits one or more AV2 OBU packets to the decoder. On success (returns 0), ownership of `*in` is transferred to the library and the caller must not call `dav2d_data_unref()` on it. Returns `DAV2D_ERR(EAGAIN)` when the internal queue is full — the caller must drain pictures via `dav2d_get_picture()` first. Passing `in = NULL` signals end-of-stream and puts the decoder into draining mode. ### Method ```c int dav2d_send_data(Dav2dContext *c, Dav2dData *in) ``` ### Parameters - **c** (`Dav2dContext *`) - Pointer to the Dav2d decoder context. - **in** (`Dav2dData *`) - Pointer to the `Dav2dData` containing compressed OBU data. Can be NULL to signal end-of-stream. ``` -------------------------------- ### Retrieve Decoded Output Frame Source: https://context7.com/videolan/dav2d/llms.txt Dequeues the next decoded `Dav2dPicture`. The caller takes ownership and must call `dav2d_picture_unref()`. Returns `DAV2D_ERR(EAGAIN)` if no picture is ready, and `DAV2D_EOF` when draining is complete. This snippet demonstrates a full encode/decode loop. ```c #include "dav2d/dav2d.h" #include #include // Full encode/decode loop (see also the docstring example in dav2d.h) int decode_loop(Dav2dContext *c, DemuxerContext *demux) { Dav2dData data = { 0 }; Dav2dPicture pic = { 0 }; int res; // Feed and drain loop while (input_read(demux, &data) == 0) { res = dav2d_send_data(c, &data); if (res < 0 && res != DAV2D_ERR(EAGAIN)) return res; for (;;) { res = dav2d_get_picture(c, &pic); if (res == DAV2D_ERR(EAGAIN)) break; if (res < 0) return res; // Access decoded YUV planes: // pic.data[0] = Y plane (uint8_t* or uint16_t* for 10bpc) // pic.data[1] = Cb plane // pic.data[2] = Cr plane // pic.stride[0] = Y stride in bytes // pic.stride[1] = Cb/Cr stride in bytes // pic.p.w, pic.p.h = frame dimensions // pic.p.bpc = bits per component (8 or 10) printf("Frame %dx%d, bpc=%d, ts=%" PRId64 "\n", pic.p.w, pic.p.h, pic.p.bpc, pic.m.timestamp); dav2d_picture_unref(&pic); } } // Drain: signal EOS dav2d_send_data(c, NULL); while ((res = dav2d_get_picture(c, &pic)) != DAV2D_EOF) { if (res == 0) { printf("Drain: frame %dx%d\n", pic.p.w, pic.p.h); dav2d_picture_unref(&pic); } else if (res != DAV2D_ERR(EAGAIN)) { return res; } } return 0; } ```