avcodec/decode: propagate global side data to frames

The changed references for fate-hevc-dv-rpu fate-mov-zombie happen because,
unlike ffmpeg and ffplay, ffprobe never injected packet side data, so the
display matrix side data at the container level is now present in the output
frames.

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer 2023-07-17 18:56:44 -03:00
parent 804be7f9e3
commit ae22271620
3 changed files with 124 additions and 74 deletions

View file

@ -1425,6 +1425,21 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
return av_packet_unpack_dictionary(side_metadata, size, frame_md);
}
static const struct {
enum AVPacketSideDataType packet;
enum AVFrameSideDataType frame;
} sd_global_map[] = {
{ AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN },
{ AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX },
{ AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL },
{ AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D },
{ AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
{ AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA },
{ AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL },
{ AV_PKT_DATA_ICC_PROFILE, AV_FRAME_DATA_ICC_PROFILE },
{ AV_PKT_DATA_DYNAMIC_HDR10_PLUS, AV_FRAME_DATA_DYNAMIC_HDR_PLUS },
};
int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
AVFrame *frame, const AVPacket *pkt)
{
@ -1432,18 +1447,9 @@ int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
enum AVPacketSideDataType packet;
enum AVFrameSideDataType frame;
} sd[] = {
{ AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN },
{ AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX },
{ AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL },
{ AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D },
{ AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
{ AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA },
{ AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL },
{ AV_PKT_DATA_A53_CC, AV_FRAME_DATA_A53_CC },
{ AV_PKT_DATA_AFD, AV_FRAME_DATA_AFD },
{ AV_PKT_DATA_ICC_PROFILE, AV_FRAME_DATA_ICC_PROFILE },
{ AV_PKT_DATA_S12M_TIMECODE, AV_FRAME_DATA_S12M_TIMECODE },
{ AV_PKT_DATA_DYNAMIC_HDR10_PLUS, AV_FRAME_DATA_DYNAMIC_HDR_PLUS },
{ AV_PKT_DATA_SKIP_SAMPLES, AV_FRAME_DATA_SKIP_SAMPLES },
};
@ -1456,6 +1462,18 @@ FF_DISABLE_DEPRECATION_WARNINGS
FF_ENABLE_DEPRECATION_WARNINGS
#endif
for (int i = 0; i < FF_ARRAY_ELEMS(sd_global_map); i++) {
size_t size;
const uint8_t *packet_sd = av_packet_get_side_data(pkt, sd_global_map[i].packet, &size);
if (packet_sd) {
AVFrameSideData *frame_sd;
frame_sd = av_frame_new_side_data(frame, sd_global_map[i].frame, size);
if (!frame_sd)
return AVERROR(ENOMEM);
memcpy(frame_sd->data, packet_sd, size);
}
}
for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
size_t size;
uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
@ -1491,6 +1509,20 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
{
int ret;
for (int i = 0; i < FF_ARRAY_ELEMS(sd_global_map); i++) {
const AVPacketSideData *packet_sd = ff_get_coded_side_data(avctx,
sd_global_map[i].packet);
if (packet_sd) {
AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
sd_global_map[i].frame,
packet_sd->size);
if (!frame_sd)
return AVERROR(ENOMEM);
memcpy(frame_sd->data, packet_sd->data, packet_sd->size);
}
}
if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
const AVPacket *pkt = avctx->internal->last_pkt_props;