mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
Compare commits
130 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9687cae2b4 | |||
| 70522b7262 | |||
| 1ed490b9dc | |||
| 9cd9f958eb | |||
| 89374decf6 | |||
| 3010773508 | |||
| 482d51884c | |||
| a50aa980eb | |||
| 550d70fde3 | |||
| f93ca3a278 | |||
| 4e61bf403f | |||
| cffa10a0cb | |||
| 08206484bc | |||
| afa04c1e9e | |||
| 07d953187b | |||
| 2ae18635da | |||
| d0e9e8c5d0 | |||
| 8fd2dc3f2b | |||
| fd4121a0aa | |||
| ba595e8d83 | |||
| 518b7474b2 | |||
| 5c1ae6738a | |||
| d63e7c3b39 | |||
| 8b13cfcc3c | |||
| 478bd4c73f | |||
| e35f910591 | |||
| ffe1ded457 | |||
| af2913d46f | |||
| debfbad67a | |||
| ee16bb81de | |||
| 637bda4cdd | |||
| 780de33f32 | |||
| 49f8f8ba20 | |||
| 849a20343d | |||
| 95322e0767 | |||
| 432cbff7bb | |||
| 32778e5a5e | |||
| f87f100558 | |||
| 5c4fdf111e | |||
| 6bd882f98a | |||
| 405c75998d | |||
| f514336829 | |||
| 096a936567 | |||
| 025bf57f77 | |||
| 473ea811db | |||
| e086aeb792 | |||
| 2e901b1304 | |||
| 0ea439dab7 | |||
| 0dabd7f603 | |||
| 0a5feebc57 | |||
| ba92c416af | |||
| 7a9ea4399d | |||
| fc85847223 | |||
| ea98cb2465 | |||
| f1ae880298 | |||
| 911d7f167c | |||
| a394d35a43 | |||
| 2bc8c87b2e | |||
| a66b58d61c | |||
| 390d6853d0 | |||
| e540605d42 | |||
| 4a9ec4d4e3 | |||
| 171802a1ba | |||
| af06b9255f | |||
| 99d6ab7154 | |||
| 92c57aece4 | |||
| 58922dc565 | |||
| fa1328babf | |||
| cd74c838fc | |||
| ce1558e66b | |||
| fb840a79b9 | |||
| 0acca1791e | |||
| e53ab575da | |||
| 832aae6c86 | |||
| 91b459ab23 | |||
| 1c2d1d988a | |||
| 4eb182b714 | |||
| 201a486a11 | |||
| 48e85918b8 | |||
| 60604702cd | |||
| fbbbe73b0f | |||
| e9b7e781d7 | |||
| 6d2317a611 | |||
| 237268f6df | |||
| 519e22b31e | |||
| 24f1997822 | |||
| a20d6eb223 | |||
| 359836ce6c | |||
| 9b099a97f0 | |||
| 6ff38630e1 | |||
| 60d6efe218 | |||
| 3975f9328a | |||
| 743d26ca04 | |||
| c8df72fce5 | |||
| 761a65106b | |||
| f59e8666f9 | |||
| b04b475917 | |||
| eb091d211f | |||
| 85fca9f92b | |||
| b4d254f2e6 | |||
| b9dbb6c114 | |||
| d4baad9fe3 | |||
| 2c1dd39a98 | |||
| 8d18c08f0c | |||
| 2186555bc9 | |||
| 5fd7b8e9b2 | |||
| 696079924a | |||
| 660858a9e4 | |||
| 1477386ca2 | |||
| 052ee78d14 | |||
| 8688209176 | |||
| 55ff7356bf | |||
| c327743ee0 | |||
| 74210138a4 | |||
| b059ded2a9 | |||
| 2641f7338d | |||
| 3cad1f756e | |||
| 9f7875c18e | |||
| 656ffdbd28 | |||
| df94cdde4b | |||
| 1292a8d91b | |||
| 795f803a47 | |||
| a5f1f0558f | |||
| ff9bb93145 | |||
| f582e40595 | |||
| a02d3054ea | |||
| 312060ecfc | |||
| 311ea9c529 | |||
| b01ac2d863 | |||
| 1f447cf9c4 |
@@ -1,7 +1,68 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version <next>:
|
||||
version 5.0.1:
|
||||
- avcodec/exr: Avoid signed overflow in displayWindow
|
||||
- avcodec/diracdec: avoid signed integer overflow in global mv
|
||||
- avcodec/takdsp: Fix integer overflow in decorrelate_sf()
|
||||
- avcodec/apedec: fix a integer overflow in long_filter_high_3800()
|
||||
- avdevice/dshow: fix regression
|
||||
- avfilter/vf_subtitles: pass storage size to libass
|
||||
- avcodec/vp9_superframe_split_bsf: Don't read inexistent data
|
||||
- avcodec/vp9_superframe_split_bsf: Discard invalid zero-sized frames
|
||||
- avcodec/vp9_superframe_bsf: Check for existence of data before reading it
|
||||
- avcodec/vp9_raw_reorder_bsf: Check for existence of data before reading it
|
||||
- avformat/imf: fix packet pts, dts and muxing
|
||||
- avformat/imf: open resources only when first needed
|
||||
- avformat/imf: cosmetics
|
||||
- avformat/imf_cpl: do not use filesize when reading XML file
|
||||
- avformat/imfdec: Use proper logcontext
|
||||
- avformat/imfdec: do not use filesize when reading XML file
|
||||
- doc/utils: add missing 22.2 layout entry
|
||||
- avcodec/av1: only set the private context pix_fmt field if get_pixel_format() succeeds
|
||||
- avformat/aqtitledec: Skip unrepresentable durations
|
||||
- avformat/cafdec: Do not store empty keys in read_info_chunk()
|
||||
- avformat/mxfdec: Do not clear array in mxf_read_strong_ref_array() before writing
|
||||
- avformat/mxfdec: Check for avio_read() failure in mxf_read_strong_ref_array()
|
||||
- avformat/mxfdec: Check count in mxf_read_strong_ref_array()
|
||||
- avformat/hls: Check target_duration
|
||||
- avcodec/pixlet: Avoid signed integer overflow in scaling in filterfn()
|
||||
- avformat/matroskadec: Check pre_ns
|
||||
- avcodec/sonic: Use unsigned for predictor_k to avoid undefined behavior
|
||||
- avcodec/libuavs3d: Check ff_set_dimensions() for failure
|
||||
- avcodec/speexdec: Align some comments
|
||||
- avcodec/speexdec: Use correct doxygen comments
|
||||
- avcodec/mjpegbdec: Set buf_size
|
||||
- avformat/matroskadec: Use rounded down duration in get_cue_desc() check
|
||||
- avcodec/argo: Check packet size
|
||||
- avcodec/g729_parser: Check channels
|
||||
- avformat/avidec: Check height
|
||||
- avformat/rmdec: Better duplicate tags check
|
||||
- avformat/mov: Disallow empty sidx
|
||||
- avformat/argo_cvg:: Fix order of operations in error check in argo_cvg_write_trailer()
|
||||
- avformat/argo_asf: Fix order of operations in error check in argo_asf_write_trailer()
|
||||
- avcodec/movtextdec: add () to CMP() macro to avoid unexpected behavior
|
||||
- avformat/matroskadec: Check duration
|
||||
- avformat/mov: Corner case encryption error cleanup in mov_read_senc()
|
||||
- avcodec/jpeglsdec: Fix if( code style
|
||||
- avcodec/jpeglsdec: Check get_ur_golomb_jpegls() for error
|
||||
- avcodec/motion_est: fix indention of ff_get_best_fcode()
|
||||
- avcodec/motion_est: Fix xy indexing on range violation in ff_get_best_fcode()
|
||||
- avformat/hls: Use unsigned for iv computation
|
||||
- avcodec/jpeglsdec: Increase range for N in ls_get_code_runterm() by using unsigned
|
||||
- avformat/matroskadec: Check desc_bytes
|
||||
- avformat/utils: Fix invalid NULL pointer operation in ff_parse_key_value()
|
||||
- avformat/matroskadec: Fix infinite loop with bz decompression
|
||||
- avformat/utils: keep chapter monotonicity on chapter updates
|
||||
- avformat/mov: Check size before subtraction
|
||||
- avcodec/cfhd: Avoid signed integer overflow in coeff
|
||||
- avcodec/libdav1d: free the Dav1dData packet on dav1d_send_data() failure
|
||||
- avcodec/h264_parser: don't alter decoder private data
|
||||
- configure: link to libatomic when it's present
|
||||
- fate/ffmpeg: add missing samples dependency to fate-shortest
|
||||
|
||||
|
||||
version 5.0:
|
||||
- ADPCM IMA Westwood encoder
|
||||
- Westwood AUD muxer
|
||||
- ADPCM IMA Acorn Replay decoder
|
||||
@@ -44,6 +105,7 @@ version <next>:
|
||||
- yadif_videotoolbox filter
|
||||
- VideoToolbox ProRes encoder
|
||||
- anlmf audio filter
|
||||
- IMF demuxer (experimental)
|
||||
|
||||
|
||||
version 4.4:
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 5.0 "Lorentz" │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 5.0 "Lorentz", about 9
|
||||
months after the release of FFmpeg 4.4.
|
||||
|
||||
A complete Changelog is available at the root of the project, and the
|
||||
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
|
||||
|
||||
We hope you will like this release as much as we enjoyed working on it, and
|
||||
as usual, if you have any questions about it, or any FFmpeg related topic,
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.libera.chat) or ask
|
||||
on the mailing-lists.
|
||||
@@ -3353,7 +3353,7 @@ librav1e_encoder_deps="librav1e"
|
||||
librav1e_encoder_select="extract_extradata_bsf"
|
||||
librsvg_decoder_deps="librsvg"
|
||||
libshine_encoder_deps="libshine"
|
||||
libshine_encoder_select="audio_frame_queue"
|
||||
libshine_encoder_select="audio_frame_queue mpegaudioheader"
|
||||
libspeex_decoder_deps="libspeex"
|
||||
libspeex_encoder_deps="libspeex"
|
||||
libspeex_encoder_select="audio_frame_queue"
|
||||
@@ -3391,6 +3391,7 @@ ac3_demuxer_select="ac3_parser"
|
||||
act_demuxer_select="riffdec"
|
||||
adts_muxer_select="mpeg4audio"
|
||||
aiff_muxer_select="iso_media"
|
||||
amv_muxer_select="riffenc"
|
||||
asf_demuxer_select="riffdec"
|
||||
asf_o_demuxer_select="riffdec"
|
||||
asf_muxer_select="riffenc"
|
||||
@@ -3476,7 +3477,6 @@ w64_muxer_select="wav_muxer"
|
||||
wav_demuxer_select="riffdec"
|
||||
wav_muxer_select="riffenc"
|
||||
webm_chunk_muxer_select="webm_muxer"
|
||||
webm_muxer_select="mpeg4audio riffenc"
|
||||
webm_dash_manifest_demuxer_select="matroska_demuxer"
|
||||
wtv_demuxer_select="mpegts_demuxer riffdec"
|
||||
wtv_muxer_select="mpegts_muxer riffenc"
|
||||
@@ -3498,6 +3498,7 @@ caca_outdev_deps="libcaca"
|
||||
decklink_deps_any="libdl LoadLibrary"
|
||||
decklink_indev_deps="decklink threads"
|
||||
decklink_indev_extralibs="-lstdc++"
|
||||
decklink_indev_suggest="libzvbi"
|
||||
decklink_outdev_deps="decklink threads"
|
||||
decklink_outdev_suggest="libklvanc"
|
||||
decklink_outdev_extralibs="-lstdc++"
|
||||
@@ -3790,20 +3791,20 @@ cws2fws_extralibs="zlib_extralibs"
|
||||
|
||||
# libraries, in any order
|
||||
avcodec_deps="avutil"
|
||||
avcodec_suggest="libm"
|
||||
avcodec_suggest="libm stdatomic"
|
||||
avdevice_deps="avformat avcodec avutil"
|
||||
avdevice_suggest="libm"
|
||||
avdevice_suggest="libm stdatomic"
|
||||
avfilter_deps="avutil"
|
||||
avfilter_suggest="libm"
|
||||
avfilter_suggest="libm stdatomic"
|
||||
avformat_deps="avcodec avutil"
|
||||
avformat_suggest="libm network zlib"
|
||||
avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
|
||||
avformat_suggest="libm network zlib stdatomic"
|
||||
avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi vulkan videotoolbox corefoundation corevideo coremedia bcrypt stdatomic"
|
||||
postproc_deps="avutil gpl"
|
||||
postproc_suggest="libm"
|
||||
postproc_suggest="libm stdatomic"
|
||||
swresample_deps="avutil"
|
||||
swresample_suggest="libm libsoxr"
|
||||
swresample_suggest="libm libsoxr stdatomic"
|
||||
swscale_deps="avutil"
|
||||
swscale_suggest="libm"
|
||||
swscale_suggest="libm stdatomic"
|
||||
|
||||
avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs"
|
||||
avfilter_extralibs="pthreads_extralibs"
|
||||
@@ -6320,7 +6321,14 @@ check_headers asm/types.h
|
||||
# it seems there are versions of clang in some distros that try to use the
|
||||
# gcc headers, which explodes for stdatomic
|
||||
# so we also check that atomics actually work here
|
||||
check_builtin stdatomic stdatomic.h "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar"
|
||||
#
|
||||
# some configurations also require linking to libatomic, so try
|
||||
# both with -latomic and without
|
||||
for LATOMIC in "-latomic" ""; do
|
||||
check_builtin stdatomic stdatomic.h \
|
||||
"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar" \
|
||||
$LATOMIC && eval stdatomic_extralibs="\$LATOMIC" && break
|
||||
done
|
||||
|
||||
check_lib advapi32 "windows.h" RegCloseKey -ladvapi32
|
||||
check_lib bcrypt "windows.h bcrypt.h" BCryptGenRandom -lbcrypt &&
|
||||
@@ -6586,7 +6594,7 @@ enabled libopus && {
|
||||
require_pkg_config libopus opus opus_multistream.h opus_multistream_surround_encoder_create
|
||||
}
|
||||
}
|
||||
enabled libplacebo && require_pkg_config libplacebo "libplacebo >= 4.184.0" libplacebo/vulkan.h pl_vulkan_create
|
||||
enabled libplacebo && require_pkg_config libplacebo "libplacebo >= 4.192.0" libplacebo/vulkan.h pl_vulkan_create
|
||||
enabled libpulse && require_pkg_config libpulse libpulse pulse/pulseaudio.h pa_context_new
|
||||
enabled librabbitmq && require_pkg_config librabbitmq "librabbitmq >= 0.7.1" amqp.h amqp_new_connection
|
||||
enabled librav1e && require_pkg_config librav1e "rav1e >= 0.4.0" rav1e.h rav1e_context_new
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_NUMBER = 5.0.1
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -719,6 +719,8 @@ FL+FR+FC+BL+BR+BC+SL+SR
|
||||
FL+FR+FC+BL+BR+BC+SL+SR+WL+WR+TBL+TBR+TBC+TFC+TFL+TFR
|
||||
@item downmix
|
||||
DL+DR
|
||||
@item 22.2
|
||||
FL+FR+FC+LFE+BL+BR+FLC+FRC+BC+SL+SR+TC+TFL+TFC+TFR+TBL+TBC+TBR+LFE2+TSL+TSR+BFC+BFL+BFR
|
||||
@end table
|
||||
|
||||
A custom channel layout can be specified as a sequence of terms, separated by
|
||||
|
||||
+1
-1
@@ -1823,7 +1823,7 @@ int show_sample_fmts(void *optctx, const char *opt, const char *arg)
|
||||
int show_dispositions(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
for (int i = 0; i < 32; i++) {
|
||||
const char *str = av_disposition_to_string(1 << i);
|
||||
const char *str = av_disposition_to_string(1U << i);
|
||||
if (str)
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
+7
-5
@@ -118,7 +118,8 @@ OBJS-$(CONFIG_MDCT) += mdct_float.o mdct_fixed_32.o
|
||||
OBJS-$(CONFIG_ME_CMP) += me_cmp.o
|
||||
OBJS-$(CONFIG_MEDIACODEC) += mediacodecdec_common.o mediacodec_surface.o mediacodec_wrapper.o mediacodec_sw_buffer.o
|
||||
OBJS-$(CONFIG_MPEG_ER) += mpeg_er.o
|
||||
OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodec_common.o
|
||||
OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodec_common.o \
|
||||
mpegaudiodata.o
|
||||
OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \
|
||||
mpegaudiodsp_data.o \
|
||||
mpegaudiodsp_fixed.o \
|
||||
@@ -133,7 +134,6 @@ OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \
|
||||
motion_est.o ratecontrol.o \
|
||||
mpegvideoencdsp.o
|
||||
OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o
|
||||
OBJS-$(CONFIG_NVENC) += nvenc.o
|
||||
OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
|
||||
OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
|
||||
OBJS-$(CONFIG_QSV) += qsv.o
|
||||
@@ -381,7 +381,7 @@ OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_H264_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
|
||||
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o
|
||||
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o nvenc.o
|
||||
OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o
|
||||
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
|
||||
@@ -396,12 +396,13 @@ OBJS-$(CONFIG_HCA_DECODER) += hcadec.o
|
||||
OBJS-$(CONFIG_HCOM_DECODER) += hcom.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
|
||||
hevc_cabac.o hevc_refs.o hevcpred.o \
|
||||
hevcdsp.o hevc_filter.o hevc_data.o
|
||||
hevcdsp.o hevc_filter.o hevc_data.o \
|
||||
h274.o
|
||||
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o nvenc.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \
|
||||
hevc_data.o
|
||||
@@ -886,6 +887,7 @@ OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o
|
||||
OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_ACORN_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_AMV_ENCODER) += adpcmenc.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_ALP_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_ALP_ENCODER) += adpcmenc.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o
|
||||
|
||||
@@ -75,7 +75,11 @@ av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
|
||||
c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_neon;
|
||||
c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_neon;
|
||||
c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_neon;
|
||||
c->sao_band_filter[0] = ff_hevc_sao_band_filter_8x8_8_neon;
|
||||
// This function is disabled, as it doesn't handle widths that aren't
|
||||
// an even multiple of 8 correctly. fate-hevc doesn't exercise that
|
||||
// for the current size, but if enabled for bigger sizes, the cases
|
||||
// of non-multiple of 8 seem to arise.
|
||||
// c->sao_band_filter[0] = ff_hevc_sao_band_filter_8x8_8_neon;
|
||||
}
|
||||
if (bit_depth == 10) {
|
||||
c->add_residual[0] = ff_hevc_add_residual_4x4_10_neon;
|
||||
|
||||
+9
-9
@@ -955,7 +955,7 @@ static void long_filter_high_3800(int32_t *buffer, int order, int shift, int len
|
||||
dotprod += delay[j] * (unsigned)coeffs[j];
|
||||
coeffs[j] += ((delay[j] >> 31) | 1) * sign;
|
||||
}
|
||||
buffer[i] -= dotprod >> shift;
|
||||
buffer[i] -= (unsigned)(dotprod >> shift);
|
||||
for (j = 0; j < order - 1; j++)
|
||||
delay[j] = delay[j + 1];
|
||||
delay[order - 1] = buffer[i];
|
||||
@@ -1088,13 +1088,13 @@ static av_always_inline int predictor_update_3930(APEPredictor *p,
|
||||
const int delayA)
|
||||
{
|
||||
int32_t predictionA, sign;
|
||||
int32_t d0, d1, d2, d3;
|
||||
uint32_t d0, d1, d2, d3;
|
||||
|
||||
p->buf[delayA] = p->lastA[filter];
|
||||
d0 = p->buf[delayA ];
|
||||
d1 = p->buf[delayA ] - p->buf[delayA - 1];
|
||||
d2 = p->buf[delayA - 1] - p->buf[delayA - 2];
|
||||
d3 = p->buf[delayA - 2] - p->buf[delayA - 3];
|
||||
d1 = p->buf[delayA ] - (unsigned)p->buf[delayA - 1];
|
||||
d2 = p->buf[delayA - 1] - (unsigned)p->buf[delayA - 2];
|
||||
d3 = p->buf[delayA - 2] - (unsigned)p->buf[delayA - 3];
|
||||
|
||||
predictionA = d0 * p->coeffsA[filter][0] +
|
||||
d1 * p->coeffsA[filter][1] +
|
||||
@@ -1105,10 +1105,10 @@ static av_always_inline int predictor_update_3930(APEPredictor *p,
|
||||
p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5);
|
||||
|
||||
sign = APESIGN(decoded);
|
||||
p->coeffsA[filter][0] += ((d0 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][1] += ((d1 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][2] += ((d2 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][3] += ((d3 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][0] += (((int32_t)d0 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][1] += (((int32_t)d1 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][2] += (((int32_t)d2 < 0) * 2 - 1) * sign;
|
||||
p->coeffsA[filter][3] += (((int32_t)d3 < 0) * 2 - 1) * sign;
|
||||
|
||||
return p->filterA[filter];
|
||||
}
|
||||
|
||||
@@ -607,6 +607,9 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
uint32_t chunk;
|
||||
int ret;
|
||||
|
||||
if (avpkt->size < 4)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
bytestream2_init(gb, avpkt->data, avpkt->size);
|
||||
|
||||
if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
|
||||
|
||||
+4
-3
@@ -499,9 +499,8 @@ static int get_pixel_format(AVCodecContext *avctx)
|
||||
|
||||
if (pix_fmt == AV_PIX_FMT_NONE)
|
||||
return -1;
|
||||
s->pix_fmt = pix_fmt;
|
||||
|
||||
switch (s->pix_fmt) {
|
||||
switch (pix_fmt) {
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
#if CONFIG_AV1_DXVA2_HWACCEL
|
||||
*fmtp++ = AV_PIX_FMT_DXVA2_VLD;
|
||||
@@ -544,7 +543,7 @@ static int get_pixel_format(AVCodecContext *avctx)
|
||||
break;
|
||||
}
|
||||
|
||||
*fmtp++ = s->pix_fmt;
|
||||
*fmtp++ = pix_fmt;
|
||||
*fmtp = AV_PIX_FMT_NONE;
|
||||
|
||||
ret = ff_thread_get_format(avctx, pix_fmts);
|
||||
@@ -562,6 +561,7 @@ static int get_pixel_format(AVCodecContext *avctx)
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
s->pix_fmt = pix_fmt;
|
||||
avctx->pix_fmt = ret;
|
||||
|
||||
return 0;
|
||||
@@ -1240,6 +1240,7 @@ const AVCodec ff_av1_decoder = {
|
||||
.flush = av1_decode_flush,
|
||||
.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
|
||||
.priv_class = &av1_class,
|
||||
.bsfs = "av1_frame_split",
|
||||
.hw_configs = (const AVCodecHWConfigInternal *const []) {
|
||||
#if CONFIG_AV1_DXVA2_HWACCEL
|
||||
HWACCEL_DXVA2(av1),
|
||||
|
||||
+2
-2
@@ -838,7 +838,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
const uint16_t q = s->quantisation;
|
||||
|
||||
for (i = 0; i < run; i++) {
|
||||
*coeff_data |= coeff * 256;
|
||||
*coeff_data |= coeff * 256U;
|
||||
*coeff_data++ *= q;
|
||||
}
|
||||
} else {
|
||||
@@ -869,7 +869,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
const uint16_t q = s->quantisation;
|
||||
|
||||
for (i = 0; i < run; i++) {
|
||||
*coeff_data |= coeff * 256;
|
||||
*coeff_data |= coeff * 256U;
|
||||
*coeff_data++ *= q;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1432,8 +1432,8 @@ static void global_mv(DiracContext *s, DiracBlock *block, int x, int y, int ref)
|
||||
int *c = s->globalmc[ref].perspective;
|
||||
|
||||
int64_t m = (1<<ep) - (c[0]*(int64_t)x + c[1]*(int64_t)y);
|
||||
int64_t mx = m * (int64_t)((A[0][0] * (int64_t)x + A[0][1]*(int64_t)y) + (1LL<<ez) * b[0]);
|
||||
int64_t my = m * (int64_t)((A[1][0] * (int64_t)x + A[1][1]*(int64_t)y) + (1LL<<ez) * b[1]);
|
||||
int64_t mx = m * (uint64_t)((A[0][0] * (int64_t)x + A[0][1]*(int64_t)y) + (1LL<<ez) * b[0]);
|
||||
int64_t my = m * (uint64_t)((A[1][0] * (int64_t)x + A[1][1]*(int64_t)y) + (1LL<<ez) * b[1]);
|
||||
|
||||
block->u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep);
|
||||
block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep);
|
||||
|
||||
+2
-2
@@ -1832,8 +1832,8 @@ static int decode_header(EXRContext *s, AVFrame *frame)
|
||||
dx = bytestream2_get_le32(gb);
|
||||
dy = bytestream2_get_le32(gb);
|
||||
|
||||
s->w = dx - sx + 1;
|
||||
s->h = dy - sy + 1;
|
||||
s->w = (unsigned)dx - sx + 1;
|
||||
s->h = (unsigned)dy - sy + 1;
|
||||
|
||||
continue;
|
||||
} else if ((var_size = check_header_variable(s, "lineOrder",
|
||||
|
||||
@@ -48,6 +48,9 @@ static int g729_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
|
||||
s->block_size = (avctx->bit_rate < 8000) ? G729D_6K4_BLOCK_SIZE : G729_8K_BLOCK_SIZE;
|
||||
if (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN)
|
||||
s->block_size++;
|
||||
// channels > 2 is invalid, we pass the packet on unchanged
|
||||
if (avctx->channels > 2)
|
||||
s->block_size = 0;
|
||||
s->block_size *= avctx->channels;
|
||||
s->duration = avctx->frame_size;
|
||||
}
|
||||
|
||||
@@ -247,7 +247,6 @@ static inline int parse_nal_units(AVCodecParserContext *s,
|
||||
const uint8_t * const buf, int buf_size)
|
||||
{
|
||||
H264ParseContext *p = s->priv_data;
|
||||
H264Context *h = avctx->priv_data;
|
||||
H2645RBSP rbsp = { NULL };
|
||||
H2645NAL nal = { NULL };
|
||||
int buf_index, next_avc;
|
||||
@@ -553,11 +552,9 @@ static inline int parse_nal_units(AVCodecParserContext *s,
|
||||
p->last_picture_structure = s->picture_structure;
|
||||
p->last_frame_num = p->poc.frame_num;
|
||||
}
|
||||
if (h && sps->timing_info_present_flag) {
|
||||
if (sps->timing_info_present_flag) {
|
||||
int64_t den = sps->time_scale;
|
||||
if (p->sei.unregistered.x264_build >= 0)
|
||||
h->x264_build = p->sei.unregistered.x264_build;
|
||||
if (h->x264_build < 44U)
|
||||
if (p->sei.unregistered.x264_build < 44U)
|
||||
den *= 2;
|
||||
av_reduce(&avctx->framerate.den, &avctx->framerate.num,
|
||||
sps->num_units_in_tick * avctx->ticks_per_frame, den, 1 << 30);
|
||||
|
||||
@@ -67,7 +67,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
|
||||
s->t3 = get_bits(&s->gb, 16);
|
||||
s->reset = get_bits(&s->gb, 16);
|
||||
|
||||
if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
|
||||
if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d T2:%d T3:%d reset:%d\n",
|
||||
s->maxval, s->t1, s->t2, s->t3, s->reset);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
|
||||
else
|
||||
maxtab = 65530/wt - 1;
|
||||
|
||||
if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
|
||||
if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab);
|
||||
}
|
||||
if (maxtab >= 256) {
|
||||
@@ -191,7 +191,7 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
|
||||
if (RItype)
|
||||
temp += state->N[Q] >> 1;
|
||||
|
||||
for (k = 0; (state->N[Q] << k) < temp; k++)
|
||||
for (k = 0; ((unsigned)state->N[Q] << k) < temp; k++)
|
||||
;
|
||||
|
||||
#ifdef JLS_BROKEN
|
||||
@@ -200,6 +200,8 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
|
||||
#endif
|
||||
ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1,
|
||||
state->qbpp);
|
||||
if (ret < 0)
|
||||
return -0x10000;
|
||||
|
||||
/* decode mapped error */
|
||||
map = 0;
|
||||
@@ -214,7 +216,7 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
|
||||
ret = ret >> 1;
|
||||
}
|
||||
|
||||
if(FFABS(ret) > 0xFFFF)
|
||||
if (FFABS(ret) > 0xFFFF)
|
||||
return -0x10000;
|
||||
/* update state */
|
||||
state->A[Q] += FFABS(ret) - RItype;
|
||||
|
||||
@@ -230,12 +230,15 @@ static av_cold int libdav1d_init(AVCodecContext *c)
|
||||
s.frame_size_limit = c->max_pixels;
|
||||
if (dav1d->apply_grain >= 0)
|
||||
s.apply_grain = dav1d->apply_grain;
|
||||
else if (c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)
|
||||
s.apply_grain = 0;
|
||||
else
|
||||
s.apply_grain = !(c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
|
||||
|
||||
s.all_layers = dav1d->all_layers;
|
||||
if (dav1d->operating_point >= 0)
|
||||
s.operating_point = dav1d->operating_point;
|
||||
#if FF_DAV1D_VERSION_AT_LEAST(6,2)
|
||||
s.strict_std_compliance = c->strict_std_compliance > 0;
|
||||
#endif
|
||||
|
||||
#if FF_DAV1D_VERSION_AT_LEAST(6,0)
|
||||
if (dav1d->frame_threads || dav1d->tile_threads)
|
||||
@@ -344,8 +347,10 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||
if (res < 0) {
|
||||
if (res == AVERROR(EINVAL))
|
||||
res = AVERROR_INVALIDDATA;
|
||||
if (res != AVERROR(EAGAIN))
|
||||
if (res != AVERROR(EAGAIN)) {
|
||||
dav1d_data_unref(data);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
res = dav1d_get_picture(dav1d->c, p);
|
||||
|
||||
@@ -208,7 +208,9 @@ static int libuavs3d_decode_frame(AVCodecContext *avctx, void *data, int *got_fr
|
||||
}
|
||||
avctx->has_b_frames = !seqh->low_delay;
|
||||
avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE;
|
||||
ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size);
|
||||
ret = ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
h->got_seqhdr = 1;
|
||||
|
||||
if (seqh->colour_description) {
|
||||
|
||||
@@ -57,6 +57,7 @@ static int mjpegb_decode_frame(AVCodecContext *avctx,
|
||||
buf_end = buf + buf_size;
|
||||
s->got_picture = 0;
|
||||
s->adobe_transform = -1;
|
||||
s->buf_size = buf_size;
|
||||
|
||||
read_header:
|
||||
/* reset on every SOI */
|
||||
|
||||
@@ -1614,7 +1614,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
|
||||
for(y=0; y<s->mb_height; y++){
|
||||
int x;
|
||||
int xy= y*s->mb_stride;
|
||||
for(x=0; x<s->mb_width; x++){
|
||||
for(x=0; x<s->mb_width; x++, xy++){
|
||||
if(s->mb_type[xy] & type){
|
||||
int mx= mv_table[xy][0];
|
||||
int my= mv_table[xy][1];
|
||||
@@ -1622,16 +1622,15 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
|
||||
fcode_tab[my + MAX_MV]);
|
||||
int j;
|
||||
|
||||
if(mx >= range || mx < -range ||
|
||||
my >= range || my < -range)
|
||||
continue;
|
||||
if (mx >= range || mx < -range ||
|
||||
my >= range || my < -range)
|
||||
continue;
|
||||
|
||||
for(j=0; j<fcode && j<8; j++){
|
||||
if(s->pict_type==AV_PICTURE_TYPE_B || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy])
|
||||
score[j]-= 170;
|
||||
}
|
||||
}
|
||||
xy++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
|
||||
|
||||
static int styles_equivalent(const StyleBox *a, const StyleBox *b)
|
||||
{
|
||||
#define CMP(field) a->field == b->field
|
||||
#define CMP(field) ((a)->field == (b)->field)
|
||||
return CMP(bold) && CMP(italic) && CMP(underline) && CMP(color) &&
|
||||
CMP(alpha) && CMP(fontsize) && CMP(font_id);
|
||||
#undef CMP
|
||||
|
||||
+1
-1
@@ -1856,7 +1856,7 @@ static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame)
|
||||
NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
|
||||
|
||||
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
|
||||
NV_ENC_REGISTER_RESOURCE reg;
|
||||
NV_ENC_REGISTER_RESOURCE reg = { 0 };
|
||||
int i, idx, ret;
|
||||
|
||||
for (i = 0; i < ctx->nb_registered_frames; i++) {
|
||||
|
||||
+2
-2
@@ -405,7 +405,7 @@ static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale)
|
||||
(int64_t) low [i - 1] * -INT64_C(325392907) +
|
||||
(int64_t) high[i + 0] * INT64_C(1518500249) +
|
||||
(int64_t) high[i - 1] * INT64_C(1518500249);
|
||||
dest[i * 2] = av_clip_int16(((value >> 32) * scale) >> 32);
|
||||
dest[i * 2] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32);
|
||||
}
|
||||
|
||||
for (i = 0; i < hsize; i++) {
|
||||
@@ -416,7 +416,7 @@ static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale)
|
||||
(int64_t) high[i + 1] * INT64_C(303700064) +
|
||||
(int64_t) high[i + 0] * -INT64_C(3644400640) +
|
||||
(int64_t) high[i - 1] * INT64_C(303700064);
|
||||
dest[i * 2 + 1] = av_clip_int16(((value >> 32) * scale) >> 32);
|
||||
dest[i * 2 + 1] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1003,7 +1003,7 @@ static int sonic_decode_frame(AVCodecContext *avctx,
|
||||
|
||||
// dequantize
|
||||
for (i = 0; i < s->num_taps; i++)
|
||||
s->predictor_k[i] *= s->tap_quant[i];
|
||||
s->predictor_k[i] *= (unsigned) s->tap_quant[i];
|
||||
|
||||
if (s->lossless)
|
||||
quant = 1;
|
||||
|
||||
+25
-25
@@ -164,39 +164,39 @@ typedef struct SpeexSubmode {
|
||||
} SpeexSubmode;
|
||||
|
||||
typedef struct SpeexMode {
|
||||
int modeID; /** ID of the mode */
|
||||
int modeID; /**< ID of the mode */
|
||||
int (*decode)(AVCodecContext *avctx, void *dec, GetBitContext *gb, float *out);
|
||||
int frame_size; /**< Size of frames used for decoding */
|
||||
int subframe_size; /**< Size of sub-frames used for decoding */
|
||||
int lpc_size; /**< Order of LPC filter */
|
||||
float folding_gain; /**< Folding gain */
|
||||
int frame_size; /**< Size of frames used for decoding */
|
||||
int subframe_size; /**< Size of sub-frames used for decoding */
|
||||
int lpc_size; /**< Order of LPC filter */
|
||||
float folding_gain; /**< Folding gain */
|
||||
const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
int default_submode; /**< Default sub-mode to use when decoding */
|
||||
int default_submode; /**< Default sub-mode to use when decoding */
|
||||
} SpeexMode;
|
||||
|
||||
typedef struct DecoderState {
|
||||
const SpeexMode *mode;
|
||||
int modeID; /** ID of the decoder mode */
|
||||
int first; /** Is first frame */
|
||||
int full_frame_size; /**< Length of full-band frames */
|
||||
int is_wideband; /**< If wideband is present */
|
||||
int count_lost; /**< Was the last frame lost? */
|
||||
int frame_size; /**< Length of high-band frames */
|
||||
int subframe_size; /**< Length of high-band sub-frames */
|
||||
int nb_subframes; /**< Number of high-band sub-frames */
|
||||
int lpc_size; /**< Order of high-band LPC analysis */
|
||||
float last_ol_gain; /**< Open-loop gain for previous frame */
|
||||
float *innov_save; /** If non-NULL, innovation is copied here */
|
||||
int modeID; /**< ID of the decoder mode */
|
||||
int first; /**< Is first frame */
|
||||
int full_frame_size; /**< Length of full-band frames */
|
||||
int is_wideband; /**< If wideband is present */
|
||||
int count_lost; /**< Was the last frame lost? */
|
||||
int frame_size; /**< Length of high-band frames */
|
||||
int subframe_size; /**< Length of high-band sub-frames */
|
||||
int nb_subframes; /**< Number of high-band sub-frames */
|
||||
int lpc_size; /**< Order of high-band LPC analysis */
|
||||
float last_ol_gain; /**< Open-loop gain for previous frame */
|
||||
float *innov_save; /**< If non-NULL, innovation is copied here */
|
||||
|
||||
/* This is used in packet loss concealment */
|
||||
int last_pitch; /**< Pitch of last correctly decoded frame */
|
||||
float last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
|
||||
uint32_t seed; /** Seed used for random number generation */
|
||||
int last_pitch; /**< Pitch of last correctly decoded frame */
|
||||
float last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
|
||||
uint32_t seed; /**< Seed used for random number generation */
|
||||
|
||||
int encode_submode;
|
||||
const SpeexSubmode *const *submodes; /**< Sub-mode data */
|
||||
int submodeID; /**< Activated sub-mode */
|
||||
int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */
|
||||
int submodeID; /**< Activated sub-mode */
|
||||
int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */
|
||||
|
||||
/* Vocoder data */
|
||||
float voc_m1;
|
||||
@@ -205,10 +205,10 @@ typedef struct DecoderState {
|
||||
int voc_offset;
|
||||
|
||||
int dtx_enabled;
|
||||
int highpass_enabled; /**< Is the input filter enabled */
|
||||
int highpass_enabled; /**< Is the input filter enabled */
|
||||
|
||||
float *exc; /**< Start of excitation frame */
|
||||
float mem_hp[2]; /**< High-pass filter memory */
|
||||
float *exc; /**< Start of excitation frame */
|
||||
float mem_hp[2]; /**< High-pass filter memory */
|
||||
float exc_buf[NB_DEC_BUFFER]; /**< Excitation buffer */
|
||||
float old_qlsp[NB_ORDER]; /**< Quantized LSPs for previous frame */
|
||||
float interp_qlpc[NB_ORDER]; /**< Interpolated quantized LPCs */
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ static void decorrelate_sf(int32_t *p1, int32_t *p2, int length, int dshift, int
|
||||
for (i = 0; i < length; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
b = (unsigned)(dfactor * (b >> dshift) + 128 >> 8) << dshift;
|
||||
b = (unsigned)((int)(dfactor * (unsigned)(b >> dshift) + 128) >> 8) << dshift;
|
||||
p1[i] = b - a;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-25
@@ -153,6 +153,21 @@ static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_upd
|
||||
}
|
||||
}
|
||||
|
||||
static int v4l2_start_decode(V4L2Context *ctx)
|
||||
{
|
||||
struct v4l2_decoder_cmd cmd = {
|
||||
.cmd = V4L2_DEC_CMD_START,
|
||||
.flags = 0,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
|
||||
if (ret)
|
||||
return AVERROR(errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle resolution change event and end of stream event
|
||||
* returns 1 if reinit was successful, negative if it failed
|
||||
@@ -162,9 +177,8 @@ static int v4l2_handle_event(V4L2Context *ctx)
|
||||
{
|
||||
V4L2m2mContext *s = ctx_to_m2mctx(ctx);
|
||||
struct v4l2_format cap_fmt = s->capture.format;
|
||||
struct v4l2_format out_fmt = s->output.format;
|
||||
struct v4l2_event evt = { 0 };
|
||||
int full_reinit, reinit, ret;
|
||||
int reinit, ret;
|
||||
|
||||
ret = ioctl(s->fd, VIDIOC_DQEVENT, &evt);
|
||||
if (ret < 0) {
|
||||
@@ -180,44 +194,25 @@ static int v4l2_handle_event(V4L2Context *ctx)
|
||||
if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
|
||||
return 0;
|
||||
|
||||
ret = ioctl(s->fd, VIDIOC_G_FMT, &out_fmt);
|
||||
if (ret) {
|
||||
av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->output.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ioctl(s->fd, VIDIOC_G_FMT, &cap_fmt);
|
||||
if (ret) {
|
||||
av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->capture.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
full_reinit = v4l2_resolution_changed(&s->output, &out_fmt);
|
||||
if (full_reinit) {
|
||||
s->output.height = v4l2_get_height(&out_fmt);
|
||||
s->output.width = v4l2_get_width(&out_fmt);
|
||||
s->output.sample_aspect_ratio = v4l2_get_sar(&s->output);
|
||||
}
|
||||
|
||||
reinit = v4l2_resolution_changed(&s->capture, &cap_fmt);
|
||||
if (reinit) {
|
||||
s->capture.height = v4l2_get_height(&cap_fmt);
|
||||
s->capture.width = v4l2_get_width(&cap_fmt);
|
||||
s->capture.sample_aspect_ratio = v4l2_get_sar(&s->capture);
|
||||
} else {
|
||||
v4l2_start_decode(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (full_reinit || reinit)
|
||||
if (reinit)
|
||||
s->reinit = 1;
|
||||
|
||||
if (full_reinit) {
|
||||
ret = ff_v4l2_m2m_codec_full_reinit(s);
|
||||
if (ret) {
|
||||
av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_full_reinit\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
goto reinit_run;
|
||||
}
|
||||
|
||||
if (reinit) {
|
||||
if (s->avctx)
|
||||
ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height);
|
||||
|
||||
@@ -825,11 +825,13 @@ static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec
|
||||
if (data)
|
||||
CFDictionarySetValue(avc_info, CFSTR("hvcC"), data);
|
||||
break;
|
||||
#if CONFIG_VP9_VIDEOTOOLBOX_HWACCEL
|
||||
case kCMVideoCodecType_VP9 :
|
||||
data = ff_videotoolbox_vpcc_extradata_create(avctx);
|
||||
if (data)
|
||||
CFDictionarySetValue(avc_info, CFSTR("vpcC"), data);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -292,6 +292,11 @@ static int vp9_raw_reorder_filter(AVBSFContext *bsf, AVPacket *out)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!in->size) {
|
||||
av_packet_free(&in);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if ((in->data[in->size - 1] & 0xe0) == 0xc0) {
|
||||
av_log(bsf, AV_LOG_ERROR, "Input in superframes is not "
|
||||
"supported.\n");
|
||||
|
||||
@@ -108,6 +108,15 @@ static int vp9_superframe_filter(AVBSFContext *ctx, AVPacket *pkt)
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
if (!pkt->size) {
|
||||
/* In case the cache is empty we can pass side-data-only packets
|
||||
* through unchanged. Otherwise, such a packet makes no sense. */
|
||||
if (!s->n_cache)
|
||||
return 0;
|
||||
res = AVERROR_INVALIDDATA;
|
||||
goto done;
|
||||
}
|
||||
|
||||
marker = pkt->data[pkt->size - 1];
|
||||
if ((marker & 0xe0) == 0xc0) {
|
||||
int nbytes = 1 + ((marker >> 3) & 0x3);
|
||||
|
||||
@@ -51,6 +51,9 @@ static int vp9_superframe_split_filter(AVBSFContext *ctx, AVPacket *out)
|
||||
return ret;
|
||||
in = s->buffer_pkt;
|
||||
|
||||
if (!in->size)
|
||||
goto passthrough;
|
||||
|
||||
marker = in->data[in->size - 1];
|
||||
if ((marker & 0xe0) == 0xc0) {
|
||||
int length_size = 1 + ((marker >> 3) & 0x3);
|
||||
@@ -70,7 +73,7 @@ static int vp9_superframe_split_filter(AVBSFContext *ctx, AVPacket *out)
|
||||
frame_size |= bytestream2_get_byte(&bc) << (j * 8);
|
||||
|
||||
total_size += frame_size;
|
||||
if (frame_size < 0 || total_size > in->size - idx_size) {
|
||||
if (frame_size <= 0 || total_size > in->size - idx_size) {
|
||||
av_log(ctx, AV_LOG_ERROR,
|
||||
"Invalid frame size in a superframe: %d\n", frame_size);
|
||||
ret = AVERROR(EINVAL);
|
||||
@@ -121,6 +124,7 @@ static int vp9_superframe_split_filter(AVBSFContext *ctx, AVPacket *out)
|
||||
out->pts = AV_NOPTS_VALUE;
|
||||
|
||||
} else {
|
||||
passthrough:
|
||||
av_packet_move_ref(out, s->buffer_pkt);
|
||||
}
|
||||
|
||||
|
||||
+6
-17
@@ -1002,23 +1002,12 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (requested_sample_rate) {
|
||||
if (requested_sample_rate > acaps->MaximumSampleFrequency ||
|
||||
requested_sample_rate < acaps->MinimumSampleFrequency)
|
||||
goto next;
|
||||
fx->nSamplesPerSec = requested_sample_rate;
|
||||
}
|
||||
if (requested_sample_size) {
|
||||
if (requested_sample_size > acaps->MaximumBitsPerSample ||
|
||||
requested_sample_size < acaps->MinimumBitsPerSample)
|
||||
goto next;
|
||||
fx->wBitsPerSample = requested_sample_size;
|
||||
}
|
||||
if (requested_channels) {
|
||||
if (requested_channels > acaps->MaximumChannels ||
|
||||
requested_channels < acaps->MinimumChannels)
|
||||
goto next;
|
||||
fx->nChannels = requested_channels;
|
||||
if (
|
||||
(ctx->sample_rate && ctx->sample_rate != fx->nSamplesPerSec) ||
|
||||
(ctx->sample_size && ctx->sample_size != fx->wBitsPerSample) ||
|
||||
(ctx->channels && ctx->channels != fx->nChannels )
|
||||
) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -220,6 +220,7 @@ static int iec61883_parse_queue_dv(struct iec61883_data *dv, AVPacket *pkt)
|
||||
|
||||
static int iec61883_parse_queue_hdv(struct iec61883_data *dv, AVPacket *pkt)
|
||||
{
|
||||
#if CONFIG_MPEGTS_DEMUXER
|
||||
DVPacket *packet;
|
||||
int size;
|
||||
|
||||
@@ -235,7 +236,7 @@ static int iec61883_parse_queue_hdv(struct iec61883_data *dv, AVPacket *pkt)
|
||||
if (size > 0)
|
||||
return size;
|
||||
}
|
||||
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
+103
-108
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avutil.h"
|
||||
#include "libavutil/colorspace.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
@@ -32,50 +33,46 @@ enum { RED = 0, GREEN, BLUE, ALPHA };
|
||||
|
||||
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
|
||||
{
|
||||
switch (pix_fmt) {
|
||||
case AV_PIX_FMT_0RGB:
|
||||
case AV_PIX_FMT_ARGB: rgba_map[ALPHA] = 0; rgba_map[RED ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
|
||||
case AV_PIX_FMT_0BGR:
|
||||
case AV_PIX_FMT_ABGR: rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED ] = 3; break;
|
||||
case AV_PIX_FMT_RGB48LE:
|
||||
case AV_PIX_FMT_RGB48BE:
|
||||
case AV_PIX_FMT_RGBA64BE:
|
||||
case AV_PIX_FMT_RGBA64LE:
|
||||
case AV_PIX_FMT_RGB0:
|
||||
case AV_PIX_FMT_RGBA:
|
||||
case AV_PIX_FMT_RGB24: rgba_map[RED ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
|
||||
case AV_PIX_FMT_BGR48LE:
|
||||
case AV_PIX_FMT_BGR48BE:
|
||||
case AV_PIX_FMT_BGRA64BE:
|
||||
case AV_PIX_FMT_BGRA64LE:
|
||||
case AV_PIX_FMT_BGRA:
|
||||
case AV_PIX_FMT_BGR0:
|
||||
case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break;
|
||||
case AV_PIX_FMT_GBRP9LE:
|
||||
case AV_PIX_FMT_GBRP9BE:
|
||||
case AV_PIX_FMT_GBRP10LE:
|
||||
case AV_PIX_FMT_GBRP10BE:
|
||||
case AV_PIX_FMT_GBRP12LE:
|
||||
case AV_PIX_FMT_GBRP12BE:
|
||||
case AV_PIX_FMT_GBRP14LE:
|
||||
case AV_PIX_FMT_GBRP14BE:
|
||||
case AV_PIX_FMT_GBRP16LE:
|
||||
case AV_PIX_FMT_GBRP16BE:
|
||||
case AV_PIX_FMT_GBRAP:
|
||||
case AV_PIX_FMT_GBRAP10LE:
|
||||
case AV_PIX_FMT_GBRAP10BE:
|
||||
case AV_PIX_FMT_GBRAP12LE:
|
||||
case AV_PIX_FMT_GBRAP12BE:
|
||||
case AV_PIX_FMT_GBRAP16LE:
|
||||
case AV_PIX_FMT_GBRAP16BE:
|
||||
case AV_PIX_FMT_GBRPF32LE:
|
||||
case AV_PIX_FMT_GBRPF32BE:
|
||||
case AV_PIX_FMT_GBRAPF32LE:
|
||||
case AV_PIX_FMT_GBRAPF32BE:
|
||||
case AV_PIX_FMT_GBRP: rgba_map[GREEN] = 0; rgba_map[BLUE ] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break;
|
||||
default: /* unsupported */
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
|
||||
if (!(desc->flags & AV_PIX_FMT_FLAG_RGB))
|
||||
return AVERROR(EINVAL);
|
||||
if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
|
||||
return AVERROR(EINVAL);
|
||||
av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA));
|
||||
if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
|
||||
rgba_map[RED] = desc->comp[0].plane;
|
||||
rgba_map[GREEN] = desc->comp[1].plane;
|
||||
rgba_map[BLUE] = desc->comp[2].plane;
|
||||
rgba_map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3;
|
||||
} else {
|
||||
int had0 = 0;
|
||||
unsigned depthb = 0;
|
||||
unsigned i;
|
||||
for (i = 0; i < desc->nb_components; i++) {
|
||||
/* all components must have same depth in bytes */
|
||||
unsigned db = (desc->comp[i].depth + 7) / 8;
|
||||
unsigned pos = desc->comp[i].offset / db;
|
||||
if (depthb && (depthb != db))
|
||||
return AVERROR(ENOSYS);
|
||||
|
||||
if (desc->comp[i].offset % db)
|
||||
return AVERROR(ENOSYS);
|
||||
|
||||
had0 |= pos == 0;
|
||||
rgba_map[i] = pos;
|
||||
}
|
||||
|
||||
if (desc->nb_components == 3)
|
||||
rgba_map[ALPHA] = had0 ? 3 : 0;
|
||||
}
|
||||
|
||||
av_assert0(rgba_map[RED] != rgba_map[GREEN]);
|
||||
av_assert0(rgba_map[GREEN] != rgba_map[BLUE]);
|
||||
av_assert0(rgba_map[BLUE] != rgba_map[RED]);
|
||||
av_assert0(rgba_map[RED] != rgba_map[ALPHA]);
|
||||
av_assert0(rgba_map[GREEN] != rgba_map[ALPHA]);
|
||||
av_assert0(rgba_map[BLUE] != rgba_map[ALPHA]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -86,25 +83,37 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
|
||||
unsigned i, nb_planes = 0;
|
||||
int pixelstep[MAX_PLANES] = { 0 };
|
||||
int full_range = 0;
|
||||
int depthb = 0;
|
||||
|
||||
if (!desc || !desc->name)
|
||||
return AVERROR(EINVAL);
|
||||
if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA))
|
||||
if (desc->flags & AV_PIX_FMT_FLAG_BE)
|
||||
return AVERROR(ENOSYS);
|
||||
if (format == AV_PIX_FMT_P010LE || format == AV_PIX_FMT_P010BE || format == AV_PIX_FMT_P016LE || format == AV_PIX_FMT_P016BE)
|
||||
if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA))
|
||||
return AVERROR(ENOSYS);
|
||||
if (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || format == AV_PIX_FMT_YUVJ444P ||
|
||||
format == AV_PIX_FMT_YUVJ411P || format == AV_PIX_FMT_YUVJ440P)
|
||||
full_range = 1;
|
||||
for (i = 0; i < desc->nb_components; i++) {
|
||||
int db;
|
||||
c = &desc->comp[i];
|
||||
/* for now, only 8-16 bits formats */
|
||||
if (c->depth < 8 || c->depth > 16)
|
||||
return AVERROR(ENOSYS);
|
||||
if (desc->flags & AV_PIX_FMT_FLAG_BE)
|
||||
return AVERROR(ENOSYS);
|
||||
if (c->plane >= MAX_PLANES)
|
||||
return AVERROR(ENOSYS);
|
||||
/* data must either be in the high or low bits, never middle */
|
||||
if (c->shift && ((c->shift + c->depth) & 0x7))
|
||||
return AVERROR(ENOSYS);
|
||||
/* mixed >8 and <=8 depth */
|
||||
db = (c->depth + 7) / 8;
|
||||
if (depthb && (depthb != db))
|
||||
return AVERROR(ENOSYS);
|
||||
depthb = db;
|
||||
if (db * (c->offset + 1) > 16)
|
||||
return AVERROR(ENOSYS);
|
||||
if (c->offset % db)
|
||||
return AVERROR(ENOSYS);
|
||||
/* strange interleaving */
|
||||
if (pixelstep[c->plane] != 0 &&
|
||||
pixelstep[c->plane] != c->step)
|
||||
@@ -126,66 +135,49 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
|
||||
memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
|
||||
draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
|
||||
draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
|
||||
for (i = 0; i < (desc->nb_components - !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(flags & FF_DRAW_PROCESS_ALPHA))); i++)
|
||||
draw->comp_mask[desc->comp[i].plane] |=
|
||||
1 << desc->comp[i].offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
|
||||
{
|
||||
unsigned i;
|
||||
uint8_t rgba_map[4];
|
||||
uint8_t tmp8[4];
|
||||
const AVPixFmtDescriptor *desc = draw->desc;
|
||||
|
||||
if (rgba != color->rgba)
|
||||
memcpy(color->rgba, rgba, sizeof(color->rgba));
|
||||
if ((draw->desc->flags & AV_PIX_FMT_FLAG_RGB) &&
|
||||
ff_fill_rgba_map(rgba_map, draw->format) >= 0) {
|
||||
if (draw->nb_planes == 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
color->comp[0].u8[rgba_map[i]] = rgba[i];
|
||||
if (draw->desc->comp[rgba_map[i]].depth > 8) {
|
||||
color->comp[0].u16[rgba_map[i]] = color->comp[0].u8[rgba_map[i]] << 8;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
color->comp[rgba_map[i]].u8[0] = rgba[i];
|
||||
if (draw->desc->comp[rgba_map[i]].depth > 8)
|
||||
color->comp[rgba_map[i]].u16[0] = color->comp[rgba_map[i]].u8[0] << (draw->desc->comp[rgba_map[i]].depth - 8);
|
||||
}
|
||||
}
|
||||
|
||||
memset(color->comp, 0, sizeof(color->comp));
|
||||
|
||||
if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB) {
|
||||
memcpy(tmp8, rgba, sizeof(tmp8));
|
||||
} else if (draw->nb_planes >= 2) {
|
||||
/* assume YUV */
|
||||
const AVPixFmtDescriptor *desc = draw->desc;
|
||||
color->comp[desc->comp[0].plane].u8[desc->comp[0].offset] = draw->full_range ? RGB_TO_Y_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
|
||||
color->comp[desc->comp[1].plane].u8[desc->comp[1].offset] = draw->full_range ? RGB_TO_U_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
|
||||
color->comp[desc->comp[2].plane].u8[desc->comp[2].offset] = draw->full_range ? RGB_TO_V_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
|
||||
color->comp[3].u8[0] = rgba[3];
|
||||
#define EXPAND(compn) \
|
||||
if (desc->comp[compn].depth > 8) \
|
||||
color->comp[desc->comp[compn].plane].u16[desc->comp[compn].offset] = \
|
||||
color->comp[desc->comp[compn].plane].u8[desc->comp[compn].offset] << \
|
||||
(draw->desc->comp[compn].depth + draw->desc->comp[compn].shift - 8)
|
||||
EXPAND(3);
|
||||
EXPAND(2);
|
||||
EXPAND(1);
|
||||
EXPAND(0);
|
||||
tmp8[0] = draw->full_range ? RGB_TO_Y_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
|
||||
tmp8[1] = draw->full_range ? RGB_TO_U_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
|
||||
tmp8[2] = draw->full_range ? RGB_TO_V_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
|
||||
tmp8[3] = rgba[3];
|
||||
} else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A ||
|
||||
draw->format == AV_PIX_FMT_GRAY16LE || draw->format == AV_PIX_FMT_YA16LE ||
|
||||
draw->format == AV_PIX_FMT_GRAY9LE ||
|
||||
draw->format == AV_PIX_FMT_GRAY10LE ||
|
||||
draw->format == AV_PIX_FMT_GRAY12LE ||
|
||||
draw->format == AV_PIX_FMT_GRAY14LE) {
|
||||
const AVPixFmtDescriptor *desc = draw->desc;
|
||||
color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
|
||||
EXPAND(0);
|
||||
color->comp[1].u8[0] = rgba[3];
|
||||
EXPAND(1);
|
||||
tmp8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
|
||||
tmp8[1] = rgba[3];
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"Color conversion not implemented for %s\n", draw->desc->name);
|
||||
memset(color, 128, sizeof(*color));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->nb_components; i++) {
|
||||
if (desc->comp[i].depth > 8)
|
||||
color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = tmp8[i] <<
|
||||
(draw->desc->comp[i].depth + draw->desc->comp[i].shift - 8);
|
||||
else
|
||||
color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = tmp8[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,11 +283,6 @@ static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
|
||||
*w >>= sub;
|
||||
}
|
||||
|
||||
static int component_used(FFDrawContext *draw, int plane, int comp)
|
||||
{
|
||||
return (draw->comp_mask[plane] >> comp) & 1;
|
||||
}
|
||||
|
||||
/* If alpha is in the [ 0 ; 0x1010101 ] range,
|
||||
then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range,
|
||||
and >> 24 gives a correct rounding. */
|
||||
@@ -355,6 +342,9 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
|
||||
int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
|
||||
uint8_t *p0, *p;
|
||||
|
||||
nb_comp = draw->desc->nb_components -
|
||||
!!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
|
||||
|
||||
/* TODO optimize if alpha = 0xFF */
|
||||
clip_interval(dst_w, &x0, &w, NULL);
|
||||
clip_interval(dst_h, &y0, &h, NULL);
|
||||
@@ -370,7 +360,6 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
|
||||
nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
|
||||
nb_planes += !nb_planes;
|
||||
for (plane = 0; plane < nb_planes; plane++) {
|
||||
nb_comp = draw->pixelstep[plane];
|
||||
p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
|
||||
w_sub = w;
|
||||
h_sub = h;
|
||||
@@ -380,17 +369,19 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
|
||||
subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
|
||||
for (comp = 0; comp < nb_comp; comp++) {
|
||||
const int depth = draw->desc->comp[comp].depth;
|
||||
const int offset = draw->desc->comp[comp].offset;
|
||||
const int index = offset / ((depth + 7) / 8);
|
||||
|
||||
if (!component_used(draw, plane, comp))
|
||||
if (draw->desc->comp[comp].plane != plane)
|
||||
continue;
|
||||
p = p0 + comp;
|
||||
p = p0 + offset;
|
||||
if (top) {
|
||||
if (depth <= 8) {
|
||||
blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
|
||||
blend_line(p, color->comp[plane].u8[index], alpha >> 1,
|
||||
draw->pixelstep[plane], w_sub,
|
||||
draw->hsub[plane], left, right);
|
||||
} else {
|
||||
blend_line16(p, color->comp[plane].u16[comp], alpha >> 1,
|
||||
blend_line16(p, color->comp[plane].u16[index], alpha >> 1,
|
||||
draw->pixelstep[plane], w_sub,
|
||||
draw->hsub[plane], left, right);
|
||||
}
|
||||
@@ -398,14 +389,14 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
|
||||
}
|
||||
if (depth <= 8) {
|
||||
for (y = 0; y < h_sub; y++) {
|
||||
blend_line(p, color->comp[plane].u8[comp], alpha,
|
||||
blend_line(p, color->comp[plane].u8[index], alpha,
|
||||
draw->pixelstep[plane], w_sub,
|
||||
draw->hsub[plane], left, right);
|
||||
p += dst_linesize[plane];
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y < h_sub; y++) {
|
||||
blend_line16(p, color->comp[plane].u16[comp], alpha,
|
||||
blend_line16(p, color->comp[plane].u16[index], alpha,
|
||||
draw->pixelstep[plane], w_sub,
|
||||
draw->hsub[plane], left, right);
|
||||
p += dst_linesize[plane];
|
||||
@@ -413,11 +404,11 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
|
||||
}
|
||||
if (bottom) {
|
||||
if (depth <= 8) {
|
||||
blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
|
||||
blend_line(p, color->comp[plane].u8[index], alpha >> 1,
|
||||
draw->pixelstep[plane], w_sub,
|
||||
draw->hsub[plane], left, right);
|
||||
} else {
|
||||
blend_line16(p, color->comp[plane].u16[comp], alpha >> 1,
|
||||
blend_line16(p, color->comp[plane].u16[index], alpha >> 1,
|
||||
draw->pixelstep[plane], w_sub,
|
||||
draw->hsub[plane], left, right);
|
||||
}
|
||||
@@ -533,6 +524,9 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
||||
uint8_t *p0, *p;
|
||||
const uint8_t *m;
|
||||
|
||||
nb_comp = draw->desc->nb_components -
|
||||
!!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
|
||||
|
||||
clip_interval(dst_w, &x0, &mask_w, &xm0);
|
||||
clip_interval(dst_h, &y0, &mask_h, &ym0);
|
||||
mask += ym0 * mask_linesize;
|
||||
@@ -548,7 +542,6 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
||||
nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
|
||||
nb_planes += !nb_planes;
|
||||
for (plane = 0; plane < nb_planes; plane++) {
|
||||
nb_comp = draw->pixelstep[plane];
|
||||
p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
|
||||
w_sub = mask_w;
|
||||
h_sub = mask_h;
|
||||
@@ -558,21 +551,23 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
||||
subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
|
||||
for (comp = 0; comp < nb_comp; comp++) {
|
||||
const int depth = draw->desc->comp[comp].depth;
|
||||
const int offset = draw->desc->comp[comp].offset;
|
||||
const int index = offset / ((depth + 7) / 8);
|
||||
|
||||
if (!component_used(draw, plane, comp))
|
||||
if (draw->desc->comp[comp].plane != plane)
|
||||
continue;
|
||||
p = p0 + comp;
|
||||
p = p0 + offset;
|
||||
m = mask;
|
||||
if (top) {
|
||||
if (depth <= 8) {
|
||||
blend_line_hv(p, draw->pixelstep[plane],
|
||||
color->comp[plane].u8[comp], alpha,
|
||||
color->comp[plane].u8[index], alpha,
|
||||
m, mask_linesize, l2depth, w_sub,
|
||||
draw->hsub[plane], draw->vsub[plane],
|
||||
xm0, left, right, top);
|
||||
} else {
|
||||
blend_line_hv16(p, draw->pixelstep[plane],
|
||||
color->comp[plane].u16[comp], alpha,
|
||||
color->comp[plane].u16[index], alpha,
|
||||
m, mask_linesize, l2depth, w_sub,
|
||||
draw->hsub[plane], draw->vsub[plane],
|
||||
xm0, left, right, top);
|
||||
@@ -583,7 +578,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
||||
if (depth <= 8) {
|
||||
for (y = 0; y < h_sub; y++) {
|
||||
blend_line_hv(p, draw->pixelstep[plane],
|
||||
color->comp[plane].u8[comp], alpha,
|
||||
color->comp[plane].u8[index], alpha,
|
||||
m, mask_linesize, l2depth, w_sub,
|
||||
draw->hsub[plane], draw->vsub[plane],
|
||||
xm0, left, right, 1 << draw->vsub[plane]);
|
||||
@@ -593,7 +588,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
||||
} else {
|
||||
for (y = 0; y < h_sub; y++) {
|
||||
blend_line_hv16(p, draw->pixelstep[plane],
|
||||
color->comp[plane].u16[comp], alpha,
|
||||
color->comp[plane].u16[index], alpha,
|
||||
m, mask_linesize, l2depth, w_sub,
|
||||
draw->hsub[plane], draw->vsub[plane],
|
||||
xm0, left, right, 1 << draw->vsub[plane]);
|
||||
@@ -604,13 +599,13 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
||||
if (bottom) {
|
||||
if (depth <= 8) {
|
||||
blend_line_hv(p, draw->pixelstep[plane],
|
||||
color->comp[plane].u8[comp], alpha,
|
||||
color->comp[plane].u8[index], alpha,
|
||||
m, mask_linesize, l2depth, w_sub,
|
||||
draw->hsub[plane], draw->vsub[plane],
|
||||
xm0, left, right, bottom);
|
||||
} else {
|
||||
blend_line_hv16(p, draw->pixelstep[plane],
|
||||
color->comp[plane].u16[comp], alpha,
|
||||
color->comp[plane].u16[index], alpha,
|
||||
m, mask_linesize, l2depth, w_sub,
|
||||
draw->hsub[plane], draw->vsub[plane],
|
||||
xm0, left, right, bottom);
|
||||
|
||||
@@ -37,7 +37,6 @@ typedef struct FFDrawContext {
|
||||
enum AVPixelFormat format;
|
||||
unsigned nb_planes;
|
||||
int pixelstep[MAX_PLANES]; /*< offset between pixels */
|
||||
uint8_t comp_mask[MAX_PLANES]; /*< bitmask of used non-alpha components */
|
||||
uint8_t hsub[MAX_PLANES]; /*< horizontal subsampling */
|
||||
uint8_t vsub[MAX_PLANES]; /*< vertical subsampling */
|
||||
uint8_t hsub_max;
|
||||
|
||||
@@ -279,7 +279,11 @@ static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf,
|
||||
dst_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h);
|
||||
if (!dst_buf)
|
||||
return top_buf;
|
||||
av_frame_copy_props(dst_buf, top_buf);
|
||||
|
||||
if (av_frame_copy_props(dst_buf, top_buf) < 0) {
|
||||
av_frame_free(&dst_buf);
|
||||
return top_buf;
|
||||
}
|
||||
|
||||
for (plane = 0; plane < s->nb_planes; plane++) {
|
||||
int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef struct LibplaceboContext {
|
||||
int force_divisible_by;
|
||||
int normalize_sar;
|
||||
int apply_filmgrain;
|
||||
int apply_dovi;
|
||||
int colorspace;
|
||||
int color_range;
|
||||
int color_primaries;
|
||||
@@ -281,8 +282,16 @@ static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in)
|
||||
LibplaceboContext *s = avctx->priv;
|
||||
struct pl_render_params params;
|
||||
struct pl_frame image, target;
|
||||
ok = pl_map_avframe(s->gpu, &image, NULL, in);
|
||||
ok &= pl_map_avframe(s->gpu, &target, NULL, out);
|
||||
ok = pl_map_avframe_ex(s->gpu, &image, pl_avframe_params(
|
||||
.frame = in,
|
||||
.map_dovi = s->apply_dovi,
|
||||
));
|
||||
|
||||
ok &= pl_map_avframe_ex(s->gpu, &target, pl_avframe_params(
|
||||
.frame = out,
|
||||
.map_dovi = false,
|
||||
));
|
||||
|
||||
if (!ok) {
|
||||
err = AVERROR_EXTERNAL;
|
||||
goto fail;
|
||||
@@ -381,7 +390,7 @@ fail:
|
||||
|
||||
static int filter_frame(AVFilterLink *link, AVFrame *in)
|
||||
{
|
||||
int err;
|
||||
int err, changed_csp;
|
||||
AVFilterContext *ctx = link->dst;
|
||||
LibplaceboContext *s = ctx->priv;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
@@ -400,6 +409,14 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
|
||||
out->width = outlink->w;
|
||||
out->height = outlink->h;
|
||||
|
||||
if (s->apply_dovi && av_frame_get_side_data(in, AV_FRAME_DATA_DOVI_METADATA)) {
|
||||
/* Output of dovi reshaping is always BT.2020+PQ, so infer the correct
|
||||
* output colorspace defaults */
|
||||
out->colorspace = AVCOL_SPC_BT2020_NCL;
|
||||
out->color_primaries = AVCOL_PRI_BT2020;
|
||||
out->color_trc = AVCOL_TRC_SMPTE2084;
|
||||
}
|
||||
|
||||
if (s->colorspace >= 0)
|
||||
out->colorspace = s->colorspace;
|
||||
if (s->color_range >= 0)
|
||||
@@ -409,11 +426,25 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
|
||||
if (s->color_primaries >= 0)
|
||||
out->color_primaries = s->color_primaries;
|
||||
|
||||
RET(process_frames(ctx, out, in));
|
||||
changed_csp = in->colorspace != out->colorspace ||
|
||||
in->color_range != out->color_range ||
|
||||
in->color_trc != out->color_trc ||
|
||||
in->color_primaries != out->color_primaries;
|
||||
|
||||
/* Strip side data if no longer relevant */
|
||||
if (changed_csp) {
|
||||
av_frame_remove_side_data(out, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||
av_frame_remove_side_data(out, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
||||
}
|
||||
if (s->apply_dovi || changed_csp) {
|
||||
av_frame_remove_side_data(out, AV_FRAME_DATA_DOVI_RPU_BUFFER);
|
||||
av_frame_remove_side_data(out, AV_FRAME_DATA_DOVI_METADATA);
|
||||
}
|
||||
if (s->apply_filmgrain)
|
||||
av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
|
||||
|
||||
RET(process_frames(ctx, out, in));
|
||||
|
||||
av_frame_free(&in);
|
||||
|
||||
return ff_filter_frame(outlink, out);
|
||||
@@ -559,6 +590,7 @@ static const AVOption libplacebo_options[] = {
|
||||
{ "antiringing", "Antiringing strength (for non-EWA filters)", OFFSET(antiringing), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, DYNAMIC },
|
||||
{ "sigmoid", "Enable sigmoid upscaling", OFFSET(sigmoid), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
|
||||
{ "apply_filmgrain", "Apply film grain metadata", OFFSET(apply_filmgrain), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
|
||||
{ "apply_dolbyvision", "Apply Dolby Vision metadata", OFFSET(apply_dovi), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
|
||||
|
||||
{ "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
|
||||
{ "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC },
|
||||
|
||||
@@ -499,7 +499,7 @@ static void dump_dovi_metadata(AVFilterContext *ctx, const AVFrameSideData *sd)
|
||||
av_log(ctx, AV_LOG_INFO, "} ");
|
||||
}
|
||||
|
||||
av_log(ctx, AV_LOG_INFO, "}; nlq_offset=%"PRIu64"; ", nlq->nlq_offset);
|
||||
av_log(ctx, AV_LOG_INFO, "}; nlq_offset=%"PRIu16"; ", nlq->nlq_offset);
|
||||
av_log(ctx, AV_LOG_INFO, "vdr_in_max=%"PRIu64"; ", nlq->vdr_in_max);
|
||||
switch (mapping->nlq_method_idc) {
|
||||
case AV_DOVI_NLQ_LINEAR_DZ:
|
||||
|
||||
@@ -146,9 +146,13 @@ static int config_input(AVFilterLink *inlink)
|
||||
ff_draw_init(&ass->draw, inlink->format, ass->alpha ? FF_DRAW_PROCESS_ALPHA : 0);
|
||||
|
||||
ass_set_frame_size (ass->renderer, inlink->w, inlink->h);
|
||||
if (ass->original_w && ass->original_h)
|
||||
if (ass->original_w && ass->original_h) {
|
||||
ass_set_pixel_aspect(ass->renderer, (double)inlink->w / inlink->h /
|
||||
((double)ass->original_w / ass->original_h));
|
||||
ass_set_storage_size(ass->renderer, ass->original_w, ass->original_h);
|
||||
} else
|
||||
ass_set_storage_size(ass->renderer, inlink->w, inlink->h);
|
||||
|
||||
if (ass->shaping != -1)
|
||||
ass_set_shaper(ass->renderer, ass->shaping);
|
||||
|
||||
|
||||
@@ -119,18 +119,19 @@ static float mobius(float in, float j, double peak)
|
||||
static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in,
|
||||
const AVPixFmtDescriptor *desc, int x, int y, double peak)
|
||||
{
|
||||
const float *r_in = (const float *)(in->data[0] + x * desc->comp[0].step + y * in->linesize[0]);
|
||||
const float *b_in = (const float *)(in->data[1] + x * desc->comp[1].step + y * in->linesize[1]);
|
||||
const float *g_in = (const float *)(in->data[2] + x * desc->comp[2].step + y * in->linesize[2]);
|
||||
float *r_out = (float *)(out->data[0] + x * desc->comp[0].step + y * out->linesize[0]);
|
||||
float *b_out = (float *)(out->data[1] + x * desc->comp[1].step + y * out->linesize[1]);
|
||||
float *g_out = (float *)(out->data[2] + x * desc->comp[2].step + y * out->linesize[2]);
|
||||
int map[3] = { desc->comp[0].plane, desc->comp[1].plane, desc->comp[2].plane };
|
||||
const float *r_in = (const float *)(in->data[map[0]] + x * desc->comp[map[0]].step + y * in->linesize[map[0]]);
|
||||
const float *g_in = (const float *)(in->data[map[1]] + x * desc->comp[map[1]].step + y * in->linesize[map[1]]);
|
||||
const float *b_in = (const float *)(in->data[map[2]] + x * desc->comp[map[2]].step + y * in->linesize[map[2]]);
|
||||
float *r_out = (float *)(out->data[map[0]] + x * desc->comp[map[0]].step + y * out->linesize[map[0]]);
|
||||
float *g_out = (float *)(out->data[map[1]] + x * desc->comp[map[1]].step + y * out->linesize[map[1]]);
|
||||
float *b_out = (float *)(out->data[map[2]] + x * desc->comp[map[2]].step + y * out->linesize[map[2]]);
|
||||
float sig, sig_orig;
|
||||
|
||||
/* load values */
|
||||
*r_out = *r_in;
|
||||
*b_out = *b_in;
|
||||
*g_out = *g_in;
|
||||
*b_out = *b_in;
|
||||
|
||||
/* desaturate to prevent unnatural colors */
|
||||
if (s->desat > 0) {
|
||||
|
||||
+46
-11
@@ -26,6 +26,7 @@
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/eval.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_qsv.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
@@ -139,8 +140,9 @@ static const AVOption options[] = {
|
||||
{ "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
|
||||
{ "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
|
||||
{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS },
|
||||
#ifdef QSV_HAVE_SCALING_CONFIG
|
||||
{ "scale_mode", "scale mode: 0=auto, 1=low power, 2=high quality", OFFSET(scale_mode), AV_OPT_TYPE_INT, { .i64 = MFX_SCALING_MODE_DEFAULT }, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, .flags = FLAGS, "scale mode" },
|
||||
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -297,6 +299,32 @@ static int config_input(AVFilterLink *inlink)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mfxStatus get_mfx_version(const AVFilterContext *ctx, mfxVersion *mfx_version)
|
||||
{
|
||||
const AVFilterLink *inlink = ctx->inputs[0];
|
||||
AVBufferRef *device_ref;
|
||||
AVHWDeviceContext *device_ctx;
|
||||
AVQSVDeviceContext *device_hwctx;
|
||||
|
||||
if (inlink->hw_frames_ctx) {
|
||||
AVHWFramesContext *frames_ctx = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
|
||||
device_ref = frames_ctx->device_ref;
|
||||
} else if (ctx->hw_device_ctx) {
|
||||
device_ref = ctx->hw_device_ctx;
|
||||
} else {
|
||||
// Unavailable hw context doesn't matter in pass-through mode,
|
||||
// so don't error here but let runtime version checks fail by setting to 0.0
|
||||
mfx_version->Major = 0;
|
||||
mfx_version->Minor = 0;
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
device_ctx = (AVHWDeviceContext *)device_ref->data;
|
||||
device_hwctx = device_ctx->hwctx;
|
||||
|
||||
return MFXQueryVersion(device_hwctx->session, mfx_version);
|
||||
}
|
||||
|
||||
static int config_output(AVFilterLink *outlink)
|
||||
{
|
||||
AVFilterContext *ctx = outlink->src;
|
||||
@@ -304,6 +332,7 @@ static int config_output(AVFilterLink *outlink)
|
||||
QSVVPPParam param = { NULL };
|
||||
QSVVPPCrop crop = { 0 };
|
||||
mfxExtBuffer *ext_buf[ENH_FILTERS_COUNT];
|
||||
mfxVersion mfx_version;
|
||||
AVFilterLink *inlink = ctx->inputs[0];
|
||||
enum AVPixelFormat in_format;
|
||||
|
||||
@@ -317,6 +346,11 @@ static int config_output(AVFilterLink *outlink)
|
||||
param.ext_buf = ext_buf;
|
||||
param.async_depth = vpp->async_depth;
|
||||
|
||||
if (get_mfx_version(ctx, &mfx_version) != MFX_ERR_NONE) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to query mfx version.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (inlink->format == AV_PIX_FMT_QSV) {
|
||||
if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data)
|
||||
return AVERROR(EINVAL);
|
||||
@@ -467,19 +501,20 @@ static int config_output(AVFilterLink *outlink)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (inlink->w != outlink->w || inlink->h != outlink->h) {
|
||||
#ifdef QSV_HAVE_SCALING_CONFIG
|
||||
memset(&vpp->scale_conf, 0, sizeof(mfxExtVPPScaling));
|
||||
vpp->scale_conf.Header.BufferId = MFX_EXTBUFF_VPP_SCALING;
|
||||
vpp->scale_conf.Header.BufferSz = sizeof(mfxExtVPPScaling);
|
||||
vpp->scale_conf.ScalingMode = vpp->scale_mode;
|
||||
if (inlink->w != outlink->w || inlink->h != outlink->h) {
|
||||
if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) {
|
||||
memset(&vpp->scale_conf, 0, sizeof(mfxExtVPPScaling));
|
||||
vpp->scale_conf.Header.BufferId = MFX_EXTBUFF_VPP_SCALING;
|
||||
vpp->scale_conf.Header.BufferSz = sizeof(mfxExtVPPScaling);
|
||||
vpp->scale_conf.ScalingMode = vpp->scale_mode;
|
||||
|
||||
param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->scale_conf;
|
||||
#else
|
||||
av_log(ctx, AV_LOG_WARNING, "The QSV VPP Scale option is "
|
||||
"not supported with this MSDK version.\n");
|
||||
#endif
|
||||
param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->scale_conf;
|
||||
} else
|
||||
av_log(ctx, AV_LOG_WARNING, "The QSV VPP Scale option is "
|
||||
"not supported with this MSDK version.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
|
||||
vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip ||
|
||||
|
||||
+10
-9
@@ -87,11 +87,11 @@ OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o aiff.o pcm.o \
|
||||
OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o aiff.o id3v2enc.o
|
||||
OBJS-$(CONFIG_AIX_DEMUXER) += aixdec.o
|
||||
OBJS-$(CONFIG_ALP_DEMUXER) += alp.o
|
||||
OBJS-$(CONFIG_ALP_MUXER) += alp.o
|
||||
OBJS-$(CONFIG_AMR_DEMUXER) += amr.o
|
||||
OBJS-$(CONFIG_ALP_MUXER) += alp.o rawenc.o
|
||||
OBJS-$(CONFIG_AMR_DEMUXER) += amr.o rawdec.o
|
||||
OBJS-$(CONFIG_AMR_MUXER) += amr.o rawenc.o
|
||||
OBJS-$(CONFIG_AMRNB_DEMUXER) += amr.o
|
||||
OBJS-$(CONFIG_AMRWB_DEMUXER) += amr.o
|
||||
OBJS-$(CONFIG_AMRNB_DEMUXER) += amr.o rawdec.o
|
||||
OBJS-$(CONFIG_AMRWB_DEMUXER) += amr.o rawdec.o
|
||||
OBJS-$(CONFIG_AMV_MUXER) += amvenc.o
|
||||
OBJS-$(CONFIG_ANM_DEMUXER) += anm.o
|
||||
OBJS-$(CONFIG_APC_DEMUXER) += apc.o
|
||||
@@ -259,9 +259,11 @@ OBJS-$(CONFIG_IMAGE2PIPE_MUXER) += img2enc.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE2_ALIAS_PIX_DEMUXER) += img2_alias_pix.o
|
||||
OBJS-$(CONFIG_IMAGE2_BRENDER_PIX_DEMUXER) += img2_brender_pix.o
|
||||
OBJS-$(CONFIG_IMAGE_BMP_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_CRI_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_DDS_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_DPX_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_EXR_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_GEM_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_GIF_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_J2K_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_JPEG_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
@@ -271,7 +273,8 @@ OBJS-$(CONFIG_IMAGE_PBM_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PCX_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PGMYUV_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PGM_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PHOTOCD_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PGX_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PHOTOCD_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PICTOR_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PNG_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PPM_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
@@ -582,9 +585,7 @@ OBJS-$(CONFIG_WAV_DEMUXER) += wavdec.o pcm.o
|
||||
OBJS-$(CONFIG_WAV_MUXER) += wavenc.o
|
||||
OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o
|
||||
OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \
|
||||
av1.o avc.o hevc.o isom_tags.o \
|
||||
flacenc_header.o avlanguage.o \
|
||||
wv.o vorbiscomment.o
|
||||
av1.o avlanguage.o
|
||||
OBJS-$(CONFIG_WEBM_DASH_MANIFEST_MUXER) += webmdashenc.o
|
||||
OBJS-$(CONFIG_WEBM_CHUNK_MUXER) += webm_chunk.o
|
||||
OBJS-$(CONFIG_WEBP_MUXER) += webpenc.o
|
||||
@@ -667,7 +668,7 @@ OBJS-$(CONFIG_UDPLITE_PROTOCOL) += udp.o ip.o
|
||||
OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o
|
||||
|
||||
# external library protocols
|
||||
OBJS-$(CONFIG_LIBAMQP_PROTOCOL) += libamqp.o
|
||||
OBJS-$(CONFIG_LIBAMQP_PROTOCOL) += libamqp.o urldecode.o
|
||||
OBJS-$(CONFIG_LIBRIST_PROTOCOL) += librist.o
|
||||
OBJS-$(CONFIG_LIBRTMP_PROTOCOL) += librtmp.o
|
||||
OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o
|
||||
|
||||
+4
-6
@@ -53,12 +53,10 @@ static int amr_write_header(AVFormatContext *s)
|
||||
AVIOContext *pb = s->pb;
|
||||
AVCodecParameters *par = s->streams[0]->codecpar;
|
||||
|
||||
s->priv_data = NULL;
|
||||
|
||||
if (par->codec_id == AV_CODEC_ID_AMR_NB) {
|
||||
avio_write(pb, AMR_header, sizeof(AMR_header) - 1); /* magic number */
|
||||
avio_write(pb, AMR_header, sizeof(AMR_header)); /* magic number */
|
||||
} else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
|
||||
avio_write(pb, AMRWB_header, sizeof(AMRWB_header) - 1); /* magic number */
|
||||
avio_write(pb, AMRWB_header, sizeof(AMRWB_header)); /* magic number */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -66,6 +64,7 @@ static int amr_write_header(AVFormatContext *s)
|
||||
}
|
||||
#endif /* CONFIG_AMR_MUXER */
|
||||
|
||||
#if CONFIG_AMR_DEMUXER
|
||||
static int amr_probe(const AVProbeData *p)
|
||||
{
|
||||
// Only check for "#!AMR" which could be amr-wb, amr-nb.
|
||||
@@ -92,7 +91,7 @@ static int amr_read_header(AVFormatContext *s)
|
||||
|
||||
read = avio_read(pb, header, sizeof(header));
|
||||
if (read < 0)
|
||||
return ret;
|
||||
return read;
|
||||
|
||||
st = avformat_new_stream(s, NULL);
|
||||
if (!st)
|
||||
@@ -140,7 +139,6 @@ static int amr_read_header(AVFormatContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_AMR_DEMUXER
|
||||
const AVInputFormat ff_amr_demuxer = {
|
||||
.name = "amr",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"),
|
||||
|
||||
@@ -74,7 +74,8 @@ static int aqt_read_header(AVFormatContext *s)
|
||||
new_event = 1;
|
||||
pos = avio_tell(s->pb);
|
||||
if (sub) {
|
||||
sub->duration = frame - sub->pts;
|
||||
if (frame >= sub->pts && (uint64_t)frame - sub->pts < INT64_MAX)
|
||||
sub->duration = frame - sub->pts;
|
||||
sub = NULL;
|
||||
}
|
||||
} else if (*line) {
|
||||
|
||||
@@ -423,7 +423,7 @@ static int argo_asf_write_trailer(AVFormatContext *s)
|
||||
ArgoASFMuxContext *ctx = s->priv_data;
|
||||
int64_t ret;
|
||||
|
||||
if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0))
|
||||
if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET)) < 0)
|
||||
return ret;
|
||||
|
||||
avio_wl32(s->pb, (uint32_t)ctx->nb_blocks);
|
||||
|
||||
@@ -350,7 +350,7 @@ static int argo_cvg_write_trailer(AVFormatContext *s)
|
||||
*/
|
||||
avio_wl32(s->pb, ctx->checksum);
|
||||
|
||||
if ((ret = avio_seek(s->pb, 0, SEEK_SET) < 0))
|
||||
if ((ret = avio_seek(s->pb, 0, SEEK_SET)) < 0)
|
||||
return ret;
|
||||
|
||||
avio_wl32(s->pb, (uint32_t)ctx->size);
|
||||
|
||||
@@ -862,6 +862,8 @@ static int avi_read_header(AVFormatContext *s)
|
||||
memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9,
|
||||
"BottomUp", 9);
|
||||
}
|
||||
if (st->codecpar->height == INT_MIN)
|
||||
return AVERROR_INVALIDDATA;
|
||||
st->codecpar->height = FFABS(st->codecpar->height);
|
||||
|
||||
// avio_skip(pb, size - 5 * 4);
|
||||
|
||||
@@ -241,6 +241,8 @@ static void read_info_chunk(AVFormatContext *s, int64_t size)
|
||||
char value[1024];
|
||||
avio_get_str(pb, INT_MAX, key, sizeof(key));
|
||||
avio_get_str(pb, INT_MAX, value, sizeof(value));
|
||||
if (!*key)
|
||||
continue;
|
||||
av_dict_set(&s->metadata, key, value, 0);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -817,10 +817,16 @@ static int parse_playlist(HLSContext *c, const char *url,
|
||||
&info);
|
||||
new_rendition(c, &info, url);
|
||||
} else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
|
||||
int64_t t;
|
||||
ret = ensure_playlist(c, &pls, url);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
pls->target_duration = strtoll(ptr, NULL, 10) * AV_TIME_BASE;
|
||||
t = strtoll(ptr, NULL, 10);
|
||||
if (t < 0 || t >= INT64_MAX / AV_TIME_BASE) {
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
pls->target_duration = t * AV_TIME_BASE;
|
||||
} else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
|
||||
uint64_t seq_no;
|
||||
ret = ensure_playlist(c, &pls, url);
|
||||
@@ -914,7 +920,7 @@ static int parse_playlist(HLSContext *c, const char *url,
|
||||
if (has_iv) {
|
||||
memcpy(seg->iv, iv, sizeof(iv));
|
||||
} else {
|
||||
int64_t seq = pls->start_seq_no + pls->n_segments;
|
||||
uint64_t seq = pls->start_seq_no + (uint64_t)pls->n_segments;
|
||||
memset(seg->iv, 0, sizeof(seg->iv));
|
||||
AV_WB64(seg->iv + 8, seq);
|
||||
}
|
||||
|
||||
@@ -900,6 +900,7 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
|
||||
st->sample_aspect_ratio = vs->streams[i]->sample_aspect_ratio;
|
||||
st->time_base = vs->streams[i]->time_base;
|
||||
av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
|
||||
st->id = vs->streams[i]->id;
|
||||
}
|
||||
|
||||
vs->start_pos = 0;
|
||||
|
||||
+33
-33
@@ -688,7 +688,7 @@ int ff_imf_parse_cpl_from_xml_dom(xmlDocPtr doc, FFIMFCPL **cpl)
|
||||
}
|
||||
|
||||
cpl_element = xmlDocGetRootElement(doc);
|
||||
if (xmlStrcmp(cpl_element->name, "CompositionPlaylist")) {
|
||||
if (!cpl_element || xmlStrcmp(cpl_element->name, "CompositionPlaylist")) {
|
||||
av_log(NULL, AV_LOG_ERROR, "The root element of the CPL is not CompositionPlaylist\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto cleanup;
|
||||
@@ -797,44 +797,44 @@ int ff_imf_parse_cpl(AVIOContext *in, FFIMFCPL **cpl)
|
||||
AVBPrint buf;
|
||||
xmlDoc *doc = NULL;
|
||||
int ret = 0;
|
||||
int64_t filesize = 0;
|
||||
|
||||
filesize = avio_size(in);
|
||||
filesize = filesize > 0 ? filesize : 8192;
|
||||
av_bprint_init(&buf, filesize + 1, AV_BPRINT_SIZE_UNLIMITED);
|
||||
ret = avio_read_to_bprint(in, &buf, UINT_MAX - 1);
|
||||
if (ret < 0 || !avio_feof(in) || buf.len == 0) {
|
||||
av_bprint_init(&buf, 0, INT_MAX); // xmlReadMemory uses integer length
|
||||
|
||||
ret = avio_read_to_bprint(in, &buf, SIZE_MAX);
|
||||
if (ret < 0 || !avio_feof(in)) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot read IMF CPL\n");
|
||||
if (ret == 0)
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
} else {
|
||||
LIBXML_TEST_VERSION
|
||||
|
||||
filesize = buf.len;
|
||||
doc = xmlReadMemory(buf.str, filesize, NULL, NULL, 0);
|
||||
if (!doc) {
|
||||
av_log(NULL,
|
||||
AV_LOG_ERROR,
|
||||
"XML parsing failed when reading the IMF CPL\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if ((ret = ff_imf_parse_cpl_from_xml_dom(doc, cpl))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot parse IMF CPL\n");
|
||||
} else {
|
||||
av_log(NULL,
|
||||
AV_LOG_INFO,
|
||||
"IMF CPL ContentTitle: %s\n",
|
||||
(*cpl)->content_title_utf8);
|
||||
av_log(NULL,
|
||||
AV_LOG_INFO,
|
||||
"IMF CPL Id: " FF_IMF_UUID_FORMAT "\n",
|
||||
UID_ARG((*cpl)->id_uuid));
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
LIBXML_TEST_VERSION
|
||||
|
||||
doc = xmlReadMemory(buf.str, buf.len, NULL, NULL, 0);
|
||||
if (!doc) {
|
||||
av_log(NULL,
|
||||
AV_LOG_ERROR,
|
||||
"XML parsing failed when reading the IMF CPL\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if ((ret = ff_imf_parse_cpl_from_xml_dom(doc, cpl))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot parse IMF CPL\n");
|
||||
} else {
|
||||
av_log(NULL,
|
||||
AV_LOG_INFO,
|
||||
"IMF CPL ContentTitle: %s\n",
|
||||
(*cpl)->content_title_utf8);
|
||||
av_log(NULL,
|
||||
AV_LOG_INFO,
|
||||
"IMF CPL Id: " FF_IMF_UUID_FORMAT "\n",
|
||||
UID_ARG((*cpl)->id_uuid));
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
clean_up:
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
|
||||
return ret;
|
||||
|
||||
+198
-120
@@ -65,16 +65,16 @@
|
||||
#include "avio_internal.h"
|
||||
#include "imf.h"
|
||||
#include "internal.h"
|
||||
#include "libavcodec/packet.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "mxf.h"
|
||||
#include "url.h"
|
||||
#include <inttypes.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
#define MAX_BPRINT_READ_SIZE (UINT_MAX - 1)
|
||||
#define DEFAULT_ASSETMAP_SIZE 8 * 1024
|
||||
#define AVRATIONAL_FORMAT "%d/%d"
|
||||
#define AVRATIONAL_ARG(rational) rational.num, rational.den
|
||||
|
||||
@@ -99,17 +99,20 @@ typedef struct IMFVirtualTrackResourcePlaybackCtx {
|
||||
IMFAssetLocator *locator;
|
||||
FFIMFTrackFileResource *resource;
|
||||
AVFormatContext *ctx;
|
||||
AVRational start_time;
|
||||
AVRational end_time;
|
||||
AVRational ts_offset;
|
||||
} IMFVirtualTrackResourcePlaybackCtx;
|
||||
|
||||
typedef struct IMFVirtualTrackPlaybackCtx {
|
||||
int32_t index; /**< Track index in playlist */
|
||||
AVRational current_timestamp; /**< Current temporal position */
|
||||
AVRational duration; /**< Overall duration */
|
||||
uint32_t resource_count; /**< Number of resources */
|
||||
uint32_t resource_count; /**< Number of resources (<= INT32_MAX) */
|
||||
unsigned int resources_alloc_sz; /**< Size of the buffer holding the resource */
|
||||
IMFVirtualTrackResourcePlaybackCtx *resources; /**< Buffer holding the resources */
|
||||
uint32_t current_resource_index; /**< Current resource */
|
||||
int64_t last_pts; /**< Last timestamp */
|
||||
int32_t current_resource_index; /**< Index of the current resource in resources,
|
||||
or < 0 if a current resource has yet to be selected */
|
||||
} IMFVirtualTrackPlaybackCtx;
|
||||
|
||||
typedef struct IMFContext {
|
||||
@@ -202,7 +205,7 @@ static int parse_imf_asset_map_from_xml_dom(AVFormatContext *s,
|
||||
elem_count + asset_map->asset_count,
|
||||
sizeof(IMFAssetLocator));
|
||||
if (!tmp) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot allocate IMF asset locators\n");
|
||||
av_log(s, AV_LOG_ERROR, "Cannot allocate IMF asset locators\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
asset_map->assets = tmp;
|
||||
@@ -263,7 +266,7 @@ static void imf_asset_locator_map_init(IMFAssetLocatorMap *asset_map)
|
||||
*/
|
||||
static void imf_asset_locator_map_deinit(IMFAssetLocatorMap *asset_map)
|
||||
{
|
||||
for (uint32_t i = 0; i < asset_map->asset_count; ++i)
|
||||
for (uint32_t i = 0; i < asset_map->asset_count; i++)
|
||||
av_freep(&asset_map->assets[i].absolute_uri);
|
||||
|
||||
av_freep(&asset_map->assets);
|
||||
@@ -279,7 +282,6 @@ static int parse_assetmap(AVFormatContext *s, const char *url)
|
||||
const char *base_url;
|
||||
char *tmp_str = NULL;
|
||||
int ret;
|
||||
int64_t filesize;
|
||||
|
||||
av_log(s, AV_LOG_DEBUG, "Asset Map URL: %s\n", url);
|
||||
|
||||
@@ -289,13 +291,10 @@ static int parse_assetmap(AVFormatContext *s, const char *url)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
filesize = avio_size(in);
|
||||
filesize = filesize > 0 ? filesize : DEFAULT_ASSETMAP_SIZE;
|
||||
av_bprint_init(&buf, 0, INT_MAX); // xmlReadMemory uses integer length
|
||||
|
||||
av_bprint_init(&buf, filesize + 1, AV_BPRINT_SIZE_UNLIMITED);
|
||||
|
||||
ret = avio_read_to_bprint(in, &buf, MAX_BPRINT_READ_SIZE);
|
||||
if (ret < 0 || !avio_feof(in) || buf.len == 0) {
|
||||
ret = avio_read_to_bprint(in, &buf, SIZE_MAX);
|
||||
if (ret < 0 || !avio_feof(in)) {
|
||||
av_log(s, AV_LOG_ERROR, "Unable to read to asset map '%s'\n", url);
|
||||
if (ret == 0)
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
@@ -311,8 +310,7 @@ static int parse_assetmap(AVFormatContext *s, const char *url)
|
||||
}
|
||||
base_url = av_dirname(tmp_str);
|
||||
|
||||
filesize = buf.len;
|
||||
doc = xmlReadMemory(buf.str, filesize, url, NULL, 0);
|
||||
doc = xmlReadMemory(buf.str, buf.len, url, NULL, 0);
|
||||
|
||||
ret = parse_imf_asset_map_from_xml_dom(s, doc, &c->asset_locator_map, base_url);
|
||||
if (!ret)
|
||||
@@ -334,7 +332,7 @@ clean_up:
|
||||
|
||||
static IMFAssetLocator *find_asset_map_locator(IMFAssetLocatorMap *asset_map, FFIMFUUID uuid)
|
||||
{
|
||||
for (uint32_t i = 0; i < asset_map->asset_count; ++i) {
|
||||
for (uint32_t i = 0; i < asset_map->asset_count; i++) {
|
||||
if (memcmp(asset_map->assets[i].uuid, uuid, 16) == 0)
|
||||
return &(asset_map->assets[i]);
|
||||
}
|
||||
@@ -348,6 +346,7 @@ static int open_track_resource_context(AVFormatContext *s,
|
||||
int ret = 0;
|
||||
int64_t entry_point;
|
||||
AVDictionary *opts = NULL;
|
||||
AVStream *st;
|
||||
|
||||
if (track_resource->ctx) {
|
||||
av_log(s,
|
||||
@@ -389,23 +388,28 @@ static int open_track_resource_context(AVFormatContext *s,
|
||||
}
|
||||
av_dict_free(&opts);
|
||||
|
||||
/* Compare the source timebase to the resource edit rate,
|
||||
* considering the first stream of the source file
|
||||
*/
|
||||
if (av_cmp_q(track_resource->ctx->streams[0]->time_base,
|
||||
av_inv_q(track_resource->resource->base.edit_rate)))
|
||||
/* make sure there is only one stream in the file */
|
||||
|
||||
if (track_resource->ctx->nb_streams != 1) {
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
st = track_resource->ctx->streams[0];
|
||||
|
||||
/* Warn if the resource time base does not match the file time base */
|
||||
if (av_cmp_q(st->time_base, av_inv_q(track_resource->resource->base.edit_rate)))
|
||||
av_log(s,
|
||||
AV_LOG_WARNING,
|
||||
"Incoherent source stream timebase %d/%d regarding resource edit rate: %d/%d",
|
||||
track_resource->ctx->streams[0]->time_base.num,
|
||||
track_resource->ctx->streams[0]->time_base.den,
|
||||
"Incoherent source stream timebase " AVRATIONAL_FORMAT
|
||||
"regarding resource edit rate: " AVRATIONAL_FORMAT,
|
||||
st->time_base.num,
|
||||
st->time_base.den,
|
||||
track_resource->resource->base.edit_rate.den,
|
||||
track_resource->resource->base.edit_rate.num);
|
||||
|
||||
entry_point = (int64_t)track_resource->resource->base.entry_point
|
||||
* track_resource->resource->base.edit_rate.den
|
||||
* AV_TIME_BASE
|
||||
/ track_resource->resource->base.edit_rate.num;
|
||||
entry_point = av_rescale_q(track_resource->resource->base.entry_point, st->time_base,
|
||||
av_inv_q(track_resource->resource->base.edit_rate));
|
||||
|
||||
if (entry_point) {
|
||||
av_log(s,
|
||||
@@ -413,7 +417,7 @@ static int open_track_resource_context(AVFormatContext *s,
|
||||
"Seek at resource %s entry point: %" PRIu32 "\n",
|
||||
track_resource->locator->absolute_uri,
|
||||
track_resource->resource->base.entry_point);
|
||||
ret = avformat_seek_file(track_resource->ctx, -1, entry_point, entry_point, entry_point, 0);
|
||||
ret = avformat_seek_file(track_resource->ctx, 0, entry_point, entry_point, entry_point, 0);
|
||||
if (ret < 0) {
|
||||
av_log(s,
|
||||
AV_LOG_ERROR,
|
||||
@@ -442,7 +446,6 @@ static int open_track_file_resource(AVFormatContext *s,
|
||||
IMFContext *c = s->priv_data;
|
||||
IMFAssetLocator *asset_locator;
|
||||
void *tmp;
|
||||
int ret;
|
||||
|
||||
asset_locator = find_asset_map_locator(&c->asset_locator_map, track_file_resource->track_file_uuid);
|
||||
if (!asset_locator) {
|
||||
@@ -459,7 +462,7 @@ static int open_track_file_resource(AVFormatContext *s,
|
||||
UID_ARG(asset_locator->uuid),
|
||||
asset_locator->absolute_uri);
|
||||
|
||||
if (track->resource_count > UINT32_MAX - track_file_resource->base.repeat_count
|
||||
if (track->resource_count > INT32_MAX - track_file_resource->base.repeat_count
|
||||
|| (track->resource_count + track_file_resource->base.repeat_count)
|
||||
> INT_MAX / sizeof(IMFVirtualTrackResourcePlaybackCtx))
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -471,19 +474,22 @@ static int open_track_file_resource(AVFormatContext *s,
|
||||
return AVERROR(ENOMEM);
|
||||
track->resources = tmp;
|
||||
|
||||
for (uint32_t i = 0; i < track_file_resource->base.repeat_count; ++i) {
|
||||
for (uint32_t i = 0; i < track_file_resource->base.repeat_count; i++) {
|
||||
IMFVirtualTrackResourcePlaybackCtx vt_ctx;
|
||||
|
||||
vt_ctx.locator = asset_locator;
|
||||
vt_ctx.resource = track_file_resource;
|
||||
vt_ctx.ctx = NULL;
|
||||
if ((ret = open_track_resource_context(s, &vt_ctx)) != 0)
|
||||
return ret;
|
||||
track->resources[track->resource_count++] = vt_ctx;
|
||||
track->duration = av_add_q(track->duration,
|
||||
vt_ctx.start_time = track->duration;
|
||||
vt_ctx.ts_offset = av_sub_q(vt_ctx.start_time,
|
||||
av_div_q(av_make_q((int)track_file_resource->base.entry_point, 1),
|
||||
track_file_resource->base.edit_rate));
|
||||
vt_ctx.end_time = av_add_q(track->duration,
|
||||
av_make_q((int)track_file_resource->base.duration
|
||||
* track_file_resource->base.edit_rate.den,
|
||||
track_file_resource->base.edit_rate.num));
|
||||
track->resources[track->resource_count++] = vt_ctx;
|
||||
track->duration = vt_ctx.end_time;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -491,7 +497,7 @@ static int open_track_file_resource(AVFormatContext *s,
|
||||
|
||||
static void imf_virtual_track_playback_context_deinit(IMFVirtualTrackPlaybackCtx *track)
|
||||
{
|
||||
for (uint32_t i = 0; i < track->resource_count; ++i)
|
||||
for (uint32_t i = 0; i < track->resource_count; i++)
|
||||
avformat_close_input(&track->resources[i].ctx);
|
||||
|
||||
av_freep(&track->resources);
|
||||
@@ -508,6 +514,7 @@ static int open_virtual_track(AVFormatContext *s,
|
||||
|
||||
if (!(track = av_mallocz(sizeof(IMFVirtualTrackPlaybackCtx))))
|
||||
return AVERROR(ENOMEM);
|
||||
track->current_resource_index = -1;
|
||||
track->index = track_index;
|
||||
track->duration = av_make_q(0, 1);
|
||||
|
||||
@@ -553,11 +560,14 @@ static int set_context_streams_from_tracks(AVFormatContext *s)
|
||||
IMFContext *c = s->priv_data;
|
||||
int ret = 0;
|
||||
|
||||
for (uint32_t i = 0; i < c->track_count; ++i) {
|
||||
for (uint32_t i = 0; i < c->track_count; i++) {
|
||||
AVStream *asset_stream;
|
||||
AVStream *first_resource_stream;
|
||||
|
||||
/* Open the first resource of the track to get stream information */
|
||||
ret = open_track_resource_context(s, &c->tracks[i]->resources[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
first_resource_stream = c->tracks[i]->resources[0].ctx->streams[0];
|
||||
av_log(s, AV_LOG_DEBUG, "Open the first resource of track %d\n", c->tracks[i]->index);
|
||||
|
||||
@@ -600,7 +610,7 @@ static int open_cpl_tracks(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < c->cpl->main_audio_track_count; ++i) {
|
||||
for (uint32_t i = 0; i < c->cpl->main_audio_track_count; i++) {
|
||||
if ((ret = open_virtual_track(s, &c->cpl->main_audio_tracks[i], track_index++)) != 0) {
|
||||
av_log(s,
|
||||
AV_LOG_ERROR,
|
||||
@@ -624,8 +634,11 @@ static int imf_read_header(AVFormatContext *s)
|
||||
tmp_str = av_strdup(s->url);
|
||||
if (!tmp_str)
|
||||
return AVERROR(ENOMEM);
|
||||
c->base_url = av_strdup(av_dirname(tmp_str));
|
||||
av_freep(&tmp_str);
|
||||
if (!c->base_url)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
c->base_url = av_dirname(tmp_str);
|
||||
if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -703,11 +716,14 @@ static IMFVirtualTrackPlaybackCtx *get_next_track_with_minimum_timestamp(AVForma
|
||||
return track;
|
||||
}
|
||||
|
||||
static IMFVirtualTrackResourcePlaybackCtx *get_resource_context_for_timestamp(AVFormatContext *s,
|
||||
IMFVirtualTrackPlaybackCtx *track)
|
||||
static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrackPlaybackCtx *track, IMFVirtualTrackResourcePlaybackCtx **resource)
|
||||
{
|
||||
AVRational edit_unit_duration = av_inv_q(track->resources[0].resource->base.edit_rate);
|
||||
AVRational cumulated_duration = av_make_q(0, edit_unit_duration.den);
|
||||
*resource = NULL;
|
||||
|
||||
if (av_cmp_q(track->current_timestamp, track->duration) >= 0) {
|
||||
av_log(s, AV_LOG_DEBUG, "Reached the end of the virtual track\n");
|
||||
return AVERROR_EOF;
|
||||
}
|
||||
|
||||
av_log(s,
|
||||
AV_LOG_DEBUG,
|
||||
@@ -715,119 +731,181 @@ static IMFVirtualTrackResourcePlaybackCtx *get_resource_context_for_timestamp(AV
|
||||
track->index,
|
||||
av_q2d(track->current_timestamp),
|
||||
av_q2d(track->duration));
|
||||
for (uint32_t i = 0; i < track->resource_count; ++i) {
|
||||
cumulated_duration = av_add_q(cumulated_duration,
|
||||
av_make_q((int)track->resources[i].resource->base.duration
|
||||
* edit_unit_duration.num,
|
||||
edit_unit_duration.den));
|
||||
for (uint32_t i = 0; i < track->resource_count; i++) {
|
||||
|
||||
if (av_cmp_q(av_add_q(track->current_timestamp, edit_unit_duration), cumulated_duration) <= 0) {
|
||||
if (av_cmp_q(track->resources[i].end_time, track->current_timestamp) > 0) {
|
||||
av_log(s,
|
||||
AV_LOG_DEBUG,
|
||||
"Found resource %d in track %d to read for timestamp %lf "
|
||||
"(on cumulated=%lf): entry=%" PRIu32
|
||||
"Found resource %d in track %d to read at timestamp %lf: "
|
||||
"entry=%" PRIu32
|
||||
", duration=%" PRIu32
|
||||
", editrate=" AVRATIONAL_FORMAT
|
||||
" | edit_unit_duration=%lf\n",
|
||||
", editrate=" AVRATIONAL_FORMAT,
|
||||
i,
|
||||
track->index,
|
||||
av_q2d(track->current_timestamp),
|
||||
av_q2d(cumulated_duration),
|
||||
track->resources[i].resource->base.entry_point,
|
||||
track->resources[i].resource->base.duration,
|
||||
AVRATIONAL_ARG(track->resources[i].resource->base.edit_rate),
|
||||
av_q2d(edit_unit_duration));
|
||||
AVRATIONAL_ARG(track->resources[i].resource->base.edit_rate));
|
||||
|
||||
if (track->current_resource_index != i) {
|
||||
int ret;
|
||||
|
||||
av_log(s,
|
||||
AV_LOG_DEBUG,
|
||||
"Switch resource on track %d: re-open context\n",
|
||||
track->index);
|
||||
if (open_track_resource_context(s, &(track->resources[i])) != 0)
|
||||
return NULL;
|
||||
avformat_close_input(&(track->resources[track->current_resource_index].ctx));
|
||||
|
||||
ret = open_track_resource_context(s, track->resources + i);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (track->current_resource_index > 0)
|
||||
avformat_close_input(&track->resources[track->current_resource_index].ctx);
|
||||
track->current_resource_index = i;
|
||||
}
|
||||
|
||||
return &(track->resources[track->current_resource_index]);
|
||||
*resource = track->resources + track->current_resource_index;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
av_log(s, AV_LOG_ERROR, "Could not find IMF track resource to read\n");
|
||||
return AVERROR_STREAM_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int imf_time_to_ts(int64_t *ts, AVRational t, AVRational time_base)
|
||||
{
|
||||
int dst_num;
|
||||
int dst_den;
|
||||
AVRational r;
|
||||
|
||||
r = av_div_q(t, time_base);
|
||||
|
||||
if ((av_reduce(&dst_num, &dst_den, r.num, r.den, INT64_MAX) != 1))
|
||||
return 1;
|
||||
|
||||
if (dst_den != 1)
|
||||
return 1;
|
||||
|
||||
*ts = dst_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
IMFContext *c = s->priv_data;
|
||||
IMFVirtualTrackResourcePlaybackCtx *resource_to_read = NULL;
|
||||
AVRational edit_unit_duration;
|
||||
IMFVirtualTrackResourcePlaybackCtx *resource = NULL;
|
||||
int ret = 0;
|
||||
IMFVirtualTrackPlaybackCtx *track;
|
||||
FFStream *track_stream;
|
||||
int64_t delta_ts;
|
||||
AVStream *st;
|
||||
AVRational next_timestamp;
|
||||
|
||||
track = get_next_track_with_minimum_timestamp(s);
|
||||
|
||||
if (av_cmp_q(track->current_timestamp, track->duration) == 0)
|
||||
return AVERROR_EOF;
|
||||
ret = get_resource_context_for_timestamp(s, track, &resource);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
resource_to_read = get_resource_context_for_timestamp(s, track);
|
||||
|
||||
if (!resource_to_read) {
|
||||
edit_unit_duration
|
||||
= av_inv_q(track->resources[track->current_resource_index].resource->base.edit_rate);
|
||||
|
||||
if (av_cmp_q(av_add_q(track->current_timestamp, edit_unit_duration), track->duration) > 0)
|
||||
return AVERROR_EOF;
|
||||
|
||||
av_log(s, AV_LOG_ERROR, "Could not find IMF track resource to read\n");
|
||||
return AVERROR_STREAM_NOT_FOUND;
|
||||
ret = av_read_frame(resource->ctx, pkt);
|
||||
if (ret) {
|
||||
av_log(s, AV_LOG_ERROR, "Failed to read frame\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
|
||||
ret = av_read_frame(resource_to_read->ctx, pkt);
|
||||
av_log(s,
|
||||
AV_LOG_DEBUG,
|
||||
"Got packet: pts=%" PRId64
|
||||
", dts=%" PRId64
|
||||
", duration=%" PRId64
|
||||
", stream_index=%d, pos=%" PRId64
|
||||
"\n",
|
||||
pkt->pts,
|
||||
pkt->dts,
|
||||
pkt->duration,
|
||||
pkt->stream_index,
|
||||
pkt->pos);
|
||||
av_log(s, AV_LOG_DEBUG, "Got packet: pts=%" PRId64 ", dts=%" PRId64
|
||||
", duration=%" PRId64 ", stream_index=%d, pos=%" PRId64
|
||||
", time_base=" AVRATIONAL_FORMAT "\n", pkt->pts, pkt->dts, pkt->duration,
|
||||
pkt->stream_index, pkt->pos, pkt->time_base.num, pkt->time_base.den);
|
||||
|
||||
track_stream = ffstream(s->streams[track->index]);
|
||||
if (ret >= 0) {
|
||||
/* Update packet info from track */
|
||||
if (pkt->dts < track_stream->cur_dts && track->last_pts > 0)
|
||||
pkt->dts = track_stream->cur_dts;
|
||||
/* IMF resources contain only one stream */
|
||||
|
||||
pkt->pts = track->last_pts;
|
||||
pkt->dts = pkt->dts
|
||||
- (int64_t)track->resources[track->current_resource_index].resource->base.entry_point;
|
||||
pkt->stream_index = track->index;
|
||||
if (pkt->stream_index != 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
st = resource->ctx->streams[0];
|
||||
|
||||
/* Update track cursors */
|
||||
track->current_timestamp
|
||||
= av_add_q(track->current_timestamp,
|
||||
av_make_q((int)pkt->duration
|
||||
* resource_to_read->ctx->streams[0]->time_base.num,
|
||||
resource_to_read->ctx->streams[0]->time_base.den));
|
||||
track->last_pts += pkt->duration;
|
||||
pkt->stream_index = track->index;
|
||||
|
||||
return 0;
|
||||
} else if (ret != AVERROR_EOF) {
|
||||
av_log(s,
|
||||
AV_LOG_ERROR,
|
||||
"Could not get packet from track %d: %s\n",
|
||||
track->index,
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
/* adjust the packet PTS and DTS based on the temporal position of the resource within the timeline */
|
||||
|
||||
ret = imf_time_to_ts(&delta_ts, resource->ts_offset, st->time_base);
|
||||
|
||||
if (!ret) {
|
||||
if (pkt->pts != AV_NOPTS_VALUE)
|
||||
pkt->pts += delta_ts;
|
||||
if (pkt->dts != AV_NOPTS_VALUE)
|
||||
pkt->dts += delta_ts;
|
||||
} else {
|
||||
av_log(s, AV_LOG_WARNING, "Incoherent time stamp " AVRATIONAL_FORMAT " for time base " AVRATIONAL_FORMAT,
|
||||
resource->ts_offset.num, resource->ts_offset.den, pkt->time_base.num,
|
||||
pkt->time_base.den);
|
||||
}
|
||||
|
||||
/* advance the track timestamp by the packet duration */
|
||||
|
||||
next_timestamp = av_add_q(track->current_timestamp,
|
||||
av_mul_q(av_make_q((int)pkt->duration, 1), st->time_base));
|
||||
|
||||
/* if necessary, clamp the next timestamp to the end of the current resource */
|
||||
|
||||
if (av_cmp_q(next_timestamp, resource->end_time) > 0) {
|
||||
|
||||
int64_t new_pkt_dur;
|
||||
|
||||
/* shrink the packet duration */
|
||||
|
||||
ret = imf_time_to_ts(&new_pkt_dur,
|
||||
av_sub_q(resource->end_time, track->current_timestamp),
|
||||
st->time_base);
|
||||
|
||||
if (!ret)
|
||||
pkt->duration = new_pkt_dur;
|
||||
else
|
||||
av_log(s, AV_LOG_WARNING, "Incoherent time base in packet duration calculation");
|
||||
|
||||
/* shrink the packet itself for audio essence */
|
||||
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE) {
|
||||
/* AV_CODEC_ID_PCM_S24LE is the only PCM format supported in IMF */
|
||||
/* in this case, explicitly shrink the packet */
|
||||
|
||||
int bytes_per_sample = av_get_exact_bits_per_sample(st->codecpar->codec_id) >> 3;
|
||||
int64_t nbsamples = av_rescale_q(pkt->duration,
|
||||
st->time_base,
|
||||
av_make_q(1, st->codecpar->sample_rate));
|
||||
av_shrink_packet(pkt, nbsamples * st->codecpar->channels * bytes_per_sample);
|
||||
|
||||
} else {
|
||||
/* in all other cases, use side data to skip samples */
|
||||
int64_t skip_samples;
|
||||
|
||||
ret = imf_time_to_ts(&skip_samples,
|
||||
av_sub_q(next_timestamp, resource->end_time),
|
||||
av_make_q(1, st->codecpar->sample_rate));
|
||||
|
||||
if (ret || skip_samples < 0 || skip_samples > UINT32_MAX) {
|
||||
av_log(s, AV_LOG_WARNING, "Cannot skip audio samples");
|
||||
} else {
|
||||
uint8_t *side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
|
||||
if (!side_data)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
AV_WL32(side_data + 4, skip_samples); /* skip from end of this packet */
|
||||
side_data[6] = 1; /* reason for end is convergence */
|
||||
}
|
||||
}
|
||||
|
||||
next_timestamp = resource->end_time;
|
||||
|
||||
} else {
|
||||
av_log(s, AV_LOG_WARNING, "Non-audio packet duration reduced");
|
||||
}
|
||||
}
|
||||
|
||||
return AVERROR_EOF;
|
||||
track->current_timestamp = next_timestamp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imf_close(AVFormatContext *s)
|
||||
@@ -840,7 +918,7 @@ static int imf_close(AVFormatContext *s)
|
||||
imf_asset_locator_map_deinit(&c->asset_locator_map);
|
||||
ff_imf_cpl_free(c->cpl);
|
||||
|
||||
for (uint32_t i = 0; i < c->track_count; ++i) {
|
||||
for (uint32_t i = 0; i < c->track_count; i++) {
|
||||
imf_virtual_track_playback_context_deinit(c->tracks[i]);
|
||||
av_freep(&c->tracks[i]);
|
||||
}
|
||||
|
||||
@@ -1708,7 +1708,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size,
|
||||
case MATROSKA_TRACK_ENCODING_COMP_ZLIB:
|
||||
{
|
||||
z_stream zstream = { 0 };
|
||||
if (inflateInit(&zstream) != Z_OK)
|
||||
if (!pkt_size || inflateInit(&zstream) != Z_OK)
|
||||
return -1;
|
||||
zstream.next_in = data;
|
||||
zstream.avail_in = isize;
|
||||
@@ -1741,7 +1741,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size,
|
||||
case MATROSKA_TRACK_ENCODING_COMP_BZLIB:
|
||||
{
|
||||
bz_stream bzstream = { 0 };
|
||||
if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)
|
||||
if (!pkt_size || BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)
|
||||
return -1;
|
||||
bzstream.next_in = data;
|
||||
bzstream.avail_in = isize;
|
||||
@@ -3027,6 +3027,8 @@ static int matroska_read_header(AVFormatContext *s)
|
||||
|
||||
if (!matroska->time_scale)
|
||||
matroska->time_scale = 1000000;
|
||||
if (isnan(matroska->duration))
|
||||
matroska->duration = 0;
|
||||
if (matroska->duration)
|
||||
matroska->ctx->duration = matroska->duration * matroska->time_scale *
|
||||
1000 / AV_TIME_BASE;
|
||||
@@ -3972,7 +3974,8 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start)
|
||||
CueDesc cue_desc;
|
||||
int i;
|
||||
|
||||
if (ts >= matroska->duration * matroska->time_scale) return (CueDesc) {-1, -1, -1, -1};
|
||||
if (ts >= (int64_t)(matroska->duration * matroska->time_scale))
|
||||
return (CueDesc) {-1, -1, -1, -1};
|
||||
for (i = 1; i < nb_index_entries; i++) {
|
||||
if (index_entries[i - 1].timestamp * matroska->time_scale <= ts &&
|
||||
index_entries[i].timestamp * matroska->time_scale > ts) {
|
||||
@@ -4167,6 +4170,8 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t
|
||||
// prebuffered.
|
||||
pre_bytes = desc_end.end_offset - desc_end.start_offset;
|
||||
pre_ns = desc_end.end_time_ns - desc_end.start_time_ns;
|
||||
if (pre_ns <= 0)
|
||||
return -1;
|
||||
pre_sec = pre_ns / nano_seconds_per_second;
|
||||
prebuffer_bytes +=
|
||||
pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec);
|
||||
@@ -4178,12 +4183,16 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t
|
||||
do {
|
||||
int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset;
|
||||
int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns;
|
||||
double desc_sec = desc_ns / nano_seconds_per_second;
|
||||
double calc_bits_per_second = (desc_bytes * 8) / desc_sec;
|
||||
double desc_sec, calc_bits_per_second, percent, mod_bits_per_second;
|
||||
if (desc_bytes <= 0)
|
||||
return -1;
|
||||
|
||||
desc_sec = desc_ns / nano_seconds_per_second;
|
||||
calc_bits_per_second = (desc_bytes * 8) / desc_sec;
|
||||
|
||||
// Drop the bps by the percentage of bytes buffered.
|
||||
double percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
|
||||
double mod_bits_per_second = calc_bits_per_second * percent;
|
||||
percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
|
||||
mod_bits_per_second = calc_bits_per_second * percent;
|
||||
|
||||
if (prebuffer < desc_sec) {
|
||||
double search_sec =
|
||||
|
||||
+67
-45
@@ -21,6 +21,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "av1.h"
|
||||
#include "avc.h"
|
||||
#include "hevc.h"
|
||||
@@ -59,6 +61,11 @@
|
||||
* Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */
|
||||
#define MAX_SEEKHEAD_ENTRIES 7
|
||||
|
||||
#define MODE_MATROSKAv2 0x01
|
||||
#define MODE_WEBM 0x02
|
||||
|
||||
#define IS_WEBM(mkv) (CONFIG_WEBM_MUXER && CONFIG_MATROSKA_MUXER ? \
|
||||
((mkv)->mode == MODE_WEBM) : CONFIG_WEBM_MUXER)
|
||||
#define IS_SEEKABLE(pb, mkv) (((pb)->seekable & AVIO_SEEKABLE_NORMAL) && \
|
||||
!(mkv)->is_live)
|
||||
|
||||
@@ -118,9 +125,6 @@ typedef struct mkv_track {
|
||||
int64_t ts_offset;
|
||||
} mkv_track;
|
||||
|
||||
#define MODE_MATROSKAv2 0x01
|
||||
#define MODE_WEBM 0x02
|
||||
|
||||
typedef struct MatroskaMuxContext {
|
||||
const AVClass *class;
|
||||
int mode;
|
||||
@@ -640,6 +644,7 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
static int put_wv_codecpriv(AVIOContext *pb, const AVCodecParameters *par)
|
||||
{
|
||||
if (par->extradata && par->extradata_size == 2)
|
||||
@@ -717,6 +722,7 @@ static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
const AVCodecParameters *par,
|
||||
@@ -726,6 +732,14 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
case AV_CODEC_ID_VORBIS:
|
||||
case AV_CODEC_ID_THEORA:
|
||||
return put_xiph_codecpriv(s, dyn_cp, par);
|
||||
case AV_CODEC_ID_AV1:
|
||||
if (par->extradata_size)
|
||||
return ff_isom_write_av1c(dyn_cp, par->extradata,
|
||||
par->extradata_size);
|
||||
else
|
||||
put_ebml_void(pb, 4 + 3);
|
||||
break;
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
case AV_CODEC_ID_FLAC:
|
||||
return put_flac_codecpriv(s, dyn_cp, par);
|
||||
case AV_CODEC_ID_WAVPACK:
|
||||
@@ -736,13 +750,6 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
case AV_CODEC_ID_HEVC:
|
||||
return ff_isom_write_hvcc(dyn_cp, par->extradata,
|
||||
par->extradata_size, 0);
|
||||
case AV_CODEC_ID_AV1:
|
||||
if (par->extradata_size)
|
||||
return ff_isom_write_av1c(dyn_cp, par->extradata,
|
||||
par->extradata_size);
|
||||
else
|
||||
put_ebml_void(pb, 4 + 3);
|
||||
break;
|
||||
case AV_CODEC_ID_ALAC:
|
||||
if (par->extradata_size < 36) {
|
||||
av_log(s, AV_LOG_ERROR,
|
||||
@@ -759,8 +766,9 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
else
|
||||
put_ebml_void(pb, MAX_PCE_SIZE + 2 + 4);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (par->codec_id == AV_CODEC_ID_PRORES &&
|
||||
if (CONFIG_MATROSKA_MUXER && par->codec_id == AV_CODEC_ID_PRORES &&
|
||||
ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == AV_CODEC_ID_PRORES) {
|
||||
avio_wl32(dyn_cp, par->codec_tag);
|
||||
} else if (par->extradata_size && par->codec_id != AV_CODEC_ID_TTA)
|
||||
@@ -774,8 +782,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
AVCodecParameters *par,
|
||||
int native_id, int qt_id)
|
||||
{
|
||||
MatroskaMuxContext av_unused *const mkv = s->priv_data;
|
||||
AVIOContext *dyn_cp;
|
||||
MatroskaMuxContext *mkv = s->priv_data;
|
||||
uint8_t *codecpriv;
|
||||
int ret, codecpriv_size;
|
||||
|
||||
@@ -785,6 +793,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
|
||||
if (native_id) {
|
||||
ret = mkv_write_native_codecprivate(s, pb, par, dyn_cp);
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
} else if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
if (qt_id) {
|
||||
if (!par->codec_tag)
|
||||
@@ -826,6 +835,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
|
||||
par->codec_tag = tag;
|
||||
|
||||
ff_put_wav_header(s, dyn_cp, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
@@ -991,7 +1001,7 @@ static void mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb,
|
||||
end_ebml_master(pb, projection);
|
||||
}
|
||||
|
||||
static void mkv_write_field_order(AVIOContext *pb, int mode,
|
||||
static void mkv_write_field_order(AVIOContext *pb, int is_webm,
|
||||
enum AVFieldOrder field_order)
|
||||
{
|
||||
switch (field_order) {
|
||||
@@ -1007,7 +1017,7 @@ static void mkv_write_field_order(AVIOContext *pb, int mode,
|
||||
case AV_FIELD_BT:
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEOFLAGINTERLACED,
|
||||
MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED);
|
||||
if (mode != MODE_WEBM) {
|
||||
if (!is_webm) {
|
||||
switch (field_order) {
|
||||
case AV_FIELD_TT:
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEOFIELDORDER,
|
||||
@@ -1031,7 +1041,8 @@ static void mkv_write_field_order(AVIOContext *pb, int mode,
|
||||
}
|
||||
|
||||
static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
|
||||
AVStream *st, int mode, int *h_width, int *h_height)
|
||||
AVStream *st, int is_webm,
|
||||
int *h_width, int *h_height)
|
||||
{
|
||||
const AVDictionaryEntry *tag;
|
||||
MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
|
||||
@@ -1106,7 +1117,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
|
||||
return 0;
|
||||
|
||||
// if webm, do not write unsupported modes
|
||||
if ((mode == MODE_WEBM &&
|
||||
if ((is_webm &&
|
||||
format > MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM &&
|
||||
format != MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT)
|
||||
|| format >= MATROSKA_VIDEO_STEREOMODE_TYPE_NB) {
|
||||
@@ -1123,6 +1134,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
|
||||
|
||||
static void mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st)
|
||||
{
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)
|
||||
av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL);
|
||||
|
||||
@@ -1150,6 +1162,7 @@ static void mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st)
|
||||
|
||||
end_ebml_master(pb, mapping);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
@@ -1171,13 +1184,6 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
if (par->codec_type == AVMEDIA_TYPE_ATTACHMENT)
|
||||
return 0;
|
||||
|
||||
if (par->codec_id == AV_CODEC_ID_AAC) {
|
||||
ret = get_aac_sample_rates(s, mkv, par->extradata, par->extradata_size,
|
||||
&sample_rate, &output_sample_rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
track_master = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0);
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKNUMBER, track->track_num);
|
||||
put_ebml_uid (pb, MATROSKA_ID_TRACKUID, track->uid);
|
||||
@@ -1197,7 +1203,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
if (st->disposition & AV_DISPOSITION_FORCED)
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1);
|
||||
|
||||
if (mkv->mode == MODE_WEBM) {
|
||||
if (IS_WEBM(mkv)) {
|
||||
const char *codec_id;
|
||||
if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) {
|
||||
for (j = 0; ff_webm_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
|
||||
@@ -1276,7 +1282,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
&& av_cmp_q(av_inv_q(st->r_frame_rate), st->time_base) > 0)
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, 1000000000LL * st->r_frame_rate.den / st->r_frame_rate.num);
|
||||
|
||||
if (!native_id &&
|
||||
if (CONFIG_MATROSKA_MUXER && !native_id &&
|
||||
ff_codec_get_tag(ff_codec_movvideo_tags, par->codec_id) &&
|
||||
((!ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id) && par->codec_id != AV_CODEC_ID_RAWVIDEO) ||
|
||||
par->codec_id == AV_CODEC_ID_SVQ1 ||
|
||||
@@ -1298,11 +1304,11 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , par->width);
|
||||
put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, par->height);
|
||||
|
||||
mkv_write_field_order(pb, mkv->mode, par->field_order);
|
||||
mkv_write_field_order(pb, IS_WEBM(mkv), par->field_order);
|
||||
|
||||
// check both side data and metadata for stereo information,
|
||||
// write the result to the bitstream if any is found
|
||||
ret = mkv_write_stereo_mode(s, pb, st, mkv->mode,
|
||||
ret = mkv_write_stereo_mode(s, pb, st, IS_WEBM(mkv),
|
||||
&display_width_div,
|
||||
&display_height_div);
|
||||
if (ret < 0)
|
||||
@@ -1323,7 +1329,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (d_width != par->width || display_width_div != 1 || display_height_div != 1) {
|
||||
if (mkv->mode == MODE_WEBM || display_width_div != 1 || display_height_div != 1) {
|
||||
if (IS_WEBM(mkv) || display_width_div != 1 || display_height_div != 1) {
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width / display_width_div);
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, par->height / display_height_div);
|
||||
} else {
|
||||
@@ -1340,7 +1346,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
} else if (display_width_div != 1 || display_height_div != 1) {
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , par->width / display_width_div);
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, par->height / display_height_div);
|
||||
} else if (mkv->mode != MODE_WEBM)
|
||||
} else if (!IS_WEBM(mkv))
|
||||
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYUNIT, MATROSKA_VIDEO_DISPLAYUNIT_UNKNOWN);
|
||||
|
||||
if (par->codec_id == AV_CODEC_ID_RAWVIDEO) {
|
||||
@@ -1352,9 +1358,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
|
||||
end_ebml_master(pb, subinfo);
|
||||
|
||||
if (mkv->mode != MODE_WEBM) {
|
||||
if (!IS_WEBM(mkv))
|
||||
mkv_write_dovi(s, pb, st);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -1375,6 +1380,14 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
}
|
||||
if (par->codec_id == AV_CODEC_ID_OPUS)
|
||||
put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL);
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
else if (par->codec_id == AV_CODEC_ID_AAC) {
|
||||
ret = get_aac_sample_rates(s, mkv, par->extradata, par->extradata_size,
|
||||
&sample_rate, &output_sample_rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO);
|
||||
|
||||
@@ -1409,10 +1422,10 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
av_log(s, AV_LOG_ERROR, "Subtitle codec %d is not supported.\n", par->codec_id);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
if (mkv->mode != MODE_WEBM && st->disposition & AV_DISPOSITION_DESCRIPTIONS)
|
||||
if (!IS_WEBM(mkv) && st->disposition & AV_DISPOSITION_DESCRIPTIONS)
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGTEXTDESCRIPTIONS, 1);
|
||||
|
||||
if (mkv->mode != MODE_WEBM || par->codec_id != AV_CODEC_ID_WEBVTT)
|
||||
if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT)
|
||||
native_id = MATROSKA_TRACK_TYPE_SUBTITLE;
|
||||
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, native_id);
|
||||
@@ -1422,7 +1435,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (mkv->mode != MODE_WEBM || par->codec_id != AV_CODEC_ID_WEBVTT) {
|
||||
if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT) {
|
||||
track->codecpriv_offset = avio_tell(pb);
|
||||
ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id);
|
||||
if (ret < 0)
|
||||
@@ -1641,7 +1654,7 @@ static int mkv_write_tags(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (mkv->nb_attachments && mkv->mode != MODE_WEBM) {
|
||||
if (mkv->nb_attachments && !IS_WEBM(mkv)) {
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
const mkv_track *track = &mkv->tracks[i];
|
||||
const AVStream *st = s->streams[i];
|
||||
@@ -1694,7 +1707,7 @@ static int mkv_write_chapters(AVFormatContext *s)
|
||||
return ret;
|
||||
|
||||
editionentry = start_ebml_master(dyn_cp, MATROSKA_ID_EDITIONENTRY, 0);
|
||||
if (mkv->mode != MODE_WEBM) {
|
||||
if (!IS_WEBM(mkv)) {
|
||||
put_ebml_uint(dyn_cp, MATROSKA_ID_EDITIONFLAGDEFAULT, 1);
|
||||
/* If mkv_write_tags() has already been called, then any tags
|
||||
* corresponding to chapters will be put into a new Tags element. */
|
||||
@@ -1854,7 +1867,7 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
int ret, i, version = 2;
|
||||
int64_t creation_time;
|
||||
|
||||
if (mkv->mode != MODE_WEBM ||
|
||||
if (!IS_WEBM(mkv) ||
|
||||
av_dict_get(s->metadata, "stereo_mode", NULL, 0) ||
|
||||
av_dict_get(s->metadata, "alpha_mode", NULL, 0))
|
||||
version = 4;
|
||||
@@ -1899,7 +1912,7 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
else
|
||||
put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT);
|
||||
|
||||
if (mkv->mode != MODE_WEBM)
|
||||
if (!IS_WEBM(mkv))
|
||||
put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, mkv->segment_uid, 16);
|
||||
} else {
|
||||
const char *ident = "Lavf";
|
||||
@@ -1947,7 +1960,7 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (mkv->mode != MODE_WEBM) {
|
||||
if (!IS_WEBM(mkv)) {
|
||||
ret = mkv_write_attachments(s);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -2009,6 +2022,7 @@ static int mkv_blockgroup_size(int pkt_size, int track_num_size)
|
||||
return size;
|
||||
}
|
||||
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
static int mkv_strip_wavpack(const uint8_t *src, uint8_t **pdst, int *size)
|
||||
{
|
||||
uint8_t *dst;
|
||||
@@ -2061,6 +2075,7 @@ fail:
|
||||
av_freep(&dst);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
||||
uint32_t blockid, const AVPacket *pkt, int keyframe)
|
||||
@@ -2088,6 +2103,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
||||
pkt->size, pkt->pts, pkt->dts, pkt->duration, avio_tell(pb),
|
||||
mkv->cluster_pos, track_number, keyframe != 0);
|
||||
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 0 &&
|
||||
(AV_RB24(par->extradata) == 1 || AV_RB32(par->extradata) == 1)) {
|
||||
err = ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
|
||||
@@ -2095,11 +2111,13 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
||||
(AV_RB24(par->extradata) == 1 || AV_RB32(par->extradata) == 1)) {
|
||||
/* extradata is Annex B, assume the bitstream is too and convert it */
|
||||
err = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL);
|
||||
} else if (par->codec_id == AV_CODEC_ID_AV1) {
|
||||
err = ff_av1_filter_obus_buf(pkt->data, &data, &size, &offset);
|
||||
} else if (par->codec_id == AV_CODEC_ID_WAVPACK) {
|
||||
err = mkv_strip_wavpack(pkt->data, &data, &size);
|
||||
} else
|
||||
#endif
|
||||
if (par->codec_id == AV_CODEC_ID_AV1) {
|
||||
err = ff_av1_filter_obus_buf(pkt->data, &data, &size, &offset);
|
||||
} else
|
||||
data = pkt->data;
|
||||
|
||||
if (err < 0) {
|
||||
@@ -2108,7 +2126,8 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (par->codec_id == AV_CODEC_ID_PRORES && size >= 8) {
|
||||
if (CONFIG_MATROSKA_MUXER &&
|
||||
par->codec_id == AV_CODEC_ID_PRORES && size >= 8) {
|
||||
/* Matroska specification requires to remove the first QuickTime atom
|
||||
*/
|
||||
size -= 8;
|
||||
@@ -2260,6 +2279,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
||||
&side_data_size);
|
||||
|
||||
switch (par->codec_id) {
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
case AV_CODEC_ID_AAC:
|
||||
if (side_data_size && mkv->track.bc) {
|
||||
int filler, output_sample_rate = 0;
|
||||
@@ -2301,6 +2321,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
||||
par->extradata = old_extradata;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
// FIXME: Remove the following once libaom starts propagating extradata during init()
|
||||
// See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012
|
||||
case AV_CODEC_ID_AV1:
|
||||
@@ -2720,7 +2741,8 @@ static int mkv_init(struct AVFormatContext *s)
|
||||
si->avoid_negative_ts_use_pts = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(s->oformat->name, "webm")) {
|
||||
if (!CONFIG_MATROSKA_MUXER ||
|
||||
(CONFIG_WEBM_MUXER && !strcmp(s->oformat->name, "webm"))) {
|
||||
mkv->mode = MODE_WEBM;
|
||||
mkv->write_crc = 0;
|
||||
} else
|
||||
@@ -2754,7 +2776,7 @@ static int mkv_init(struct AVFormatContext *s)
|
||||
avpriv_set_pts_info(st, 64, 1, 1000);
|
||||
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
|
||||
if (mkv->mode == MODE_WEBM) {
|
||||
if (IS_WEBM(mkv)) {
|
||||
av_log(s, AV_LOG_WARNING, "Stream %d will be ignored "
|
||||
"as WebM doesn't support attachments.\n", i);
|
||||
} else if (!get_mimetype(st)) {
|
||||
@@ -2782,7 +2804,7 @@ static int mkv_check_bitstream(AVFormatContext *s, AVStream *st,
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
|
||||
if (CONFIG_MATROSKA_MUXER && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
|
||||
if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
|
||||
ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
|
||||
} else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
|
||||
|
||||
@@ -5118,6 +5118,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
avio_rb16(pb); // reserved
|
||||
|
||||
item_count = avio_rb16(pb);
|
||||
if (item_count == 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
for (i = 0; i < item_count; i++) {
|
||||
int index;
|
||||
@@ -6105,6 +6107,8 @@ static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
}
|
||||
if (pb->eof_reached) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
|
||||
if (ret >= 0)
|
||||
av_encryption_info_free(encryption_index->encrypted_samples[i]);
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
@@ -7329,6 +7333,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
if (a.size == 0) {
|
||||
a.size = atom.size - total_size + 8;
|
||||
}
|
||||
if (a.size < 0)
|
||||
break;
|
||||
a.size -= 8;
|
||||
if (a.size < 0)
|
||||
break;
|
||||
|
||||
@@ -2960,7 +2960,7 @@ static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
|
||||
static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov,
|
||||
MOVTrack *track)
|
||||
{
|
||||
int64_t duration = calc_pts_duration(mov, track);
|
||||
int64_t duration = calc_samples_pts_duration(mov, track);
|
||||
int version = duration < INT32_MAX ? 0 : 1;
|
||||
|
||||
if (track->mode == MODE_ISM)
|
||||
|
||||
@@ -50,6 +50,9 @@ enum MXFMetadataSetType {
|
||||
TaggedValue,
|
||||
TapeDescriptor,
|
||||
AVCSubDescriptor,
|
||||
AudioChannelLabelSubDescriptor,
|
||||
SoundfieldGroupLabelSubDescriptor,
|
||||
GroupOfSoundfieldGroupsLabelSubDescriptor,
|
||||
};
|
||||
|
||||
enum MXFFrameLayout {
|
||||
|
||||
+297
-9
@@ -51,11 +51,14 @@
|
||||
#include "libavutil/mastering_display_metadata.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavcodec/bytestream.h"
|
||||
#include "libavcodec/internal.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/timecode.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "avformat.h"
|
||||
#include "avlanguage.h"
|
||||
#include "internal.h"
|
||||
#include "mxf.h"
|
||||
|
||||
@@ -177,6 +180,8 @@ typedef struct {
|
||||
int body_sid;
|
||||
MXFWrappingScheme wrapping;
|
||||
int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */
|
||||
int require_reordering;
|
||||
int channel_ordering[FF_SANE_NB_CHANNELS];
|
||||
} MXFTrack;
|
||||
|
||||
typedef struct MXFDescriptor {
|
||||
@@ -205,6 +210,8 @@ typedef struct MXFDescriptor {
|
||||
unsigned int vert_subsampling;
|
||||
UID *file_descriptors_refs;
|
||||
int file_descriptors_count;
|
||||
UID *sub_descriptors_refs;
|
||||
int sub_descriptors_count;
|
||||
int linked_track_id;
|
||||
uint8_t *extradata;
|
||||
int extradata_size;
|
||||
@@ -217,6 +224,18 @@ typedef struct MXFDescriptor {
|
||||
size_t coll_size;
|
||||
} MXFDescriptor;
|
||||
|
||||
typedef struct MXFMCASubDescriptor {
|
||||
MXFMetadataSet meta;
|
||||
UID uid;
|
||||
UID mca_link_id;
|
||||
UID soundfield_group_link_id;
|
||||
UID *group_of_soundfield_groups_link_id_refs;
|
||||
int group_of_soundfield_groups_link_id_count;
|
||||
UID mca_label_dictionary_id;
|
||||
int mca_channel_id;
|
||||
char *language;
|
||||
} MXFMCASubDescriptor;
|
||||
|
||||
typedef struct MXFIndexTableSegment {
|
||||
MXFMetadataSet meta;
|
||||
int edit_unit_byte_count;
|
||||
@@ -311,6 +330,7 @@ static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x
|
||||
static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
|
||||
static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 };
|
||||
static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 };
|
||||
|
||||
/* complete keys to match */
|
||||
static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
|
||||
@@ -323,6 +343,17 @@ static const uint8_t mxf_indirect_value_utf16be[] = { 0x42,0x01,0x10,0x
|
||||
static const uint8_t mxf_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 };
|
||||
static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 };
|
||||
|
||||
static const uint8_t mxf_mca_label_dictionary_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x01,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_mca_tag_symbol[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x02,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_mca_tag_name[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x03,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_group_of_soundfield_groups_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x04,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_mca_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x05,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_mca_channel_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x04,0x0a,0x00,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_soundfield_group_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x06,0x00,0x00,0x00 };
|
||||
static const uint8_t mxf_mca_rfc5646_spoken_language[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x03,0x01,0x01,0x02,0x03,0x15,0x00,0x00 };
|
||||
|
||||
static const uint8_t mxf_sub_descriptor[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00 };
|
||||
|
||||
static const uint8_t mxf_mastering_display_prefix[13] = { FF_MXF_MasteringDisplay_PREFIX };
|
||||
static const uint8_t mxf_mastering_display_uls[4][16] = {
|
||||
FF_MXF_MasteringDisplayPrimaries,
|
||||
@@ -343,6 +374,13 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
|
||||
av_freep(&((MXFDescriptor *)*ctx)->mastering);
|
||||
av_freep(&((MXFDescriptor *)*ctx)->coll);
|
||||
av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs);
|
||||
av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
|
||||
break;
|
||||
case AudioChannelLabelSubDescriptor:
|
||||
case SoundfieldGroupLabelSubDescriptor:
|
||||
case GroupOfSoundfieldGroupsLabelSubDescriptor:
|
||||
av_freep(&((MXFMCASubDescriptor *)*ctx)->language);
|
||||
av_freep(&((MXFMCASubDescriptor *)*ctx)->group_of_soundfield_groups_link_id_refs);
|
||||
break;
|
||||
case Sequence:
|
||||
av_freep(&((MXFSequence *)*ctx)->structural_components_refs);
|
||||
@@ -894,18 +932,54 @@ static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, i
|
||||
|
||||
static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
|
||||
{
|
||||
*count = avio_rb32(pb);
|
||||
int64_t ret;
|
||||
unsigned c = avio_rb32(pb);
|
||||
|
||||
//avio_read() used int
|
||||
if (c > INT_MAX / sizeof(UID))
|
||||
return AVERROR_PATCHWELCOME;
|
||||
*count = c;
|
||||
|
||||
av_free(*refs);
|
||||
*refs = av_calloc(*count, sizeof(UID));
|
||||
*refs = av_malloc_array(*count, sizeof(UID));
|
||||
if (!*refs) {
|
||||
*count = 0;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
|
||||
avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID));
|
||||
ret = avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID));
|
||||
if (ret != *count * sizeof(UID)) {
|
||||
*count = ret < 0 ? 0 : ret / sizeof(UID);
|
||||
return ret < 0 ? ret : AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str)
|
||||
{
|
||||
int ret;
|
||||
size_t buf_size;
|
||||
|
||||
if (size < 0 || size > INT_MAX - 1)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
buf_size = size + 1;
|
||||
av_free(*str);
|
||||
*str = av_malloc(buf_size);
|
||||
if (!*str)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = avio_get_str(pb, size, *str, buf_size);
|
||||
|
||||
if (ret < 0) {
|
||||
av_freep(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be)
|
||||
{
|
||||
int ret;
|
||||
@@ -1363,11 +1437,40 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
|
||||
descriptor->coll->MaxFALL = avio_rb16(pb);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_sub_descriptor))
|
||||
return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count);
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
|
||||
{
|
||||
MXFMCASubDescriptor *mca_sub_descriptor = arg;
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_mca_label_dictionary_id))
|
||||
avio_read(pb, mca_sub_descriptor->mca_label_dictionary_id, 16);
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_mca_link_id))
|
||||
avio_read(pb, mca_sub_descriptor->mca_link_id, 16);
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_soundfield_group_link_id))
|
||||
avio_read(pb, mca_sub_descriptor->soundfield_group_link_id, 16);
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_group_of_soundfield_groups_link_id))
|
||||
return mxf_read_strong_ref_array(pb, &mca_sub_descriptor->group_of_soundfield_groups_link_id_refs, &mca_sub_descriptor->group_of_soundfield_groups_link_id_count);
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_mca_channel_id))
|
||||
mca_sub_descriptor->mca_channel_id = avio_rb32(pb);
|
||||
|
||||
if (IS_KLV_KEY(uid, mxf_mca_rfc5646_spoken_language))
|
||||
return mxf_read_us_ascii_string(pb, size, &mca_sub_descriptor->language);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size)
|
||||
{
|
||||
MXFTaggedValue *tagged_value = arg;
|
||||
@@ -1497,6 +1600,52 @@ static const MXFCodecUL mxf_data_essence_container_uls[] = {
|
||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
|
||||
};
|
||||
|
||||
typedef struct MXFChannelOrderingUL {
|
||||
UID uid;
|
||||
uint64_t layout_mask;
|
||||
enum AVAudioServiceType service_type;
|
||||
} MXFChannelOrderingUL;
|
||||
|
||||
static const MXFChannelOrderingUL mxf_channel_ordering[] = {
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x03,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x04,0x00,0x00,0x00,0x00 }, AV_CH_LOW_FREQUENCY, AV_AUDIO_SERVICE_TYPE_MAIN }, // Low Frequency Effects
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x05,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x06,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x07,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x08,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x09,0x00,0x00,0x00,0x00 }, AV_CH_BACK_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0a,0x00,0x00,0x00,0x00 }, AV_CH_BACK_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0b,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Center
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0c,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Center
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0d,0x00,0x00,0x00,0x00 }, AV_CH_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0e,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, // Hearing impaired audio channel
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0f,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, // Visually impaired narrative audio channel
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x20,0x03,0x00,0x00,0x00 }, AV_CH_STEREO_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Total
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x20,0x04,0x00,0x00,0x00 }, AV_CH_STEREO_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Total
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x01,0x00,0x00 }, AV_CH_TOP_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x02,0x00,0x00 }, AV_CH_TOP_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x03,0x00,0x00 }, AV_CH_TOP_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x04,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x05,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x06,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x07,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x08,0x00,0x00 }, AV_CH_TOP_BACK_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x09,0x00,0x00 }, AV_CH_TOP_BACK_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0a,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Top Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0b,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Top Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0c,0x00,0x00 }, AV_CH_TOP_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Top Surround
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0d,0x00,0x00 }, AV_CH_LOW_FREQUENCY, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Front Subwoofer
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0e,0x00,0x00 }, AV_CH_LOW_FREQUENCY_2, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Front Subwoofer
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0f,0x00,0x00 }, AV_CH_TOP_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear Height
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x10,0x00,0x00 }, AV_CH_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x11,0x00,0x00 }, AV_CH_BOTTOM_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Below
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x12,0x00,0x00 }, AV_CH_BOTTOM_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Below
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x13,0x00,0x00 }, AV_CH_BOTTOM_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Below
|
||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_NB },
|
||||
};
|
||||
|
||||
static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul)
|
||||
{
|
||||
int val;
|
||||
@@ -2295,6 +2444,139 @@ static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *des
|
||||
return AVCOL_RANGE_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static int is_pcm(enum AVCodecID codec_id)
|
||||
{
|
||||
/* we only care about "normal" PCM codecs until we get samples */
|
||||
return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
|
||||
}
|
||||
|
||||
static int set_language(AVFormatContext *s, const char *rfc5646, AVDictionary **met)
|
||||
{
|
||||
// language abbr should contain at least 2 chars
|
||||
if (rfc5646 && strlen(rfc5646) > 1) {
|
||||
char primary_tag[4] =
|
||||
{rfc5646[0], rfc5646[1], rfc5646[2] != '-' ? rfc5646[2] : '\0', '\0'};
|
||||
|
||||
const char *iso6392 = ff_convert_lang_to(primary_tag,
|
||||
AV_LANG_ISO639_2_BIBL);
|
||||
if (iso6392)
|
||||
return(av_dict_set(met, "language", iso6392, 0));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MXFMCASubDescriptor *find_mca_link_id(MXFContext *mxf, enum MXFMetadataSetType type, UID *mca_link_id)
|
||||
{
|
||||
for (int k = 0; k < mxf->metadata_sets_count; k++) {
|
||||
MXFMCASubDescriptor *group = (MXFMCASubDescriptor*)mxf->metadata_sets[k];
|
||||
if (group->meta.type == type && !memcmp(&group->mca_link_id, mca_link_id, 16))
|
||||
return group;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int parse_mca_labels(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st)
|
||||
{
|
||||
uint64_t routing[FF_SANE_NB_CHANNELS] = {0};
|
||||
char *language = NULL;
|
||||
int ambigous_language = 0;
|
||||
enum AVAudioServiceType service_type = AV_AUDIO_SERVICE_TYPE_NB;
|
||||
int ambigous_service_type = 0;
|
||||
int has_channel_label = 0;
|
||||
|
||||
for (int i = 0; i < descriptor->sub_descriptors_count; i++) {
|
||||
char *channel_language;
|
||||
|
||||
MXFMCASubDescriptor *label = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], AudioChannelLabelSubDescriptor);
|
||||
if (label == NULL)
|
||||
continue;
|
||||
|
||||
has_channel_label = 1;
|
||||
for (const MXFChannelOrderingUL* channel_ordering = mxf_channel_ordering; channel_ordering->uid[0]; channel_ordering++) {
|
||||
if (IS_KLV_KEY(channel_ordering->uid, label->mca_label_dictionary_id)) {
|
||||
int target_channel = label->mca_channel_id;
|
||||
if (target_channel == 0 && descriptor->channels == 1)
|
||||
target_channel = 1;
|
||||
if (target_channel <= 0 || target_channel > descriptor->channels) {
|
||||
av_log(mxf->fc, AV_LOG_ERROR, "AudioChannelLabelSubDescriptor has invalid MCA channel ID %d\n", target_channel);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
routing[target_channel - 1] = channel_ordering->layout_mask;
|
||||
if (service_type == AV_AUDIO_SERVICE_TYPE_NB)
|
||||
service_type = channel_ordering->service_type;
|
||||
else if (service_type != channel_ordering->service_type)
|
||||
ambigous_service_type = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
channel_language = label->language;
|
||||
if (!channel_language) {
|
||||
MXFMCASubDescriptor *group = find_mca_link_id(mxf, SoundfieldGroupLabelSubDescriptor, &label->soundfield_group_link_id);
|
||||
if (group) {
|
||||
channel_language = group->language;
|
||||
if (!channel_language && group->group_of_soundfield_groups_link_id_count) {
|
||||
MXFMCASubDescriptor *supergroup = find_mca_link_id(mxf, GroupOfSoundfieldGroupsLabelSubDescriptor,
|
||||
group->group_of_soundfield_groups_link_id_refs);
|
||||
if (supergroup)
|
||||
channel_language = supergroup->language;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel_language) {
|
||||
if (language && strcmp(language, channel_language))
|
||||
ambigous_language = 1;
|
||||
else
|
||||
language = channel_language;
|
||||
}
|
||||
}
|
||||
|
||||
if (language && !ambigous_language) {
|
||||
int ret = set_language(mxf->fc, language, &st->metadata);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (service_type != AV_AUDIO_SERVICE_TYPE_NB && service_type != AV_AUDIO_SERVICE_TYPE_MAIN && !ambigous_service_type) {
|
||||
enum AVAudioServiceType *ast;
|
||||
uint8_t* side_data = av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE, sizeof(*ast));
|
||||
if (!side_data)
|
||||
return AVERROR(ENOMEM);
|
||||
ast = (enum AVAudioServiceType*)side_data;
|
||||
*ast = service_type;
|
||||
}
|
||||
|
||||
if (has_channel_label) {
|
||||
uint64_t channel_layout = 0;
|
||||
|
||||
for (int i = 0; i < descriptor->channels; i++) {
|
||||
if (!routing[i]) {
|
||||
av_log(mxf->fc, AV_LOG_WARNING, "Designation of audio channel %d in stream #%d is unknown or unsupported, "
|
||||
"falling back to unknown channel layout\n", st->index, i);
|
||||
return 0;
|
||||
}
|
||||
if (channel_layout & routing[i]) {
|
||||
av_log(mxf->fc, AV_LOG_WARNING, "%s audio channel is used multiple times in stream #%d, "
|
||||
"falling back to unknown channel layout\n",
|
||||
av_get_channel_name(routing[i]), st->index);
|
||||
return 0;
|
||||
}
|
||||
if (routing[i] < channel_layout) {
|
||||
av_log(mxf->fc, AV_LOG_WARNING, "stream #%d is not in in native channel order, "
|
||||
"falling back to unknown channel layout\n", st->index);
|
||||
return 0;
|
||||
}
|
||||
channel_layout |= routing[i];
|
||||
}
|
||||
|
||||
av_assert0(descriptor->channels == av_get_channel_layout_nb_channels(channel_layout));
|
||||
|
||||
st->codecpar->channel_layout = channel_layout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_parse_structural_metadata(MXFContext *mxf)
|
||||
{
|
||||
MXFPackage *material_package = NULL;
|
||||
@@ -2691,6 +2973,15 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
|
||||
sti->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
}
|
||||
st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
|
||||
|
||||
if (descriptor->channels <= 0 || descriptor->channels >= FF_SANE_NB_CHANNELS) {
|
||||
av_log(mxf->fc, AV_LOG_ERROR, "Invalid number of channels %d, must be less than %d\n", descriptor->channels, FF_SANE_NB_CHANNELS);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ret = parse_mca_labels(mxf, source_track, descriptor, st);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
|
||||
enum AVMediaType type;
|
||||
container_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
|
||||
@@ -2891,6 +3182,9 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* VANC/VBI - SMPTE 436M */
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2AudioDescriptor */
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x64,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* DC Timed Text Descriptor */
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6b,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), AudioChannelLabelSubDescriptor },
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6c,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), SoundfieldGroupLabelSubDescriptor },
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6d,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor },
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
|
||||
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
|
||||
@@ -3190,12 +3484,6 @@ static void mxf_compute_essence_containers(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
static int is_pcm(enum AVCodecID codec_id)
|
||||
{
|
||||
/* we only care about "normal" PCM codecs until we get samples */
|
||||
return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
|
||||
}
|
||||
|
||||
static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -40,6 +40,7 @@ static int rawvideo_read_header(AVFormatContext *ctx)
|
||||
enum AVPixelFormat pix_fmt;
|
||||
AVStream *st;
|
||||
int packet_size;
|
||||
int ret;
|
||||
|
||||
st = avformat_new_stream(ctx, NULL);
|
||||
if (!st)
|
||||
@@ -57,6 +58,10 @@ static int rawvideo_read_header(AVFormatContext *ctx)
|
||||
|
||||
avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num);
|
||||
|
||||
ret = av_image_check_size(s->width, s->height, 0, ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
st->codecpar->width = s->width;
|
||||
st->codecpar->height = s->height;
|
||||
|
||||
@@ -89,6 +94,8 @@ static int rawvideo_read_header(AVFormatContext *ctx)
|
||||
if (packet_size < 0)
|
||||
return packet_size;
|
||||
}
|
||||
if (packet_size == 0)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
st->codecpar->format = pix_fmt;
|
||||
ctx->packet_size = packet_size;
|
||||
|
||||
+5
-4
@@ -127,10 +127,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
|
||||
uint32_t version;
|
||||
int ret;
|
||||
|
||||
// Duplicate tags
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* ra type header */
|
||||
version = avio_rb16(pb); /* version */
|
||||
if (version == 3) {
|
||||
@@ -330,6 +326,11 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
|
||||
if (codec_data_size == 0)
|
||||
return 0;
|
||||
|
||||
// Duplicate tags
|
||||
if ( st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN
|
||||
&& st->codecpar->codec_type != AVMEDIA_TYPE_DATA)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
avpriv_set_pts_info(st, 64, 1, 1000);
|
||||
codec_pos = avio_tell(pb);
|
||||
v = avio_rb32(pb);
|
||||
|
||||
@@ -246,6 +246,7 @@ static void finalize_rtp_handler_init(AVFormatContext *s, RTSPStream *rtsp_st,
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_RTSP_DEMUXER
|
||||
static int init_satip_stream(AVFormatContext *s)
|
||||
{
|
||||
RTSPState *rt = s->priv_data;
|
||||
@@ -274,6 +275,7 @@ static int init_satip_stream(AVFormatContext *s)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
|
||||
static int sdp_parse_rtpmap(AVFormatContext *s,
|
||||
@@ -2006,6 +2008,7 @@ redirect:
|
||||
#endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
|
||||
|
||||
#if CONFIG_RTPDEC
|
||||
#if CONFIG_RTSP_DEMUXER
|
||||
static int parse_rtsp_message(AVFormatContext *s)
|
||||
{
|
||||
RTSPState *rt = s->priv_data;
|
||||
@@ -2028,6 +2031,7 @@ static int parse_rtsp_message(AVFormatContext *s)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
|
||||
uint8_t *buf, int buf_size, int64_t wait_end)
|
||||
|
||||
+6
-2
@@ -739,8 +739,10 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
/* XXX: fix av_url_split */
|
||||
if (hostname[0] == '\0' || hostname[0] == '?') {
|
||||
/* only accepts null hostname if input */
|
||||
if (!(flags & AVIO_FLAG_READ))
|
||||
if (!(flags & AVIO_FLAG_READ)) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if ((ret = ff_udp_set_remote_url(h, uri)) < 0)
|
||||
goto fail;
|
||||
@@ -750,8 +752,10 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
s->local_port = port;
|
||||
|
||||
udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr);
|
||||
if (udp_fd < 0)
|
||||
if (udp_fd < 0) {
|
||||
ret = AVERROR(EIO);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s->local_addr_storage=my_addr; //store for future multicast join
|
||||
|
||||
|
||||
+3
-2
@@ -895,10 +895,11 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_ba
|
||||
if (!s->nb_chapters) {
|
||||
si->chapter_ids_monotonic = 1;
|
||||
} else if (!si->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) {
|
||||
si->chapter_ids_monotonic = 0;
|
||||
for (unsigned i = 0; i < s->nb_chapters; i++)
|
||||
if (s->chapters[i]->id == id)
|
||||
chapter = s->chapters[i];
|
||||
if (!chapter)
|
||||
si->chapter_ids_monotonic = 0;
|
||||
}
|
||||
|
||||
if (!chapter) {
|
||||
@@ -1243,7 +1244,7 @@ void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
|
||||
key_len = ptr - key;
|
||||
|
||||
callback_get_buf(context, key, key_len, &dest, &dest_len);
|
||||
dest_end = dest + dest_len - 1;
|
||||
dest_end = dest ? dest + dest_len - 1 : NULL;
|
||||
|
||||
if (*ptr == '\"') {
|
||||
ptr++;
|
||||
|
||||
@@ -1872,12 +1872,14 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
|
||||
|
||||
f->size[0] = cont_memory_requirements.size;
|
||||
|
||||
for (int i = 0; i < planes; i++) {
|
||||
bind_info[i].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
|
||||
bind_info[i].image = f->img[i];
|
||||
bind_info[i].memory = f->mem[0];
|
||||
bind_info[i].memoryOffset = !i ? 0 : cont_mem_size_list[i - 1];
|
||||
for (int i = 0, offset = 0; i < planes; i++) {
|
||||
bind_info[i].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
|
||||
bind_info[i].image = f->img[i];
|
||||
bind_info[i].memory = f->mem[0];
|
||||
bind_info[i].memoryOffset = offset;
|
||||
|
||||
f->offset[i] = bind_info[i].memoryOffset;
|
||||
offset += cont_mem_size_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ static const VideoSizeAbbr video_size_abbrs[] = {
|
||||
{ "hd480", 852, 480 },
|
||||
{ "hd720", 1280, 720 },
|
||||
{ "hd1080", 1920,1080 },
|
||||
{ "qhd", 2560,1440 },
|
||||
{ "quadhd", 2560,1440 },
|
||||
{ "2k", 2048,1080 }, /* Digital Cinema System Specification */
|
||||
{ "2kdci", 2048,1080 },
|
||||
{ "2kflat", 1998,1080 },
|
||||
|
||||
+46
-17
@@ -180,17 +180,18 @@ yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
|
||||
}
|
||||
}
|
||||
|
||||
static void yuv2p016cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
static av_always_inline void
|
||||
yuv2nv12cX_16_c_template(int big_endian, const uint8_t *chrDither,
|
||||
const int16_t *chrFilter, int chrFilterSize,
|
||||
const int16_t **chrUSrc, const int16_t **chrVSrc,
|
||||
uint8_t *dest8, int chrDstW)
|
||||
uint8_t *dest8, int chrDstW, int output_bits)
|
||||
{
|
||||
uint16_t *dest = (uint16_t*)dest8;
|
||||
const int32_t **uSrc = (const int32_t **)chrUSrc;
|
||||
const int32_t **vSrc = (const int32_t **)chrVSrc;
|
||||
int shift = 15;
|
||||
int big_endian = dstFormat == AV_PIX_FMT_P016BE;
|
||||
int i, j;
|
||||
av_assert0(output_bits == 16);
|
||||
|
||||
for (i = 0; i < chrDstW; i++) {
|
||||
int u = 1 << (shift - 1);
|
||||
@@ -367,6 +368,7 @@ static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filter
|
||||
filterSize, (const typeX_t **) src, \
|
||||
(uint16_t *) dest, dstW, is_be, bits); \
|
||||
}
|
||||
|
||||
yuv2NBPS( 9, BE, 1, 10, int16_t)
|
||||
yuv2NBPS( 9, LE, 0, 10, int16_t)
|
||||
yuv2NBPS(10, BE, 1, 10, int16_t)
|
||||
@@ -378,6 +380,23 @@ yuv2NBPS(14, LE, 0, 10, int16_t)
|
||||
yuv2NBPS(16, BE, 1, 16, int32_t)
|
||||
yuv2NBPS(16, LE, 0, 16, int32_t)
|
||||
|
||||
|
||||
static void yuv2nv12cX_16LE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
const int16_t *chrFilter, int chrFilterSize,
|
||||
const int16_t **chrUSrc, const int16_t **chrVSrc,
|
||||
uint8_t *dest8, int chrDstW)
|
||||
{
|
||||
yuv2nv12cX_16_c_template(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW, 16);
|
||||
}
|
||||
|
||||
static void yuv2nv12cX_16BE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
const int16_t *chrFilter, int chrFilterSize,
|
||||
const int16_t **chrUSrc, const int16_t **chrVSrc,
|
||||
uint8_t *dest8, int chrDstW)
|
||||
{
|
||||
yuv2nv12cX_16_c_template(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW, 16);
|
||||
}
|
||||
|
||||
static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
|
||||
const int16_t **src, uint8_t *dest, int dstW,
|
||||
const uint8_t *dither, int offset)
|
||||
@@ -410,8 +429,7 @@ static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dstFormat == AV_PIX_FMT_NV12 ||
|
||||
dstFormat == AV_PIX_FMT_NV24)
|
||||
if (!isSwappedChroma(dstFormat))
|
||||
for (i=0; i<chrDstW; i++) {
|
||||
int u = chrDither[i & 7] << 12;
|
||||
int v = chrDither[(i + 3) & 7] << 12;
|
||||
@@ -477,14 +495,13 @@ static void yuv2p010lX_c(const int16_t *filter, int filterSize,
|
||||
}
|
||||
}
|
||||
|
||||
static void yuv2p010cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
static void yuv2p010cX_c(int big_endian, const uint8_t *chrDither,
|
||||
const int16_t *chrFilter, int chrFilterSize,
|
||||
const int16_t **chrUSrc, const int16_t **chrVSrc,
|
||||
uint8_t *dest8, int chrDstW)
|
||||
{
|
||||
uint16_t *dest = (uint16_t*)dest8;
|
||||
int shift = 17;
|
||||
int big_endian = dstFormat == AV_PIX_FMT_P010BE;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < chrDstW; i++) {
|
||||
@@ -529,6 +546,22 @@ static void yuv2p010lX_BE_c(const int16_t *filter, int filterSize,
|
||||
yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 1);
|
||||
}
|
||||
|
||||
static void yuv2p010cX_LE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
const int16_t *chrFilter, int chrFilterSize,
|
||||
const int16_t **chrUSrc, const int16_t **chrVSrc,
|
||||
uint8_t *dest8, int chrDstW)
|
||||
{
|
||||
yuv2p010cX_c(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW);
|
||||
}
|
||||
|
||||
static void yuv2p010cX_BE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
|
||||
const int16_t *chrFilter, int chrFilterSize,
|
||||
const int16_t **chrUSrc, const int16_t **chrVSrc,
|
||||
uint8_t *dest8, int chrDstW)
|
||||
{
|
||||
yuv2p010cX_c(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW);
|
||||
}
|
||||
|
||||
#undef output_pixel
|
||||
|
||||
|
||||
@@ -2563,19 +2596,16 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
|
||||
enum AVPixelFormat dstFormat = c->dstFormat;
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
|
||||
|
||||
if (dstFormat == AV_PIX_FMT_P010LE || dstFormat == AV_PIX_FMT_P010BE ||
|
||||
dstFormat == AV_PIX_FMT_P210LE || dstFormat == AV_PIX_FMT_P210BE ||
|
||||
dstFormat == AV_PIX_FMT_P410LE || dstFormat == AV_PIX_FMT_P410BE) {
|
||||
if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) {
|
||||
av_assert0(desc->comp[0].depth == 10);
|
||||
*yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c;
|
||||
*yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c;
|
||||
*yuv2nv12cX = yuv2p010cX_c;
|
||||
*yuv2nv12cX = isBE(dstFormat) ? yuv2p010cX_BE_c : yuv2p010cX_LE_c;
|
||||
} else if (is16BPS(dstFormat)) {
|
||||
*yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c : yuv2planeX_16LE_c;
|
||||
*yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c : yuv2plane1_16LE_c;
|
||||
if (dstFormat == AV_PIX_FMT_P016LE || dstFormat == AV_PIX_FMT_P016BE ||
|
||||
dstFormat == AV_PIX_FMT_P216LE || dstFormat == AV_PIX_FMT_P216BE ||
|
||||
dstFormat == AV_PIX_FMT_P416LE || dstFormat == AV_PIX_FMT_P416BE) {
|
||||
*yuv2nv12cX = yuv2p016cX_c;
|
||||
if (isSemiPlanarYUV(dstFormat)) {
|
||||
*yuv2nv12cX = isBE(dstFormat) ? yuv2nv12cX_16BE_c : yuv2nv12cX_16LE_c;
|
||||
}
|
||||
} else if (isNBPS(dstFormat)) {
|
||||
if (desc->comp[0].depth == 9) {
|
||||
@@ -2601,8 +2631,7 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
|
||||
} else {
|
||||
*yuv2plane1 = yuv2plane1_8_c;
|
||||
*yuv2planeX = yuv2planeX_8_c;
|
||||
if (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21 ||
|
||||
dstFormat == AV_PIX_FMT_NV24 || dstFormat == AV_PIX_FMT_NV42)
|
||||
if (isSemiPlanarYUV(dstFormat))
|
||||
*yuv2nv12cX = yuv2nv12cX_c;
|
||||
}
|
||||
|
||||
|
||||
@@ -892,6 +892,44 @@ static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Identity formats where the data is in the high bits, and the low bits are shifted away.
|
||||
*/
|
||||
static av_always_inline int isDataInHighBits(enum AVPixelFormat pix_fmt)
|
||||
{
|
||||
int i;
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
|
||||
av_assert0(desc);
|
||||
if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL))
|
||||
return 0;
|
||||
for (i = 0; i < desc->nb_components; i++) {
|
||||
if (!desc->comp[i].shift)
|
||||
return 0;
|
||||
if ((desc->comp[i].shift + desc->comp[i].depth) & 0x7)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Identity formats where the chroma planes are swapped (CrCb order).
|
||||
*/
|
||||
static av_always_inline int isSwappedChroma(enum AVPixelFormat pix_fmt)
|
||||
{
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
|
||||
av_assert0(desc);
|
||||
if (!isYUV(pix_fmt))
|
||||
return 0;
|
||||
if ((desc->flags & AV_PIX_FMT_FLAG_ALPHA) && desc->nb_components < 4)
|
||||
return 0;
|
||||
if (desc->nb_components < 3)
|
||||
return 0;
|
||||
if (!isPlanarYUV(pix_fmt) || isSemiPlanarYUV(pix_fmt))
|
||||
return desc->comp[1].offset > desc->comp[2].offset;
|
||||
else
|
||||
return desc->comp[1].plane > desc->comp[2].plane;
|
||||
}
|
||||
|
||||
extern const uint64_t ff_dither4[2];
|
||||
extern const uint64_t ff_dither8[2];
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ static const struct {
|
||||
{"PackedRGB", isPackedRGB},
|
||||
{"PlanarRGB", isPlanarRGB},
|
||||
{"usePal", usePal},
|
||||
{"DataInHighBits", isDataInHighBits},
|
||||
{"SwappedChroma", isSwappedChroma},
|
||||
};
|
||||
|
||||
static int cmp_str(const void *a, const void *b)
|
||||
|
||||
@@ -86,7 +86,7 @@ fate-unknown_layout-ac3: CMD = md5 -auto_conversion_filters \
|
||||
-guess_layout_max 0 -f s32le -ac 1 -ar 44100 -i $(TARGET_PATH)/$(AREF) \
|
||||
-f ac3 -flags +bitexact -c ac3_fixed
|
||||
|
||||
FATE_FFMPEG-$(call ALLYES, FILE_PROTOCOL LAVFI_INDEV RAWVIDEO_DEMUXER \
|
||||
FATE_SAMPLES_FFMPEG-$(call ALLYES, FILE_PROTOCOL LAVFI_INDEV RAWVIDEO_DEMUXER \
|
||||
SINE_FILTER PCM_S16LE_DECODER RAWVIDEO_DECODER \
|
||||
ARESAMPLE_FILTER AMIX_FILTER MPEG4_ENCODER \
|
||||
AC3_FIXED_ENCODER FRAMECRC_MUXER PIPE_PROTOCOL) \
|
||||
|
||||
@@ -16,7 +16,7 @@ fate-sub-ass-to-ass-transcode: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/1ede
|
||||
FATE_SUBTITLES_ASS-$(CONFIG_ASS_DEMUXER) += fate-sub-ssa-to-ass-remux
|
||||
fate-sub-ssa-to-ass-remux: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/a9-misc.ssa -c copy
|
||||
|
||||
FATE_SUBTITLES-$(call ALLYES, ASS_DEMUXER, MATROSKA_MUXER) += fate-binsub-mksenc
|
||||
FATE_SUBTITLES-$(call ALLYES, ASS_DEMUXER MATROSKA_MUXER) += fate-binsub-mksenc
|
||||
fate-binsub-mksenc: CMD = md5pipe -i $(TARGET_SAMPLES)/sub/1ededcbd7b.ass -c copy -f matroska -flags +bitexact -fflags +bitexact
|
||||
|
||||
FATE_SUBTITLES_ASS-$(call DEMDEC, JACOSUB, JACOSUB) += fate-sub-jacosub
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
452d91e7c6889b787717fef25b6fce43 *tests/data/fate/copy-trac3074.mp4
|
||||
36fcc0a62695bcf93068fcfe68283ee9 *tests/data/fate/copy-trac3074.mp4
|
||||
334016 tests/data/fate/copy-trac3074.mp4
|
||||
#tb 0: 1/48000
|
||||
#media_type 0: audio
|
||||
|
||||
@@ -1 +1 @@
|
||||
pixdesc-p210be 9f3465e388d91beeb5cb7fe0011c5a67
|
||||
pixdesc-p210be 016fd90989d14914bbbcc7dc2968bef0
|
||||
|
||||
@@ -1 +1 @@
|
||||
pixdesc-p216be db5cabe6e5f1814a6d20e8398aec4785
|
||||
pixdesc-p216be d95084fa0758169851f57455a9624a2e
|
||||
|
||||
@@ -1 +1 @@
|
||||
pixdesc-p410be 85671676fa52d0350c918f45417f3c64
|
||||
pixdesc-p410be 33d7e8e5d6a85cc22fcbf0c12c7bafd0
|
||||
|
||||
@@ -1 +1 @@
|
||||
pixdesc-p416be a7d8a859ce47c3860e0fee31539a84b0
|
||||
pixdesc-p416be 6a4b1b2fc8435acfc82312109f13bc58
|
||||
|
||||
@@ -63,13 +63,13 @@ p010be 7f9842d6015026136bad60d03c035cc3
|
||||
p010le c453421b9f726bdaf2bacf59a492c43b
|
||||
p016be 7f9842d6015026136bad60d03c035cc3
|
||||
p016le c453421b9f726bdaf2bacf59a492c43b
|
||||
p210be 6df2a72ee297e53f9ac7f96acf0ef5d5
|
||||
p210be 847e9c6e292b17349e69570829252b3e
|
||||
p210le c06e4b76cf504e908128081f92b60ce2
|
||||
p216be 01d10b0d17c9f575b512dff36623a85b
|
||||
p216be f5009974fc1cd5d552705eeb52de35d9
|
||||
p216le 2f634e1a3cd5c9c122e0f2ebadb3503d
|
||||
p410be d9af5b8126ea7457edaf0c90ad0cb2b7
|
||||
p410be 7c2509d2df4bbb199ab653ebb6dce61e
|
||||
p410le 527761e1f4381007044679710a352ecc
|
||||
p416be fc5c1c45567de4a6bc9dbc8eef30116d
|
||||
p416be fd828e966d45ae908f5d2d4b3349b816
|
||||
p416le 983064bfd506be1e26cd57bafc14ae50
|
||||
pal8 ff5929f5b42075793b2c34cb441bede5
|
||||
rgb0 0de71e5a1f97f81fb51397a0435bfa72
|
||||
|
||||
@@ -61,13 +61,13 @@ p010be 8b2de2eb6b099bbf355bfc55a0694ddc
|
||||
p010le 373b50c766dfd0a8e79c9a73246d803a
|
||||
p016be 8b2de2eb6b099bbf355bfc55a0694ddc
|
||||
p016le 373b50c766dfd0a8e79c9a73246d803a
|
||||
p210be b75f0e53a245e49af955fe210fc31bb8
|
||||
p210be 2947f43774352ef61f9e83777548c7c5
|
||||
p210le 74fcd5a32eee687eebe002c884103963
|
||||
p216be 89cb3a4bd44ba624c1395e7ea6998dde
|
||||
p216be 41351128eaf636041c8987698730391a
|
||||
p216le e56f5e5b0d4460d56f27a5df8a4a1462
|
||||
p410be 37e56737c2421aa59a33c57423d58616
|
||||
p410be e17c78ff059363177548412e6ab4e65f
|
||||
p410le 75f910c7282d8065d97f502ba974c481
|
||||
p416be 13b2dc247bdb0ab7e5532f75048f5a2c
|
||||
p416be 52f08b8a56a09d6e954c2eab6cf24d99
|
||||
p416le ecb78b327ea5cfe1fff82945c1fca310
|
||||
pal8 1f2cdc8e718f95c875dbc1034a688bfb
|
||||
rgb0 736646b70dd9a0be22b8da8041e35035
|
||||
|
||||
@@ -63,13 +63,13 @@ p010be a0311a09bba7383553267d2b3b9c075e
|
||||
p010le ee09a18aefa3ebe97715b3a7312cb8ff
|
||||
p016be a0311a09bba7383553267d2b3b9c075e
|
||||
p016le ee09a18aefa3ebe97715b3a7312cb8ff
|
||||
p210be 341db7c98afd2767d48cdd72e224df2f
|
||||
p210be 58d46f566ab28e3bcfb715c7aa53cf58
|
||||
p210le 8d68f7655a3d76f2f8436bd25beb3973
|
||||
p216be 0dde930860e940dced179884c359f720
|
||||
p216be dd1f3e0bb5c49775a598ab29802fc268
|
||||
p216le b573c0473a1368813d077487cc9bce0e
|
||||
p410be 9e9a812b74854226271c5f7dc18c37b7
|
||||
p410be 658fd0d92eb327cbd562abafc8694db7
|
||||
p410le c981188c7fd9f32988a9f4732303f82b
|
||||
p416be 203203e6788a80b52d2ca6ba629beb9c
|
||||
p416be 66616bf2320464b5e9b6372d48b6b9a9
|
||||
p416le 1039b97bbe42ef0af1bc46d2c0fc819e
|
||||
pal8 0658c18dcd8d052d59dfbe23f5b368d9
|
||||
rgb0 ca3fa6e865b91b3511c7f2bf62830059
|
||||
|
||||
@@ -55,13 +55,13 @@ grayf32be 1aa7960131f880c54fe3c77f13448674
|
||||
grayf32le 4029ac9d197f255794c1b9e416520fc7
|
||||
nv24 4fdbef26042c77f012df114e666efdb2
|
||||
nv42 59608290fece913e6b7d61edf581a529
|
||||
p210be 82958903f553e9d2d91549bd44559a5a
|
||||
p210be ca2ce2c25db43dcd14729b2a72a7c604
|
||||
p210le 755363012d8801b96ead2e8b1b4d2ab8
|
||||
p216be 7159f11beb9138932f8d60b95efe96dc
|
||||
p216be 17741c0cdb65914ad13c5114121a175f
|
||||
p216le c0c888ab7bde56638732344076b3b2ba
|
||||
p410be 411f89fadbee1ca43d2918eba583bea5
|
||||
p410be b6d65b820198ca6ff0103d9794727792
|
||||
p410le 2771dd3ae54a439921f51c29e79b6799
|
||||
p416be de6b84bd524e8fcfc251634cae416069
|
||||
p416be a0f8b5acad8fafc45fc7b2275fac1d84
|
||||
p416le 2e73af44eb933580da59981176848dcc
|
||||
rgb0 2e3d8c91c7a83d451593dfd06607ff39
|
||||
rgb24 b82577f8215d3dc2681be60f1da247af
|
||||
|
||||
@@ -61,13 +61,13 @@ p010be 744b13e44d39e1ff7588983fa03e0101
|
||||
p010le a50b160346ab94f55a425065b57006f0
|
||||
p016be 744b13e44d39e1ff7588983fa03e0101
|
||||
p016le a50b160346ab94f55a425065b57006f0
|
||||
p210be 174cdf99f18658724e269bf38d2b653b
|
||||
p210be 6f5a76d6467b86d55fe5589d3af8a7ea
|
||||
p210le b6982912b2376371edea4fccf99fe40c
|
||||
p216be c58f03c6668ab0fbc3ee1a2da051e28c
|
||||
p216be c1b58f61cd6df9cf01c3086786fb8a69
|
||||
p216le 1f5213bebf4c99634f57290f5ad99c0d
|
||||
p410be aa40aa32be7aa353252bac70b5edc175
|
||||
p410be 2e06214ea84595aa1294239b0f1e900f
|
||||
p410le 1143c811c383e4461b1192dca0c74246
|
||||
p416be 8863e9156ee7edcb6b9e6ac01a2e338c
|
||||
p416be da6807d924b63a54b804d32e427524bf
|
||||
p416le a42b88cabc4395aa0bf1bcbbc876f48f
|
||||
pal8 5b7c77d99817b4f52339742a47de7797
|
||||
rgb0 0092452f37d73da20193265ace0b7d57
|
||||
|
||||
@@ -63,13 +63,13 @@ p010be 3df51286ef66b53e3e283dbbab582263
|
||||
p010le eadcd8241e97e35b2b47d5eb2eaea6cd
|
||||
p016be 3df51286ef66b53e3e283dbbab582263
|
||||
p016le eadcd8241e97e35b2b47d5eb2eaea6cd
|
||||
p210be 4992fe87c600dfb177b1e2e6aa0f922c
|
||||
p210be 29ec4e8912d456cd15203a96487c42e8
|
||||
p210le c695064fb9f2cc4e35957d4d649cc281
|
||||
p216be 98b73479f0ea9843768c162c449c3ac5
|
||||
p216be ad85bdc59755608602608a9438bb82ea
|
||||
p216le 77757390da383a90981e461d128d8789
|
||||
p410be a7183a01888b47a4d9f3672073c7ea7d
|
||||
p410be 2128861337e660232e6fb664cc4de3e6
|
||||
p410le 6cf3a3e199b327f4f013e0346410d7a8
|
||||
p416be 4dc4aebf18e09e8f8b49db90ae5ec127
|
||||
p416be 47dec75cefeb6220be7731bc25b7be9c
|
||||
p416le 4990b51ff889d9ee23e68997f81c09f1
|
||||
rgb0 cfaf68671e43248267d8cd50cae8c13f
|
||||
rgb24 88894f608cf33ba310f21996748d77a7
|
||||
|
||||
@@ -63,13 +63,13 @@ p010be 7f9842d6015026136bad60d03c035cc3
|
||||
p010le c453421b9f726bdaf2bacf59a492c43b
|
||||
p016be 7f9842d6015026136bad60d03c035cc3
|
||||
p016le c453421b9f726bdaf2bacf59a492c43b
|
||||
p210be 6df2a72ee297e53f9ac7f96acf0ef5d5
|
||||
p210be 847e9c6e292b17349e69570829252b3e
|
||||
p210le c06e4b76cf504e908128081f92b60ce2
|
||||
p216be 01d10b0d17c9f575b512dff36623a85b
|
||||
p216be f5009974fc1cd5d552705eeb52de35d9
|
||||
p216le 2f634e1a3cd5c9c122e0f2ebadb3503d
|
||||
p410be d9af5b8126ea7457edaf0c90ad0cb2b7
|
||||
p410be 7c2509d2df4bbb199ab653ebb6dce61e
|
||||
p410le 527761e1f4381007044679710a352ecc
|
||||
p416be fc5c1c45567de4a6bc9dbc8eef30116d
|
||||
p416be fd828e966d45ae908f5d2d4b3349b816
|
||||
p416le 983064bfd506be1e26cd57bafc14ae50
|
||||
pal8 ff5929f5b42075793b2c34cb441bede5
|
||||
rgb0 0de71e5a1f97f81fb51397a0435bfa72
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
0bgr 7bc6f5a1c44cdd7506174dccf52c68d7
|
||||
0rgb ff12e0f1e576b47a4c962729d5c0b868
|
||||
0bgr 55d41bba3609383bf658169f90b30b42
|
||||
0rgb 8e076dd0f8a9f4652595dffe3544f0f0
|
||||
abgr 52738042432893de555e6a3833172806
|
||||
argb 2a10108ac524b422b8a2393c064b3eab
|
||||
bgr0 32207a2de1b2ac7937e940a8459b97c0
|
||||
bgr0 025d4d5e5691801ba39bc9de70e39df0
|
||||
bgr24 f8b65ad845905c7d0c93ca28dfbb826f
|
||||
bgra 929aac15e848038e367c250037575f9f
|
||||
gbrap 5f16cccab5a17cb766c882e865995167
|
||||
@@ -25,18 +25,18 @@ nv12 381574979cb04be10c9168540310afad
|
||||
nv21 0fdeb2cdd56cf5a7147dc273456fa217
|
||||
nv24 193b9eadcc06ad5081609f76249b3e47
|
||||
nv42 1738ad3c31c6c16e17679f5b09ce4677
|
||||
p210le 10b53de63b086de93c076d1d40f9da42
|
||||
p216le 0bbf778e1b6101a3f650ce0454a357f2
|
||||
p410le fcab6381bde9cd84b813925ff29be4d2
|
||||
p416le 6db094f8d7d27d7299bf9496ad66e2e0
|
||||
rgb0 78d500c8361ab6423a4826a00268c908
|
||||
p010le c57224f2dc09601c66aa3365b3cd7254
|
||||
p016le c57224f2dc09601c66aa3365b3cd7254
|
||||
p210le abc02945a9b9585f0914716e4787cefb
|
||||
p216le 1b43feb94b8a030c0c699aa0deff017b
|
||||
p410le 1f0294141ae1657d6c10c6a0d46a879f
|
||||
p416le 320e558b7ee8d598231ae0763ecca275
|
||||
rgb0 0984eb985dabbe757ed6beb53db84eff
|
||||
rgb24 17f9e2e0c609009acaf2175c42d4a2a5
|
||||
rgba b157c90191463d34fb3ce77b36c96386
|
||||
x2bgr10le d4aff89f5e15ccbb1812f319874ed444
|
||||
x2rgb10le a0c5925bd56b6f85f918c4e9fb93e90e
|
||||
xyz12le 85abf80b77a9236a76ba0b00fcbdea2d
|
||||
ya16le 940fafa240b9916de5f73cb20a552f24
|
||||
ya8 5fc0f471207ddf7aa01b07027d56b672
|
||||
ya16le d85740ba2cac9fa9ea8aaea8a5864407
|
||||
ya8 495daaca2dcb4f7aeba7652768b41ced
|
||||
yuv410p cb871dcc1e84a7ef1d21f9237b88cf6e
|
||||
yuv411p aec2c1740de9a62db0d41f4dda9121b0
|
||||
yuv420p 4398e408fc35436ce4b20468946f58b6
|
||||
|
||||
@@ -63,13 +63,13 @@ p010be 1d6726d94bf1385996a9a9840dd0e878
|
||||
p010le 4b316f2b9e18972299beb73511278fa8
|
||||
p016be 31e204018cbb53f8988c4e1174ea8ce9
|
||||
p016le d5afe557f492a09317e525d7cb782f5b
|
||||
p210be 42be1e97427247317444afa836969667
|
||||
p210be 2cc6dfcf5e006c8ed5238988a06fd45e
|
||||
p210le 04efb8f14a9d98417af40954a06aa187
|
||||
p216be caa0268d0f6779343a4432b6bc832c5b
|
||||
p216be 2f649a226812c8e5a553c4e22d301684
|
||||
p216le c8f65811f717a12706a598561c6df46d
|
||||
p410be f580b8dcf5a826c94258eeba837fd874
|
||||
p410be 354cd1324ad382df1a3d573833323cce
|
||||
p410le 90fdd95ec4482c127d98307550a885c6
|
||||
p416be a1242f80d32705a757f4d3553542ae1f
|
||||
p416be aa54294859a8e6cb2c9cf64d343fdb60
|
||||
p416le d91a0858ea8d2cf1ed29f179c9ad9666
|
||||
pal8 29e10892009b2cfe431815ec3052ed3b
|
||||
rgb0 fbd27e98154efb7535826afed41e9bb0
|
||||
|
||||
@@ -61,9 +61,9 @@ p010be ad0de2cc9bff81688b182a870fcf7000
|
||||
p010le e7ff5143595021246733ce6bd0a769e8
|
||||
p016be ad0de2cc9bff81688b182a870fcf7000
|
||||
p016le e7ff5143595021246733ce6bd0a769e8
|
||||
p410be 171453dc34dd3c77659914e2202c5aa6
|
||||
p410be 8b3e0ccb31b6a20ff00a29253fb2dec3
|
||||
p410le 4e5f78dfccda9a6387e81354a56a033a
|
||||
p416be ff09601f127101a8ce8997b9ae0fd6bf
|
||||
p416be 350a90bda53349435d89ec13533726b7
|
||||
p416le 7bb46e2aec65669a27502ec452941237
|
||||
rgb0 31ea5da7fe779c6ea0a33f1d28aad918
|
||||
rgb24 47654cabaaad79170b90afd5a02161dd
|
||||
|
||||
@@ -63,13 +63,13 @@ p010be 06e9354b6e0e38ba41736352cedc0bd5
|
||||
p010le fd18d322bffbf5816902c13102872e22
|
||||
p016be 06e9354b6e0e38ba41736352cedc0bd5
|
||||
p016le fd18d322bffbf5816902c13102872e22
|
||||
p210be 328b09bb0c70571617901322b4194023
|
||||
p210be ca886ab2b3ea5c153f1954b3709f7249
|
||||
p210le d71c2d4e483030ffd87fa6a68c83fce0
|
||||
p216be e4ab026532db1dfee38cedef384e605b
|
||||
p216be 7f268f755ed02592b3a49fd5f7bd48bb
|
||||
p216le 2c0a660762527706799c4705ca50a9c5
|
||||
p410be 637fb064c2ce173de5cf431aa9267914
|
||||
p410be 4c603e4464ed3f34cc432b4d1f912082
|
||||
p410le 849308a1cdf41e055019cf311d1b2201
|
||||
p416be 8e9cf1b695c0a33b6094dd6c7b3722d9
|
||||
p416be 7e7657ab40cf953351a14ea76e296519
|
||||
p416le 0991d7fff4e2caf36be219ecdd9619d4
|
||||
pal8 450b0155d0f2d5628bf95a442db5f817
|
||||
rgb0 56a7ea69541bcd27bef6a5615784722b
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
4e92f776010bd7a727c11bf8c34cde1e *tests/data/fate/mov-cover-image.mp4
|
||||
54a8870d5d1e6cc4da28ae422aa70898 *tests/data/fate/mov-cover-image.mp4
|
||||
1011919 tests/data/fate/mov-cover-image.mp4
|
||||
#extradata 0: 2, 0x00340022
|
||||
#tb 0: 1/44100
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
3c4432fe59ffd9f2ed6ba4b122cea935 *tests/data/fate/mov-mp4-disposition-mpegts-remux.mp4
|
||||
adb3b95c07a5f3e0c86641dd62f01dae *tests/data/fate/mov-mp4-disposition-mpegts-remux.mp4
|
||||
5709 tests/data/fate/mov-mp4-disposition-mpegts-remux.mp4
|
||||
#tb 0: 1/48000
|
||||
#media_type 0: audio
|
||||
|
||||
@@ -7,7 +7,7 @@ write_data len 36, time nopts, type header atom ftyp
|
||||
write_data len 2761, time nopts, type header atom -
|
||||
write_data len 908, time 966667, type sync atom moof
|
||||
write_data len 110, time nopts, type trailer atom -
|
||||
caf0876986b5f033efc0958c338289cc 3815 non-empty-moov-elst
|
||||
9d260d424e9de4626163fd25ccce5bab 3815 non-empty-moov-elst
|
||||
write_data len 36, time nopts, type header atom ftyp
|
||||
write_data len 2669, time nopts, type header atom -
|
||||
write_data len 908, time 1000000, type sync atom moof
|
||||
|
||||
@@ -952,3 +952,20 @@ usePal:
|
||||
rgb4_byte
|
||||
rgb8
|
||||
|
||||
DataInHighBits:
|
||||
p010be
|
||||
p010le
|
||||
p210be
|
||||
p210le
|
||||
p410be
|
||||
p410le
|
||||
xyz12be
|
||||
xyz12le
|
||||
y210be
|
||||
y210le
|
||||
|
||||
SwappedChroma:
|
||||
nv21
|
||||
nv42
|
||||
yvyu422
|
||||
|
||||
|
||||
Reference in New Issue
Block a user