Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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,7 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version <next>:
|
||||
version 5.0:
|
||||
- ADPCM IMA Westwood encoder
|
||||
- Westwood AUD muxer
|
||||
- ADPCM IMA Acorn Replay decoder
|
||||
@@ -44,6 +44,7 @@ version <next>:
|
||||
- yadif_videotoolbox filter
|
||||
- VideoToolbox ProRes encoder
|
||||
- anlmf audio filter
|
||||
- IMF demuxer (experimental)
|
||||
|
||||
|
||||
version 4.4:
|
||||
|
||||
15
RELEASE_NOTES
Normal file
15
RELEASE_NOTES
Normal file
@@ -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.
|
||||
7
configure
vendored
7
configure
vendored
@@ -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++"
|
||||
@@ -6586,7 +6587,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
|
||||
|
||||
@@ -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
|
||||
|
||||
# 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -807,34 +807,37 @@ int ff_imf_parse_cpl(AVIOContext *in, FFIMFCPL **cpl)
|
||||
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
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
@@ -624,8 +624,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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
@@ -906,6 +944,30 @@ static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
|
||||
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 +1425,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 +1588,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 +2432,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 +2961,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 +3170,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 +3472,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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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