[vlc-commits] [Git][videolan/vlc][master] 7 commits: fourcc: add VLC_CODEC_APV

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Nov 13 13:02:37 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
a806130d by Steve Lhomme at 2025-11-13T11:38:14+00:00
fourcc: add VLC_CODEC_APV

- - - - -
20ce369b by Steve Lhomme at 2025-11-13T11:38:14+00:00
codec: avcodec: map VLC_CODEC_APV

- - - - -
98264dd3 by Steve Lhomme at 2025-11-13T11:38:14+00:00
demux: mp4: map APV

- - - - -
bdb73a0e by Steve Lhomme at 2025-11-13T11:38:14+00:00
contrib: add openapv

- - - - -
a1d125f6 by Steve Lhomme at 2025-11-13T11:38:14+00:00
codec: add OpenAPV decoder using openapv library

- - - - -
2a8b57ef by Steve Lhomme at 2025-11-13T12:51:14+01:00
contrib: don't let emcmake overwrite CMAKE_SYSTEM_PROCESSOR

It sets X86 even though it's not the proper architecture,
just to notify some code that it's 32-bit. [^1]

[^1]: https://github.com/emscripten-core/emscripten/blob/8ce631e70431d707512231af17ccd80759396e2a/cmake/Modules/Platform/Emscripten.cmake

- - - - -
9adb6ce4 by Steve Lhomme at 2025-11-13T12:51:14+01:00
NEWS: add APV decoding support via openapv

- - - - -


16 changed files:

- NEWS
- configure.ac
- contrib/src/main.mak
- + contrib/src/openapv/SHA512SUMS
- + contrib/src/openapv/rules.mak
- include/vlc_fourcc.h
- meson_options.txt
- modules/codec/Makefile.am
- modules/codec/avcodec/fourcc.c
- modules/codec/meson.build
- + modules/codec/openapv.c
- modules/demux/mp4/essetup.c
- modules/demux/mp4/libmp4.c
- modules/demux/mp4/libmp4.h
- modules/demux/mp4/mp4.c
- src/misc/fourcc_list.h


Changes:

=====================================
NEWS
=====================================
@@ -59,6 +59,7 @@ Codecs:
  * Improve 708 decoder
  * Support AGM decoder
  * Support VP4 decoder
+ * Support OpenAPV decoder (FFmpeg 8 and OpenAPV)
  * Add NVDEC hardware decoder
  * Remove SDL_image support
 
@@ -5841,4 +5842,3 @@ iPaq port:
   * fixed crash on directory change in Familiar interface
   * added qte_main module for use in all modules that need Opie or Qte support
   * native video output module for Qt Embedded/Opie is not working
-


=====================================
configure.ac
=====================================
@@ -3043,6 +3043,11 @@ dnl  schroedinger decoder plugin (for dirac format video)
 dnl
 PKG_ENABLE_MODULES_VLC([SCHROEDINGER], [], [schroedinger-1.0 >= 1.0.10], [dirac decoder and encoder using schroedinger], [auto])
 
+dnl
+dnl  OpenAPV decoder plugin
+dnl
+PKG_ENABLE_MODULES_VLC([OPENAPV], [], [oapv >= 0.2], [OpenAPV decoder], [auto])
+
 dnl
 dnl  PNG decoder module
 dnl


=====================================
contrib/src/main.mak
=====================================
@@ -504,6 +504,10 @@ CMAKECONFIG = cmake -S $< -B $(BUILD_DIR) \
 ifeq ($(V),1)
 CMAKECONFIG += -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
 endif
+ifdef HAVE_EMSCRIPTEN
+# by default emcmake forces the processor to X86 to mark it as 32-bit
+CMAKECONFIG += -DEMSCRIPTEN_SYSTEM_PROCESSOR=$(ARCH)
+endif
 
 CMAKE = $(CMAKECONFIG) \
 		-DCMAKE_TOOLCHAIN_FILE=$(abspath toolchain.cmake) \


=====================================
contrib/src/openapv/SHA512SUMS
=====================================
@@ -0,0 +1 @@
+59a1d1168015e20cba984bdac098bbee1c4bd475832d553ce27f2c7c52a13fb60a19a48d94422220c007739883370a9cbce3158c7a1218063fd49a8d20270ec0  openapv-0.2.0.4.tar.gz


