static int add_metadata_from_side_data(AVCodecContext *avctx, AVFrame *frame)
{
- int size, ret = 0;
+ int size;
const uint8_t *side_metadata;
- const uint8_t *end;
+
+ AVDictionary **frame_md = avpriv_frame_get_metadatap(frame);
side_metadata = av_packet_get_side_data(avctx->internal->pkt,
AV_PKT_DATA_STRINGS_METADATA, &size);
- if (!side_metadata)
- goto end;
- end = side_metadata + size;
- if (size && end[-1])
- return AVERROR_INVALIDDATA;
- while (side_metadata < end) {
- const uint8_t *key = side_metadata;
- const uint8_t *val = side_metadata + strlen(key) + 1;
- int ret;
-
- if (val >= end)
- return AVERROR_INVALIDDATA;
-
- ret = av_dict_set(avpriv_frame_get_metadatap(frame), key, val, 0);
- if (ret < 0)
- break;
- side_metadata = val + strlen(val) + 1;
- }
-end:
- return ret;
+ return av_packet_unpack_dictionary(side_metadata, size, frame_md);
}
int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
int did_split = av_packet_split_side_data(&tmp);
//apply_param_change(avctx, &tmp);
+ if (did_split) {
+ /* FFMIN() prevents overflow in case the packet wasn't allocated with
+ * proper padding.
+ * If the side data is smaller than the buffer padding size, the
+ * remaining bytes should have already been filled with zeros by the
+ * original packet allocation anyway. */
+ memset(tmp.data + tmp.size, 0,
+ FFMIN(avpkt->size - tmp.size, FF_INPUT_BUFFER_PADDING_SIZE));
+ }
+
pkt_recoded = tmp;
ret = recode_subtitle(avctx, &pkt_recoded, &tmp);
if (ret < 0) {