| @@ -98,6 +98,23 @@ static void remove_side_data(AVFrameSideData ***sd, int *nb_side_data, · 97 unmodified lines |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| 100 | | 100 | |
| | 101 | static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd, |
| | 102 | const AVFrameSideData *target) |
| | 103 | { |
| | 104 | for (int i = *nb_sd - 1; i >= 0; i--) { |
| | 105 | AVFrameSideData *entry = ((*sd)[i]); |
| | 106 | if (entry != target) |
| | 107 | continue; |
| | 108 | |
| | 109 | free_side_data(&entry); |
| | 110 | |
| | 111 | ((*sd)[i]) = ((*sd)[*nb_sd - 1]); |
| | 112 | (*nb_sd)--; |
| | 113 | |
| | 114 | return; |
| | 115 | } |
| | 116 | } |
| | 117 | |
| 101 | AVFrame *av_frame_alloc(void) | 118 | AVFrame *av_frame_alloc(void) |
| 102 | { | 119 | { |
| 103 | AVFrame *frame = av_malloc(sizeof(*frame)); | 120 | AVFrame *frame = av_malloc(sizeof(*frame)); |
| @@ -764,6 +781,38 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, · 660 unmodified lines |
| 764 | return ret; | 781 | return ret; |
| 765 | } | 782 | } |
| 766 | | 783 | |
| | 784 | int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, |
| | 785 | const AVFrameSideData *src, unsigned int flags) |
| | 786 | { |
| | 787 | AVBufferRef *buf = NULL; |
| | 788 | AVFrameSideData *sd_dst = NULL; |
| | 789 | int ret = AVERROR_BUG; |
| | 790 | |
| | 791 | if (!sd || !src || !nb_sd || (*nb_sd && !*sd)) |
| | 792 | return AVERROR(EINVAL); |
| | 793 | |
| | 794 | buf = av_buffer_ref(src->buf); |
| | 795 | if (!buf) |
| | 796 | return AVERROR(ENOMEM); |
| | 797 | |
| | 798 | if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) |
| | 799 | remove_side_data(sd, nb_sd, src->type); |
| | 800 | |
| | 801 | sd_dst = add_side_data_from_buf(sd, nb_sd, src->type, buf); |
| | 802 | if (!sd_dst) { |
| | 803 | av_buffer_unref(&buf); |
| | 804 | return AVERROR(ENOMEM); |
| | 805 | } |
| | 806 | |
| | 807 | ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0); |
| | 808 | if (ret < 0) { |
| | 809 | remove_side_data_by_entry(sd, nb_sd, sd_dst); |
| | 810 | return ret; |
| | 811 | } |
| | 812 | |
| | 813 | return 0; |
| | 814 | } |
| | 815 | |
| 767 | AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, | 816 | AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, |
| 768 | enum AVFrameSideDataType type) | 817 | enum AVFrameSideDataType type) |
| 769 | { | 818 | { |