=====================================
contrib/src/openapv/rules.mak
=====================================
@@ -0,0 +1,30 @@
+# openapv
+
+OPENAPV_VERSION := 0.2.0.4
+OPENAPV_URL := $(GITHUB)/AcademySoftwareFoundation/openapv/archive/refs/tags/v$(OPENAPV_VERSION).tar.gz
+
+PKGS += openapv
+ifeq ($(call need_pkg,"oapv >= 0.2"),)
+PKGS_FOUND += openapv
+endif
+
+$(TARBALLS)/openapv-$(OPENAPV_VERSION).tar.gz:
+	$(call download_pkg,$(OPENAPV_URL),openapv)
+
+.sum-openapv: openapv-$(OPENAPV_VERSION).tar.gz
+
+OPENAPV_CONF := -DOAPV_BUILD_SHARED_LIB=OFF -DOAPV_BUILD_APPS=OFF
+
+openapv: openapv-$(OPENAPV_VERSION).tar.gz .sum-openapv
+	$(UNPACK)
+	$(call pkg_static,"pkgconfig/oapv.pc.in")
+	# install the library in the usual <prefix>/lib place to match the .pc file
+	sed -i.orig 's,$${CMAKE_INSTALL_LIBDIR}/$${LIB_NAME_BASE},$${CMAKE_INSTALL_LIBDIR},g' $(UNPACK_DIR)/src/CMakeLists.txt
+	$(MOVE)
+
+.openapv: openapv toolchain.cmake
+	$(CMAKECLEAN)
+	$(HOSTVARS_CMAKE) $(CMAKE) $(OPENAPV_CONF)
+	+$(CMAKEBUILD)
+	$(CMAKEINSTALL)
+	touch $@


=====================================
include/vlc_fourcc.h
=====================================
@@ -198,6 +198,7 @@
 #define VLC_CODEC_AGM             VLC_FOURCC('A','G','M','0')
 #define VLC_CODEC_NOTCHLC         VLC_FOURCC('n','c','l','c')
 #define VLC_CODEC_RTP_VIDEO_RAW   VLC_FOURCC('R','T','P','V')
