lavc: add a decoder option for configuring side data preference

This and the following commits fix #10857
This commit is contained in:
Anton Khirnov 2024-01-11 19:24:58 +01:00
parent efe4478778
commit 68a8eca752
5 changed files with 85 additions and 1 deletions

View file

@ -65,6 +65,12 @@ typedef struct DecodeContext {
int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
int64_t pts_correction_last_pts; /// PTS of the last frame
int64_t pts_correction_last_dts; /// DTS of the last frame
/**
* Bitmask indicating for which side data types we prefer user-supplied
* (global or attached to packets) side data over bytestream.
*/
uint64_t side_data_pref_mask;
} DecodeContext;
static DecodeContext *decode_ctx(AVCodecInternal *avci)
@ -1739,6 +1745,35 @@ int ff_decode_preinit(AVCodecContext *avctx)
avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS;
}
if (avctx->nb_side_data_prefer_packet == 1 &&
avctx->side_data_prefer_packet[0] == -1)
dc->side_data_pref_mask = ~0ULL;
else {
for (unsigned i = 0; i < avctx->nb_side_data_prefer_packet; i++) {
int val = avctx->side_data_prefer_packet[i];
if (val < 0 || val >= AV_PKT_DATA_NB) {
av_log(avctx, AV_LOG_ERROR, "Invalid side data type: %d\n", val);
return AVERROR(EINVAL);
}
for (unsigned j = 0; j < FF_ARRAY_ELEMS(sd_global_map); j++) {
if (sd_global_map[j].packet == val) {
val = sd_global_map[j].frame;
// this code will need to be changed when we have more than
// 64 frame side data types
if (val >= 64) {
av_log(avctx, AV_LOG_ERROR, "Side data type too big\n");
return AVERROR_BUG;
}
dc->side_data_pref_mask |= 1ULL << val;
}
}
}
}
avci->in_pkt = av_packet_alloc();
avci->last_pkt_props = av_packet_alloc();
if (!avci->in_pkt || !avci->last_pkt_props)