mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
avformat/mov: add support for 'amve' ambient viewing environment box
As defined in ISOBMFF (ISO/IEC 14496-12) document. Co-Authored-By: Cosmin Stejerean <cosmin@cosmin.at>
This commit is contained in:
parent
dda4b25e2d
commit
112d3618ca
@ -28,6 +28,7 @@
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/mastering_display_metadata.h"
|
||||
#include "libavutil/ambient_viewing_environment.h"
|
||||
#include "libavutil/dovi_meta.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/opt.h"
|
||||
@ -379,6 +380,17 @@ static void dump_content_light_metadata(void *ctx, const AVPacketSideData *sd,
|
||||
metadata->MaxCLL, metadata->MaxFALL);
|
||||
}
|
||||
|
||||
static void dump_ambient_viewing_environment_metadata(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
const AVAmbientViewingEnvironment *ambient =
|
||||
(const AVAmbientViewingEnvironment *)sd->data;
|
||||
av_log(ctx, AV_LOG_INFO, "Ambient Viewing Environment, "
|
||||
"ambient_illuminance=%f, ambient_light_x=%f, ambient_light_y=%f",
|
||||
av_q2d(ambient->ambient_illuminance),
|
||||
av_q2d(ambient->ambient_light_x),
|
||||
av_q2d(ambient->ambient_light_y));
|
||||
}
|
||||
|
||||
static void dump_spherical(void *ctx, const AVCodecParameters *par,
|
||||
const AVPacketSideData *sd, int log_level)
|
||||
{
|
||||
@ -513,6 +525,9 @@ static void dump_sidedata(void *ctx, const AVStream *st, const char *indent,
|
||||
av_log(ctx, log_level, "SMPTE ST 12-1:2014: ");
|
||||
dump_s12m_timecode(ctx, st, sd, log_level);
|
||||
break;
|
||||
case AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT:
|
||||
dump_ambient_viewing_environment_metadata(ctx, sd);
|
||||
break;
|
||||
default:
|
||||
av_log(ctx, log_level, "unknown side data type %d "
|
||||
"(%"SIZE_SPECIFIER" bytes)", sd->type, sd->size);
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "libavutil/encryption_info.h"
|
||||
#include "libavutil/mastering_display_metadata.h"
|
||||
#include "libavutil/ambient_viewing_environment.h"
|
||||
#include "libavutil/spherical.h"
|
||||
#include "libavutil/stereo3d.h"
|
||||
|
||||
@ -249,6 +250,8 @@ typedef struct MOVStreamContext {
|
||||
AVMasteringDisplayMetadata *mastering;
|
||||
AVContentLightMetadata *coll;
|
||||
size_t coll_size;
|
||||
AVAmbientViewingEnvironment *ambient;
|
||||
size_t ambient_size;
|
||||
|
||||
uint32_t format;
|
||||
|
||||
|
@ -6039,6 +6039,31 @@ static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
{
|
||||
MOVStreamContext *sc;
|
||||
const int illuminance_den = 10000;
|
||||
const int ambient_den = 50000;
|
||||
if (c->fc->nb_streams < 1)
|
||||
return AVERROR_INVALIDDATA;
|
||||
sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
|
||||
if (atom.size < 6) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (sc->ambient){
|
||||
av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
|
||||
return 0;
|
||||
}
|
||||
sc->ambient = av_ambient_viewing_environment_alloc(&sc->ambient_size);
|
||||
if (!sc->ambient)
|
||||
return AVERROR(ENOMEM);
|
||||
sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
|
||||
sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
|
||||
sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
{
|
||||
AVStream *st;
|
||||
@ -8215,6 +8240,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
|
||||
{ MKTAG('i','s','p','e'), mov_read_ispe },
|
||||
{ MKTAG('i','p','r','p'), mov_read_iprp },
|
||||
{ MKTAG('i','i','n','f'), mov_read_iinf },
|
||||
{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@ -8680,6 +8706,7 @@ static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
|
||||
av_freep(&sc->spherical);
|
||||
av_freep(&sc->mastering);
|
||||
av_freep(&sc->coll);
|
||||
av_freep(&sc->ambient);
|
||||
}
|
||||
|
||||
static int mov_read_close(AVFormatContext *s)
|
||||
@ -9072,6 +9099,14 @@ static int mov_read_header(AVFormatContext *s)
|
||||
|
||||
sc->coll = NULL;
|
||||
}
|
||||
if (sc->ambient) {
|
||||
if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
|
||||
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,
|
||||
(uint8_t *) sc->ambient, sc->ambient_size, 0))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
sc->ambient = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2244,6 +2244,33 @@ static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
|
||||
{
|
||||
const int illuminance_den = 10000;
|
||||
const int ambient_den = 50000;
|
||||
const AVPacketSideData *side_data;
|
||||
const AVAmbientViewingEnvironment *ambient;
|
||||
|
||||
|
||||
side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
|
||||
track->st->codecpar->nb_coded_side_data,
|
||||
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT);
|
||||
|
||||
if (!side_data)
|
||||
return 0;
|
||||
|
||||
ambient = (const AVAmbientViewingEnvironment*)side_data->data;
|
||||
if (!ambient || !ambient->ambient_illuminance.num)
|
||||
return 0;
|
||||
|
||||
avio_wb32(pb, 16); // size
|
||||
ffio_wfourcc(pb, "amve");
|
||||
avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
|
||||
avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
|
||||
avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
|
||||
return 16;
|
||||
}
|
||||
|
||||
static void find_compressor(char * compressor_name, int len, MOVTrack *track)
|
||||
{
|
||||
AVDictionaryEntry *encoder;
|
||||
@ -2457,6 +2484,7 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
|
||||
if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
|
||||
mov_write_clli_tag(pb, track);
|
||||
mov_write_mdcv_tag(pb, track);
|
||||
mov_write_amve_tag(pb, track);
|
||||
}
|
||||
|
||||
if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user