+#define VLC_CODEC_APV             VLC_FOURCC('a','p','v','1')
 
 /***********
  * Chromas


=====================================
meson_options.txt
=====================================
@@ -244,6 +244,11 @@ option('schroedinger',
     value : 'auto',
     description : 'Enable/disable schroedinger support')
 
+option('openapv',
+    type : 'feature',
+    value : 'auto',
+    description : 'Enable/disable OpenAPV decoder support')
+
 option('rsvg',
     type : 'feature',
     value : 'auto',


=====================================
modules/codec/Makefile.am
=====================================
@@ -103,6 +103,13 @@ libschroedinger_plugin_la_LIBADD = $(LIBS_schroedinger)
 EXTRA_LTLIBRARIES += libschroedinger_plugin.la
 codec_LTLIBRARIES += $(LTLIBschroedinger)
 
+libopenapv_plugin_la_SOURCES = codec/openapv.c
+libopenapv_plugin_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS_openapv)
+libopenapv_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
+libopenapv_plugin_la_LIBADD = $(LIBS_openapv)
+EXTRA_LTLIBRARIES += libopenapv_plugin.la
+codec_LTLIBRARIES += $(LTLIBopenapv)
+
 librtp_rawvid_plugin_la_SOURCES = codec/rtp-rawvid.c
 codec_LTLIBRARIES += librtp_rawvid_plugin.la
 


=====================================
modules/codec/avcodec/fourcc.c
=====================================
@@ -326,6 +326,10 @@ static const struct vlc_avcodec_fourcc video_codecs[] =
 
     { VLC_CODEC_NOTCHLC, AV_CODEC_ID_NOTCHLC },
 
+#if LIBAVCODEC_VERSION_CHECK( 62, 1, 100 )
+    { VLC_CODEC_APV, AV_CODEC_ID_APV },
+#endif
+
 };
 
 /*


=====================================
modules/codec/meson.build
=====================================
@@ -168,6 +168,17 @@ vlc_modules += {
     'enabled' : schroedinger_dep.found(),
 }
 
+# Dirac decoder and encoder using schroedinger
+openapv_dep = dependency('oapv',
+                              version: '>= 0.2',
+                              required: get_option('openapv'))
+vlc_modules += {
+    'name' : 'openapv',
+    'sources' : files('openapv.c'),
+    'dependencies' : [openapv_dep],
+    'enabled' : openapv_dep.found(),
+}
+
 # RTP Raw video codec
 vlc_modules += {
     'name' : 'rtp_rawvid',


=====================================
modules/codec/openapv.c
=====================================
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// openapv.c : APV decoder using openapv library
+// Copyright © 2025 VideoLabs, VLC authors and VideoLAN
+
+// Authors: Steve Lhomme <robux4 at videolabs.io>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+#include <vlc_modules.h>
+#include <vlc_bits.h>
+
+#include "../packetizer/iso_color_tables.h"
+
+#include <oapv.h>
+#include <limits.h>
+
+#define THREAD_TILES_TEXT N_("Tile Threads")
+#define THREAD_TILES_LONGTEXT N_( "Max number of threads used for decoding, default 0=auto" )
+
+static int OpenAPVDecoder(vlc_object_t *);
+static void CloseAPVDecoder(vlc_object_t *);
+
+vlc_module_begin ()
+    set_description(N_("OpenAPV video decoder"))
+    set_capability("video decoder", 10)
+    set_callbacks(OpenAPVDecoder, CloseAPVDecoder)
+    set_subcategory(SUBCAT_INPUT_VCODEC)
+
+    add_integer_with_range( "openapv-threads", 0, 0, INT_MAX,
+                 THREAD_TILES_TEXT, THREAD_TILES_LONGTEXT)
+vlc_module_end ()
+
+struct oapv_sys
+{
+    oapvd_t        decoder;
+    int            cs;
+};
+
+static const struct {
+    vlc_fourcc_t vlc;
+    int          oapv;
+} vlc_oapv_chromas[] = {
+    { VLC_CODEC_I422_10L, OAPV_CS_SET(OAPV_CF_YCBCR422, 10, 0) },
+    { VLC_CODEC_I422_12L, OAPV_CS_SET(OAPV_CF_YCBCR422, 12, 0) },
+    { VLC_CODEC_I422_16L, OAPV_CS_SET(OAPV_CF_YCBCR422, 16, 0) },
+    { VLC_CODEC_I444_10L, OAPV_CS_SET(OAPV_CF_YCBCR444, 10, 0) },
+    { VLC_CODEC_I444_12L, OAPV_CS_SET(OAPV_CF_YCBCR444, 12, 0) },
+    { VLC_CODEC_I444_16L, OAPV_CS_SET(OAPV_CF_YCBCR444, 16, 0) },
+    { VLC_CODEC_GREY_10L, OAPV_CS_SET(OAPV_CF_YCBCR400, 10, 0) },
+    { VLC_CODEC_GREY_12L, OAPV_CS_SET(OAPV_CF_YCBCR400, 12, 0) },
+    { VLC_CODEC_GREY_16L, OAPV_CS_SET(OAPV_CF_YCBCR400, 16, 0) },
+};
+
+static inline vlc_fourcc_t FindVlcChroma(uint8_t profile_idc, uint8_t bit_depth_minus8, uint8_t chroma_format_idc)
+{
+    if (profile_idc == 33) // 422-10 profile
+    {
+        assert(chroma_format_idc == 2);
+        assert(bit_depth_minus8 == 2);
+        return VLC_CODEC_I422_10L;
+    }
+    if (profile_idc == 44) // 422-12 profile
+    {
+        assert(chroma_format_idc == 2);
+        assert(bit_depth_minus8 >= 2 && bit_depth_minus8 <= 4);
+        return VLC_CODEC_I422_12L;
+    }
+    if (profile_idc == 55) // 444-10 profile
+    {
+        assert(chroma_format_idc == 2 || chroma_format_idc == 3);
+        assert(bit_depth_minus8 == 2);
+        return VLC_CODEC_I444_10L;
+    }
+    if (profile_idc == 66) // 444-12 profile
+    {
+        assert(chroma_format_idc == 2 || chroma_format_idc == 3);
+        assert(bit_depth_minus8 >= 2 && bit_depth_minus8 <= 4);
+        return VLC_CODEC_I444_12L;
+    }
+    // if (profile_idc == 77) // 4444-10 profile
+    // {
+    //     assert(chroma_format_idc >= 2 && chroma_format_idc <= 4);
+    //     assert(bit_depth_minus8 == 2);
+    //     return VLC_CODEC_V410;
+    // }
+    // if (profile_idc == 88) // 4444-12 profile
+    // {
+    //     assert(chroma_format_idc >= 2 && chroma_format_idc <= 4);
+    //     assert(bit_depth_minus8 >= 2 && bit_depth_minus8 <= 4);
+    //     return VLC_CODEC_V410;
+    // }
+    if (bit_depth_minus8 == 2) // 10-bit
+    {
+        switch(chroma_format_idc)
+        {
+            case 0: return VLC_CODEC_GREY_10L;
+            case 2: return VLC_CODEC_I422_10L;
+            case 3: return VLC_CODEC_I444_10L;
+            // case 4: return VLC_CODEC_I4444_10L;
+            default: return 0;
+        }
+    }
+    if (bit_depth_minus8 == 4) // 12-bit
+    {
+        switch(chroma_format_idc)
+        {
+            case 0: return VLC_CODEC_GREY_12L;
+            case 2: return VLC_CODEC_I422_12L;
+            case 3: return VLC_CODEC_I444_12L;
+            // case 4: return VLC_CODEC_I4444_12L;
+            default: return 0;
+        }
+    }
+    // if (bit_depth_minus8 == 6) // 14-bit
+    // {
+    //     switch(chroma_format_idc)
+    //     {
+    //         case 0: return VLC_CODEC_GREY_14L;
+    //         case 2: return VLC_CODEC_I422_14L;
+    //         case 3: return VLC_CODEC_I444_14L;
+    // //        case 4: return VLC_CODEC_I4444_14L;
+    //         default: return 0;
+    //     }
+    // }
+    if (bit_depth_minus8 == 8) // 16-bit
+    {
+        switch(chroma_format_idc)
+        {
+            case 0: return VLC_CODEC_GREY_16L;
+            case 2: return VLC_CODEC_I422_16L;
+            case 3: return VLC_CODEC_I444_16L;
+            // case 4: return VLC_CODEC_I4444_16L;
+            default: return 0;
+        }
+    }
+    return 0;
+}
+
+static int imgb_addref(oapv_imgb_t *imgb)
+{
+    return imgb->refcnt++;
+}
+
+static int imgb_getref(oapv_imgb_t *imgb)
+{
+    return imgb->refcnt;
+}
+
+static int imgb_release(oapv_imgb_t *imgb)
+{
+    if (--imgb->refcnt == 0)
+    {
+        picture_Release(imgb->pdata[0]);
+        free(imgb);
+        return 0;
+    }
+    return imgb->refcnt;
+}
+
+static oapv_imgb_t *GetImage( decoder_t *p_dec )
+{
+    struct oapv_sys *sys = p_dec->p_sys;
+
+    oapv_imgb_t *imgb = calloc(1, sizeof(*imgb));
+    if (imgb == NULL)
+        return NULL;
+
+    picture_t *pic = decoder_NewPicture( p_dec );
+    if (pic == NULL)
+        goto fail;
+
+    imgb->refcnt = 1;
+    imgb->cs = sys->cs;
+    imgb->pdata[0] = pic;
+    imgb->np = pic->i_planes;
+    for (int i = 0; i < pic->i_planes; i++)
+    {
+        imgb->w[i] = pic->p[i].i_visible_pitch / pic->p[i].i_pixel_pitch;
+        imgb->h[i] = pic->p[i].i_visible_lines / pic->p[i].i_pixel_pitch;
+
+        imgb->aw[i] = pic->p[i].i_pitch / pic->p[i].i_pixel_pitch;
+        imgb->s[i] = pic->p[i].i_pitch;
+        imgb->ah[i] = pic->p[i].i_lines / pic->p[i].i_pixel_pitch;
+        imgb->e[i] = pic->p[i].i_lines;
+        imgb->bsize[i] = imgb->s[i] * imgb->e[i];
+        imgb->a[i] = pic->p[i].p_pixels;
+    }
+
+    imgb->addref = imgb_addref;
+    imgb->getref = imgb_getref;
+    imgb->release = imgb_release;
+
+    return imgb;
+fail:
+    free(imgb);
+    return NULL;
+}
+
+static int Decode( decoder_t *p_dec, block_t *p_block )
+{
+    struct oapv_sys *sys = p_dec->p_sys;
+
+    if (p_block == NULL) // drain nothing to do
+        return VLCDEC_SUCCESS;
+
+    oapv_frms_t  ofrms = { 0 };
+    oapvm_t      mid = { 0 };
+    oapv_bitb_t  bitb = { 0 };
+    oapvd_stat_t stats = { 0 };
+    int err;
+
+    ofrms.num_frms = 1;
+    ofrms.frm[0].imgb = GetImage(p_dec);
+    if (ofrms.frm[0].imgb == NULL)
+        return VLCDEC_ECRITICAL; // no more memory ?
+
+    bitb.addr = p_block->p_buffer;
+    bitb.ssize = p_block->i_buffer;
+
+    err = oapvd_decode(sys->decoder, &bitb, &ofrms, &mid, &stats);
+    if (unlikely(err != OAPV_OK))
+    {
+        msg_Err( p_dec, "decoding error %d", err );
+        ofrms.frm[0].imgb->release(ofrms.frm[0].imgb);
+        return VLCDEC_ECRITICAL;
+    }
+
+    assert(stats.aui.num_frms == 1 || stats.aui.num_frms == 0);
+    if (stats.aui.num_frms == 1)
+    {
+        picture_t *decoded = ofrms.frm[0].imgb->pdata[0];
+        picture_Hold(decoded);
+        decoded->date = p_block->i_pts != VLC_TICK_INVALID ? p_block->i_pts : p_block->i_dts;
+
+        decoder_QueueVideo( p_dec, decoded );
+    }
+    for (int i=0; i<stats.aui.num_frms; i++)
+    {
+        ofrms.frm[i].imgb->release(ofrms.frm[i].imgb);
+    }
+
+    return VLCDEC_SUCCESS;
+}
+
+
+int OpenAPVDecoder(vlc_object_t *o)
+{
+    decoder_t *dec = container_of(o, decoder_t, obj);
+    if (dec->fmt_in->i_codec != VLC_CODEC_APV)
+        return VLC_ENOTSUP;
+
+    uint8_t color_primaries = 2;
+    uint8_t transfer_characteristics = 2;
+    uint8_t matrix_coefficients = 2;
+    uint8_t profile_idc = 0;
+    uint8_t chroma_format_idc = 0;
+    uint8_t bit_depth_minus8 = 2;
+    bool full_range_flag = false;
+    uint32_t frame_width = dec->fmt_in->video.i_width;
+    uint32_t frame_height = dec->fmt_in->video.i_height;
+
+    // parse extradata to get stream info
+    bs_t extra;
+    bs_init(&extra, dec->fmt_in->p_extra, dec->fmt_in->i_extra);
+    uint8_t configurationVersion = bs_read(&extra, 8);
+    if (configurationVersion != 1)
+    {
+        msg_Dbg(o, "unknown configuration %" PRIu8, configurationVersion);
+        return VLC_ENOTSUP;
+    }
+
+    uint32_t number_of_configuration_entry = bs_read(&extra, 8);
+    if (number_of_configuration_entry != 1)
+    {
+        msg_Err(o, "unsupported number of configurations (%u)", (unsigned)number_of_configuration_entry);
+        return VLC_EGENERIC;
+    }
+    bs_skip(&extra, 8); // pbu_type
+    uint8_t number_of_frame_info = bs_read(&extra, 8);
+    if (number_of_frame_info != 1)
+    {
+        msg_Err(o, "unsupported number of frames (%u)", (unsigned)number_of_frame_info);
+        return VLC_EGENERIC;
+    }
+    bs_skip(&extra, 6);
+    bool color_description_present_flag = bs_read1(&extra);
+    bs_skip(&extra, 1); // capture_time_distance_ignored
+    profile_idc = bs_read(&extra, 8);
+    bs_skip(&extra, 8); // level_idc
+    bs_skip(&extra, 8); // band_idc
+    frame_width = bs_read(&extra, 32);
+    frame_height = bs_read(&extra, 32);
+    chroma_format_idc = bs_read(&extra, 4);
+    bit_depth_minus8 = bs_read(&extra, 4);
+    bs_skip(&extra, 8); // capture_time_distance
+    if (color_description_present_flag)
+    {
+        color_primaries = bs_read(&extra, 8);
+        transfer_characteristics = bs_read(&extra, 8);
+        matrix_coefficients = bs_read(&extra, 8);
+        full_range_flag = bs_read1(&extra);
+        bs_skip(&extra, 7); // reserved
+    }
+
+    struct oapv_sys *sys = vlc_obj_malloc(o, sizeof(*sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    oapvd_cdesc_t desc = { 0 };
+    desc.threads = var_InheritInteger( o, "openapv-threads" );
+    sys->decoder = oapvd_create(&desc, NULL);
+    if (sys->decoder == NULL)
+    {
+        msg_Err(o, "failed to create decoder");
+        return VLC_EGENERIC;
+    }
+
+    if (dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF)
+        dec->fmt_out.video.primaries = iso_23001_8_cp_to_vlc_primaries(color_primaries);
+    else
+        dec->fmt_out.video.primaries = dec->fmt_in->video.primaries;
+    if (dec->fmt_in->video.transfer == TRANSFER_FUNC_UNDEF)
+        dec->fmt_out.video.transfer = iso_23001_8_tc_to_vlc_xfer(transfer_characteristics);
+    else
+        dec->fmt_out.video.transfer = dec->fmt_in->video.transfer;
+    if (dec->fmt_in->video.space == COLOR_SPACE_UNDEF)
+        dec->fmt_out.video.space = iso_23001_8_mc_to_vlc_coeffs(matrix_coefficients);
+    else
+        dec->fmt_out.video.space = dec->fmt_in->video.space;
+    if (dec->fmt_in->video.color_range == COLOR_RANGE_UNDEF)
+        dec->fmt_out.video.color_range = full_range_flag ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
+    else
+        dec->fmt_out.video.color_range = dec->fmt_in->video.color_range;
+
+    dec->fmt_out.video.i_width = frame_width;
+    dec->fmt_out.video.i_height = frame_height;
+
+    dec->fmt_out.i_codec = FindVlcChroma(profile_idc, bit_depth_minus8, chroma_format_idc);
+    dec->fmt_out.video.i_chroma = dec->fmt_out.i_codec;
+
+    if (decoder_UpdateVideoOutput(dec, NULL) != 0)
+    {
+        msg_Err(o, "decoder_UpdateVideoOutput failed");
+        CloseAPVDecoder(o);
+        return VLC_EGENERIC;
+    }
+    for (size_t i=0; i < ARRAY_SIZE(vlc_oapv_chromas); i++)
+    {
+        if (dec->fmt_out.video.i_chroma == vlc_oapv_chromas[i].vlc)
+        {
+            sys->cs = vlc_oapv_chromas[i].oapv;
+            break;
+        }
+    }
+
+    dec->p_sys = sys;
+
+    dec->pf_decode = Decode;
+
+    return VLC_SUCCESS;
+}
+
+void CloseAPVDecoder(vlc_object_t *o)
+{
+    decoder_t *dec = container_of(o, decoder_t, obj);
+    struct oapv_sys *sys = dec->p_sys;
+    oapvd_delete(sys->decoder);
+}


=====================================
modules/demux/mp4/essetup.c
=====================================
@@ -639,6 +639,24 @@ int SetupVideoES( demux_t *p_demux, const mp4_track_t *p_track, const MP4_Box_t
             break;
         }
 
+        case ATOM_apv1:
+        {
+            const MP4_Box_t *p_binary = MP4_BoxGet(  p_sample, "apvC" );
+            if( p_binary && p_binary->data.p_binary->i_blob > 4 &&
+                GetDWBE(p_binary->data.p_binary->p_blob) == 0 ) /* fullbox header */
+            {
+                size_t i_extra = p_binary->data.p_binary->i_blob - 4;
+                uint8_t *p_extra = malloc(i_extra);
+                if( likely( p_extra ) )
+                {
+                    p_fmt->i_extra = i_extra;
+                    p_fmt->p_extra = p_extra;
+                    memcpy( p_extra, ((uint8_t *)p_binary->data.p_binary->p_blob) + 4, i_extra);
+                }
+            }
+            break;
+        }
+
         /* avc1: send avcC (h264 without annexe B, ie without start code)*/
         case VLC_FOURCC( 'a', 'v', 'c', '3' ):
         case VLC_FOURCC( 'a', 'v', 'c', '1' ):


=====================================
modules/demux/mp4/libmp4.c
=====================================
@@ -5110,6 +5110,7 @@ static const struct
     { ATOM_avcC,    MP4_ReadBox_avcC,         ATOM_avc1 },
     { ATOM_avcC,    MP4_ReadBox_avcC,         ATOM_avc3 },
     { ATOM_vvcC,    MP4_ReadBox_Binary,       ATOM_vvc1 },
+    { ATOM_apvC,    MP4_ReadBox_Binary,       ATOM_apv1 },
     { ATOM_hvcC,    MP4_ReadBox_Binary,       0 },
     { ATOM_jpeC,    MP4_ReadBox_Binary,       0 }, /* heif */
     { ATOM_av1C,    MP4_ReadBox_av1C,         ATOM_ipco }, /* heif */


=====================================
modules/demux/mp4/libmp4.h
=====================================
@@ -277,6 +277,8 @@ typedef int64_t stime_t;
 #define ATOM_vpcC VLC_FOURCC( 'v', 'p', 'c', 'C' )
 #define ATOM_vvc1 VLC_FOURCC( 'v', 'v', 'c', '1' )
 #define ATOM_vvcC VLC_FOURCC( 'v', 'v', 'c', 'C' )
+#define ATOM_apv1 VLC_FOURCC( 'a', 'p', 'v', '1' )
+#define ATOM_apvC VLC_FOURCC( 'a', 'p', 'v', 'C' )
 #define ATOM_m4ds VLC_FOURCC( 'm', '4', 'd', 's' )
 
 #define ATOM_fiel VLC_FOURCC( 'f', 'i', 'e', 'l' )


=====================================
modules/demux/mp4/mp4.c
=====================================
@@ -1697,6 +1697,14 @@ static int DemuxTrack( demux_t *p_demux, mp4_track_t *tk, uint64_t i_readpos,
 
             p_block->i_length = MP4_GetSamplesDuration( tk, i_nb_samples );
 
+            if ( tk->fmt.i_codec == VLC_CODEC_APV )
+            {
+                // the APU are preceeded by 4 bytes containing the size of the data
+                // this is not used by decoder like libavcodec or openapv.
+                p_block->p_buffer += 4;
+                p_block->i_buffer -= 4;
+            }
+
             MP4_Block_Send( p_demux, tk, p_block );
         }
 


=====================================
src/misc/fourcc_list.h
=====================================
@@ -1309,6 +1309,8 @@ static const staticentry_t p_list_video[] = {
     B(VLC_CODEC_NOTCHLC, "NotchLC"),
 
     B(VLC_CODEC_RTP_VIDEO_RAW, "RTP raw video"),
+
+    B(VLC_CODEC_APV, "Advanced Professional Video (APV)"),
 };
 
 static const staticentry_t p_list_audio[] = {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/88fb5d501f8110ea1b52062f58c62fa5f52ae325...9adb6ce4a955973ca8642aa351d0e3ad81908650

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/88fb5d501f8110ea1b52062f58c62fa5f52ae325...9adb6ce4a955973ca8642aa351d0e3ad81908650
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list