tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

packet.c (23285B)


      1 /*
      2 * AVPacket functions for libavcodec
      3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
      4 *
      5 * This file is part of FFmpeg.
      6 *
      7 * FFmpeg is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU Lesser General Public
      9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * FFmpeg is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with FFmpeg; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     20 */
     21 
     22 #include <string.h>
     23 
     24 #include "libavutil/avassert.h"
     25 #include "libavutil/avutil.h"
     26 #include "libavutil/container_fifo.h"
     27 #include "libavutil/intreadwrite.h"
     28 #include "libavutil/mathematics.h"
     29 #include "libavutil/mem.h"
     30 #include "libavutil/rational.h"
     31 
     32 #include "defs.h"
     33 #include "packet.h"
     34 #include "packet_internal.h"
     35 
     36 #if FF_API_INIT_PACKET
     37 void av_init_packet(AVPacket *pkt)
     38 {
     39    pkt->pts                  = AV_NOPTS_VALUE;
     40    pkt->dts                  = AV_NOPTS_VALUE;
     41    pkt->pos                  = -1;
     42    pkt->duration             = 0;
     43    pkt->flags                = 0;
     44    pkt->stream_index         = 0;
     45    pkt->buf                  = NULL;
     46    pkt->side_data            = NULL;
     47    pkt->side_data_elems      = 0;
     48    pkt->opaque               = NULL;
     49    pkt->opaque_ref           = NULL;
     50    pkt->time_base            = av_make_q(0, 1);
     51 }
     52 #endif
     53 
     54 static void get_packet_defaults(AVPacket *pkt)
     55 {
     56    memset(pkt, 0, sizeof(*pkt));
     57 
     58    pkt->pts             = AV_NOPTS_VALUE;
     59    pkt->dts             = AV_NOPTS_VALUE;
     60    pkt->pos             = -1;
     61    pkt->time_base       = av_make_q(0, 1);
     62 }
     63 
     64 AVPacket *av_packet_alloc(void)
     65 {
     66    AVPacket *pkt = av_malloc(sizeof(AVPacket));
     67    if (!pkt)
     68        return pkt;
     69 
     70    get_packet_defaults(pkt);
     71 
     72    return pkt;
     73 }
     74 
     75 void av_packet_free(AVPacket **pkt)
     76 {
     77    if (!pkt || !*pkt)
     78        return;
     79 
     80    av_packet_unref(*pkt);
     81    av_freep(pkt);
     82 }
     83 
     84 static int packet_alloc(AVBufferRef **buf, int size)
     85 {
     86    int ret;
     87    if (size < 0 || size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
     88        return AVERROR(EINVAL);
     89 
     90    ret = av_buffer_realloc(buf, size + AV_INPUT_BUFFER_PADDING_SIZE);
     91    if (ret < 0)
     92        return ret;
     93 
     94    memset((*buf)->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     95 
     96    return 0;
     97 }
     98 
     99 int av_new_packet(AVPacket *pkt, int size)
    100 {
    101    AVBufferRef *buf = NULL;
    102    int ret = packet_alloc(&buf, size);
    103    if (ret < 0)
    104        return ret;
    105 
    106    get_packet_defaults(pkt);
    107    pkt->buf      = buf;
    108    pkt->data     = buf->data;
    109    pkt->size     = size;
    110 
    111    return 0;
    112 }
    113 
    114 void av_shrink_packet(AVPacket *pkt, int size)
    115 {
    116    if (pkt->size <= size)
    117        return;
    118    pkt->size = size;
    119    memset(pkt->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    120 }
    121 
    122 int av_grow_packet(AVPacket *pkt, int grow_by)
    123 {
    124    int new_size;
    125    av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
    126    if ((unsigned)grow_by >
    127        INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE))
    128        return AVERROR(ENOMEM);
    129 
    130    new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE;
    131    if (pkt->buf) {
    132        size_t data_offset;
    133        uint8_t *old_data = pkt->data;
    134        if (pkt->data == NULL) {
    135            data_offset = 0;
    136            pkt->data = pkt->buf->data;
    137        } else {
    138            data_offset = pkt->data - pkt->buf->data;
    139            if (data_offset > INT_MAX - new_size)
    140                return AVERROR(ENOMEM);
    141        }
    142 
    143        if (new_size + data_offset > pkt->buf->size ||
    144            !av_buffer_is_writable(pkt->buf)) {
    145            int ret;
    146 
    147            // allocate slightly more than requested to avoid excessive
    148            // reallocations
    149            if (new_size + data_offset < INT_MAX - new_size/16)
    150                new_size += new_size/16;
    151 
    152            ret = av_buffer_realloc(&pkt->buf, new_size + data_offset);
    153            if (ret < 0) {
    154                pkt->data = old_data;
    155                return ret;
    156            }
    157            pkt->data = pkt->buf->data + data_offset;
    158        }
    159    } else {
    160        pkt->buf = av_buffer_alloc(new_size);
    161        if (!pkt->buf)
    162            return AVERROR(ENOMEM);
    163        if (pkt->size > 0)
    164            memcpy(pkt->buf->data, pkt->data, pkt->size);
    165        pkt->data = pkt->buf->data;
    166    }
    167    pkt->size += grow_by;
    168    memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    169 
    170    return 0;
    171 }
    172 
    173 int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
    174 {
    175    if (size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
    176        return AVERROR(EINVAL);
    177 
    178    pkt->buf = av_buffer_create(data, size + AV_INPUT_BUFFER_PADDING_SIZE,
    179                                av_buffer_default_free, NULL, 0);
    180    if (!pkt->buf)
    181        return AVERROR(ENOMEM);
    182 
    183    pkt->data = data;
    184    pkt->size = size;
    185 
    186    return 0;
    187 }
    188 
    189 void av_packet_free_side_data(AVPacket *pkt)
    190 {
    191    int i;
    192    for (i = 0; i < pkt->side_data_elems; i++)
    193        av_freep(&pkt->side_data[i].data);
    194    av_freep(&pkt->side_data);
    195    pkt->side_data_elems = 0;
    196 }
    197 
    198 int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
    199                            uint8_t *data, size_t size)
    200 {
    201    AVPacketSideData *tmp;
    202    int i, elems = pkt->side_data_elems;
    203 
    204    for (i = 0; i < elems; i++) {
    205        AVPacketSideData *sd = &pkt->side_data[i];
    206 
    207        if (sd->type == type) {
    208            av_free(sd->data);
    209            sd->data = data;
    210            sd->size = size;
    211            return 0;
    212        }
    213    }
    214 
    215    if ((unsigned)elems + 1 > AV_PKT_DATA_NB)
    216        return AVERROR(ERANGE);
    217 
    218    tmp = av_realloc(pkt->side_data, (elems + 1) * sizeof(*tmp));
    219    if (!tmp)
    220        return AVERROR(ENOMEM);
    221 
    222    pkt->side_data = tmp;
    223    pkt->side_data[elems].data = data;
    224    pkt->side_data[elems].size = size;
    225    pkt->side_data[elems].type = type;
    226    pkt->side_data_elems++;
    227 
    228    return 0;
    229 }
    230 
    231 
    232 uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
    233                                 size_t size)
    234 {
    235    int ret;
    236    uint8_t *data;
    237 
    238    if (size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
    239        return NULL;
    240    data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
    241    if (!data)
    242        return NULL;
    243 
    244    ret = av_packet_add_side_data(pkt, type, data, size);
    245    if (ret < 0) {
    246        av_freep(&data);
    247        return NULL;
    248    }
    249 
    250    return data;
    251 }
    252 
    253 uint8_t *av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type,
    254                                 size_t *size)
    255 {
    256    int i;
    257 
    258    for (i = 0; i < pkt->side_data_elems; i++) {
    259        if (pkt->side_data[i].type == type) {
    260            if (size)
    261                *size = pkt->side_data[i].size;
    262            return pkt->side_data[i].data;
    263        }
    264    }
    265    if (size)
    266        *size = 0;
    267    return NULL;
    268 }
    269 
    270 const char *av_packet_side_data_name(enum AVPacketSideDataType type)
    271 {
    272    switch(type) {
    273    case AV_PKT_DATA_PALETTE:                    return "Palette";
    274    case AV_PKT_DATA_NEW_EXTRADATA:              return "New Extradata";
    275    case AV_PKT_DATA_PARAM_CHANGE:               return "Param Change";
    276    case AV_PKT_DATA_H263_MB_INFO:               return "H263 MB Info";
    277    case AV_PKT_DATA_REPLAYGAIN:                 return "Replay Gain";
    278    case AV_PKT_DATA_DISPLAYMATRIX:              return "Display Matrix";
    279    case AV_PKT_DATA_STEREO3D:                   return "Stereo 3D";
    280    case AV_PKT_DATA_AUDIO_SERVICE_TYPE:         return "Audio Service Type";
    281    case AV_PKT_DATA_QUALITY_STATS:              return "Quality stats";
    282    case AV_PKT_DATA_FALLBACK_TRACK:             return "Fallback track";
    283    case AV_PKT_DATA_CPB_PROPERTIES:             return "CPB properties";
    284    case AV_PKT_DATA_SKIP_SAMPLES:               return "Skip Samples";
    285    case AV_PKT_DATA_JP_DUALMONO:                return "JP Dual Mono";
    286    case AV_PKT_DATA_STRINGS_METADATA:           return "Strings Metadata";
    287    case AV_PKT_DATA_SUBTITLE_POSITION:          return "Subtitle Position";
    288    case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL:   return "Matroska BlockAdditional";
    289    case AV_PKT_DATA_WEBVTT_IDENTIFIER:          return "WebVTT ID";
    290    case AV_PKT_DATA_WEBVTT_SETTINGS:            return "WebVTT Settings";
    291    case AV_PKT_DATA_METADATA_UPDATE:            return "Metadata Update";
    292    case AV_PKT_DATA_MPEGTS_STREAM_ID:           return "MPEGTS Stream ID";
    293    case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata";
    294    case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:        return "Content light level metadata";
    295    case AV_PKT_DATA_SPHERICAL:                  return "Spherical Mapping";
    296    case AV_PKT_DATA_A53_CC:                     return "A53 Closed Captions";
    297    case AV_PKT_DATA_ENCRYPTION_INIT_INFO:       return "Encryption initialization data";
    298    case AV_PKT_DATA_ENCRYPTION_INFO:            return "Encryption info";
    299    case AV_PKT_DATA_AFD:                        return "Active Format Description data";
    300    case AV_PKT_DATA_PRFT:                       return "Producer Reference Time";
    301    case AV_PKT_DATA_ICC_PROFILE:                return "ICC Profile";
    302    case AV_PKT_DATA_DOVI_CONF:                  return "DOVI configuration record";
    303    case AV_PKT_DATA_S12M_TIMECODE:              return "SMPTE ST 12-1:2014 timecode";
    304    case AV_PKT_DATA_DYNAMIC_HDR10_PLUS:         return "HDR10+ Dynamic Metadata (SMPTE 2094-40)";
    305    case AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT:return "Ambient viewing environment";
    306    case AV_PKT_DATA_IAMF_MIX_GAIN_PARAM:        return "IAMF Mix Gain Parameter Data";
    307    case AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM:   return "IAMF Demixing Info Parameter Data";
    308    case AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM: return "IAMF Recon Gain Info Parameter Data";
    309    case AV_PKT_DATA_FRAME_CROPPING:             return "Frame Cropping";
    310    case AV_PKT_DATA_LCEVC:                      return "LCEVC NAL data";
    311    }
    312    return NULL;
    313 }
    314 
    315 uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size)
    316 {
    317    uint8_t *data = NULL;
    318    *size = 0;
    319 
    320    if (!dict)
    321        return NULL;
    322 
    323    for (int pass = 0; pass < 2; pass++) {
    324        const AVDictionaryEntry *t = NULL;
    325        size_t total_length = 0;
    326 
    327        while ((t = av_dict_iterate(dict, t))) {
    328            for (int i = 0; i < 2; i++) {
    329                const char  *str = i ? t->value : t->key;
    330                const size_t len = strlen(str) + 1;
    331 
    332                if (pass)
    333                    memcpy(data + total_length, str, len);
    334                else if (len > SIZE_MAX - total_length)
    335                    return NULL;
    336                total_length += len;
    337            }
    338        }
    339        if (pass)
    340            break;
    341        data = av_malloc(total_length);
    342        if (!data)
    343            return NULL;
    344        *size = total_length;
    345    }
    346 
    347    return data;
    348 }
    349 
    350 int av_packet_unpack_dictionary(const uint8_t *data, size_t size,
    351                                AVDictionary **dict)
    352 {
    353    const uint8_t *end;
    354    int ret;
    355 
    356    if (!dict || !data || !size)
    357        return 0;
    358    end = data + size;
    359    if (size && end[-1])
    360        return AVERROR_INVALIDDATA;
    361    while (data < end) {
    362        const uint8_t *key = data;
    363        const uint8_t *val = data + strlen(key) + 1;
    364 
    365        if (val >= end || !*key)
    366            return AVERROR_INVALIDDATA;
    367 
    368        ret = av_dict_set(dict, key, val, 0);
    369        if (ret < 0)
    370            return ret;
    371        data = val + strlen(val) + 1;
    372    }
    373 
    374    return 0;
    375 }
    376 
    377 int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
    378                               size_t size)
    379 {
    380    int i;
    381 
    382    for (i = 0; i < pkt->side_data_elems; i++) {
    383        if (pkt->side_data[i].type == type) {
    384            if (size > pkt->side_data[i].size)
    385                return AVERROR(ENOMEM);
    386            pkt->side_data[i].size = size;
    387            return 0;
    388        }
    389    }
    390    return AVERROR(ENOENT);
    391 }
    392 
    393 static void av_packet_free_moz_crypto_info(AVPacket *pkt) {
    394  if (pkt->moz_crypto_info_release && pkt->moz_crypto_info) {
    395    (*pkt->moz_crypto_info_release)(pkt->moz_crypto_info);
    396  }
    397  pkt->moz_ndk_crypto_info        = NULL;
    398  pkt->moz_crypto_info            = NULL;
    399  pkt->moz_crypto_info_addref     = NULL;
    400  pkt->moz_crypto_info_release    = NULL;
    401 }
    402 
    403 static int av_packet_copy_moz_crypto_info(AVPacket *dst, const AVPacket *src) {
    404  av_packet_free_moz_crypto_info(dst);
    405  if (!src->moz_ndk_crypto_info) {
    406    return 0;
    407  }
    408  if (!src->moz_crypto_info || !src->moz_crypto_info_addref || !src->moz_crypto_info_release) {
    409    return AVERROR(EINVAL);
    410  }
    411  dst->moz_ndk_crypto_info        = src->moz_ndk_crypto_info;
    412  dst->moz_crypto_info            = src->moz_crypto_info;
    413  dst->moz_crypto_info_addref     = src->moz_crypto_info_addref;
    414  dst->moz_crypto_info_release    = src->moz_crypto_info_release;
    415  (*dst->moz_crypto_info_addref)(dst->moz_crypto_info);
    416  return 0;
    417 }
    418 
    419 int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
    420 {
    421    int i, ret;
    422 
    423    dst->pts                  = src->pts;
    424    dst->dts                  = src->dts;
    425    dst->pos                  = src->pos;
    426    dst->duration             = src->duration;
    427    dst->flags                = src->flags;
    428    dst->stream_index         = src->stream_index;
    429    dst->opaque               = src->opaque;
    430    dst->time_base            = src->time_base;
    431    dst->opaque_ref           = NULL;
    432    dst->side_data            = NULL;
    433    dst->side_data_elems      = 0;
    434 
    435    ret = av_packet_copy_moz_crypto_info(dst, src);
    436    if (ret < 0)
    437        return ret;
    438 
    439    ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
    440    if (ret < 0) {
    441        av_packet_free_moz_crypto_info(dst);
    442        return ret;
    443    }
    444 
    445    for (i = 0; i < src->side_data_elems; i++) {
    446        enum AVPacketSideDataType type = src->side_data[i].type;
    447        size_t size = src->side_data[i].size;
    448        uint8_t *src_data = src->side_data[i].data;
    449        uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
    450 
    451        if (!dst_data) {
    452            av_packet_free_moz_crypto_info(dst);
    453            av_buffer_unref(&dst->opaque_ref);
    454            av_packet_free_side_data(dst);
    455            return AVERROR(ENOMEM);
    456        }
    457        memcpy(dst_data, src_data, size);
    458    }
    459 
    460    return 0;
    461 }
    462 
    463 void av_packet_unref(AVPacket *pkt)
    464 {
    465    av_packet_free_moz_crypto_info(pkt);
    466    av_packet_free_side_data(pkt);
    467    av_buffer_unref(&pkt->opaque_ref);
    468    av_buffer_unref(&pkt->buf);
    469    get_packet_defaults(pkt);
    470 }
    471 
    472 int av_packet_ref(AVPacket *dst, const AVPacket *src)
    473 {
    474    int ret;
    475 
    476    dst->buf = NULL;
    477 
    478    ret = av_packet_copy_props(dst, src);
    479    if (ret < 0)
    480        goto fail;
    481 
    482    if (!src->buf) {
    483        ret = packet_alloc(&dst->buf, src->size);
    484        if (ret < 0)
    485            goto fail;
    486        av_assert1(!src->size || src->data);
    487        if (src->size)
    488            memcpy(dst->buf->data, src->data, src->size);
    489 
    490        dst->data = dst->buf->data;
    491    } else {
    492        dst->buf = av_buffer_ref(src->buf);
    493        if (!dst->buf) {
    494            ret = AVERROR(ENOMEM);
    495            goto fail;
    496        }
    497        dst->data = src->data;
    498    }
    499 
    500    dst->size = src->size;
    501 
    502    return 0;
    503 fail:
    504    av_packet_unref(dst);
    505    return ret;
    506 }
    507 
    508 AVPacket *av_packet_clone(const AVPacket *src)
    509 {
    510    AVPacket *ret = av_packet_alloc();
    511 
    512    if (!ret)
    513        return ret;
    514 
    515    if (av_packet_ref(ret, src))
    516        av_packet_free(&ret);
    517 
    518    return ret;
    519 }
    520 
    521 void av_packet_move_ref(AVPacket *dst, AVPacket *src)
    522 {
    523    *dst = *src;
    524    get_packet_defaults(src);
    525 }
    526 
    527 int av_packet_make_refcounted(AVPacket *pkt)
    528 {
    529    int ret;
    530 
    531    if (pkt->buf)
    532        return 0;
    533 
    534    ret = packet_alloc(&pkt->buf, pkt->size);
    535    if (ret < 0)
    536        return ret;
    537    av_assert1(!pkt->size || pkt->data);
    538    if (pkt->size)
    539        memcpy(pkt->buf->data, pkt->data, pkt->size);
    540 
    541    pkt->data = pkt->buf->data;
    542 
    543    return 0;
    544 }
    545 
    546 int av_packet_make_writable(AVPacket *pkt)
    547 {
    548    AVBufferRef *buf = NULL;
    549    int ret;
    550 
    551    if (pkt->buf && av_buffer_is_writable(pkt->buf))
    552        return 0;
    553 
    554    ret = packet_alloc(&buf, pkt->size);
    555    if (ret < 0)
    556        return ret;
    557    av_assert1(!pkt->size || pkt->data);
    558    if (pkt->size)
    559        memcpy(buf->data, pkt->data, pkt->size);
    560 
    561    av_buffer_unref(&pkt->buf);
    562    pkt->buf  = buf;
    563    pkt->data = buf->data;
    564 
    565    return 0;
    566 }
    567 
    568 void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
    569 {
    570    if (pkt->pts != AV_NOPTS_VALUE)
    571        pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb);
    572    if (pkt->dts != AV_NOPTS_VALUE)
    573        pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb);
    574    if (pkt->duration > 0)
    575        pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb);
    576 }
    577 
    578 int avpriv_packet_list_put(PacketList *packet_buffer,
    579                           AVPacket      *pkt,
    580                           int (*copy)(AVPacket *dst, const AVPacket *src),
    581                           int flags)
    582 {
    583    PacketListEntry *pktl = av_malloc(sizeof(*pktl));
    584    int ret;
    585 
    586    if (!pktl)
    587        return AVERROR(ENOMEM);
    588 
    589    if (copy) {
    590        get_packet_defaults(&pktl->pkt);
    591        ret = copy(&pktl->pkt, pkt);
    592        if (ret < 0) {
    593            av_free(pktl);
    594            return ret;
    595        }
    596    } else {
    597        ret = av_packet_make_refcounted(pkt);
    598        if (ret < 0) {
    599            av_free(pktl);
    600            return ret;
    601        }
    602        av_packet_move_ref(&pktl->pkt, pkt);
    603    }
    604 
    605    pktl->next = NULL;
    606 
    607    if (packet_buffer->head)
    608        packet_buffer->tail->next = pktl;
    609    else
    610        packet_buffer->head = pktl;
    611 
    612    /* Add the packet in the buffered packet list. */
    613    packet_buffer->tail = pktl;
    614    return 0;
    615 }
    616 
    617 int avpriv_packet_list_get(PacketList *pkt_buffer,
    618                           AVPacket      *pkt)
    619 {
    620    PacketListEntry *pktl = pkt_buffer->head;
    621    if (!pktl)
    622        return AVERROR(EAGAIN);
    623    *pkt        = pktl->pkt;
    624    pkt_buffer->head = pktl->next;
    625    if (!pkt_buffer->head)
    626        pkt_buffer->tail = NULL;
    627    av_freep(&pktl);
    628    return 0;
    629 }
    630 
    631 void avpriv_packet_list_free(PacketList *pkt_buf)
    632 {
    633    PacketListEntry *tmp = pkt_buf->head;
    634 
    635    while (tmp) {
    636        PacketListEntry *pktl = tmp;
    637        tmp = pktl->next;
    638        av_packet_unref(&pktl->pkt);
    639        av_freep(&pktl);
    640    }
    641    pkt_buf->head = pkt_buf->tail = NULL;
    642 }
    643 
    644 int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type)
    645 {
    646    uint8_t *side_data;
    647    size_t side_data_size;
    648    int i;
    649 
    650    side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size);
    651    if (!side_data) {
    652        side_data_size = 4+4+8*error_count;
    653        side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
    654                                            side_data_size);
    655    }
    656 
    657    if (!side_data || side_data_size < 4+4+8*error_count)
    658        return AVERROR(ENOMEM);
    659 
    660    AV_WL32(side_data   , quality  );
    661    side_data[4] = pict_type;
    662    side_data[5] = error_count;
    663    for (i = 0; i<error_count; i++)
    664        AV_WL64(side_data+8 + 8*i , error[i]);
    665 
    666    return 0;
    667 }
    668 
    669 int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp)
    670 {
    671    AVProducerReferenceTime *prft;
    672    uint8_t *side_data;
    673    size_t side_data_size;
    674 
    675    side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size);
    676    if (!side_data) {
    677        side_data_size = sizeof(AVProducerReferenceTime);
    678        side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_PRFT, side_data_size);
    679    }
    680 
    681    if (!side_data || side_data_size < sizeof(AVProducerReferenceTime))
    682        return AVERROR(ENOMEM);
    683 
    684    prft = (AVProducerReferenceTime *)side_data;
    685    prft->wallclock = timestamp;
    686    prft->flags = 0;
    687 
    688    return 0;
    689 }
    690 
    691 const AVPacketSideData *av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd,
    692                                                enum AVPacketSideDataType type)
    693 {
    694    for (int i = 0; i < nb_sd; i++)
    695        if (sd[i].type == type)
    696            return &sd[i];
    697 
    698    return NULL;
    699 }
    700 
    701 static AVPacketSideData *packet_side_data_add(AVPacketSideData **psd, int *pnb_sd,
    702                                              enum AVPacketSideDataType type,
    703                                              void *data, size_t size)
    704 {
    705    AVPacketSideData *sd = *psd, *tmp;
    706    int nb_sd = *pnb_sd;
    707 
    708    for (int i = 0; i < nb_sd; i++) {
    709        if (sd[i].type != type)
    710            continue;
    711 
    712        av_free(sd[i].data);
    713        sd[i].data = data;
    714        sd[i].size = size;
    715        return &sd[i];
    716    }
    717 
    718    if (nb_sd == INT_MAX)
    719        return NULL;
    720 
    721    tmp = av_realloc_array(sd, nb_sd + 1, sizeof(*tmp));
    722    if (!tmp)
    723        return NULL;
    724 
    725    *psd = sd = tmp;
    726    sd[nb_sd].type = type;
    727    sd[nb_sd].data = data;
    728    sd[nb_sd].size = size;
    729    *pnb_sd = nb_sd + 1;
    730 
    731    return &sd[nb_sd];
    732 }
    733 
    734 AVPacketSideData *av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd,
    735                                          enum AVPacketSideDataType type,
    736                                          void *data, size_t size, int flags)
    737 {
    738    return packet_side_data_add(psd, pnb_sd, type, data, size);
    739 }
    740 
    741 AVPacketSideData *av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd,
    742                                          enum AVPacketSideDataType type,
    743                                          size_t size, int flags)
    744 {
    745    AVPacketSideData *sd = NULL;
    746    uint8_t *data;
    747 
    748    if (size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
    749        return NULL;
    750 
    751    data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
    752    if (!data)
    753        return NULL;
    754    memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    755 
    756    sd = packet_side_data_add(psd, pnb_sd, type, data, size);
    757    if (!sd)
    758        av_freep(&data);
    759 
    760    return sd;
    761 }
    762 
    763 void av_packet_side_data_remove(AVPacketSideData *sd, int *pnb_sd,
    764                                enum AVPacketSideDataType type)
    765 {
    766    int nb_sd = *pnb_sd;
    767 
    768    for (int i = nb_sd - 1; i >= 0; i--) {
    769        if (sd[i].type != type)
    770            continue;
    771        av_free(sd[i].data);
    772        sd[i] = sd[--nb_sd];
    773        break;
    774    }
    775 
    776    *pnb_sd = nb_sd;
    777 }
    778 
    779 void av_packet_side_data_free(AVPacketSideData **psd, int *pnb_sd)
    780 {
    781    AVPacketSideData *sd = *psd;
    782    int nb_sd = *pnb_sd;
    783 
    784    for (int i = 0; i < nb_sd; i++)
    785        av_free(sd[i].data);
    786 
    787    av_freep(psd);
    788    *pnb_sd = 0;
    789 }
    790 
    791 static void *container_packet_alloc(void *opaque)
    792 {
    793    return av_packet_alloc();
    794 }
    795 
    796 static void container_packet_reset(void *opaque, void *obj)
    797 {
    798    av_packet_unref(obj);
    799 }
    800 
    801 static void container_packet_free(void *opaque, void *obj)
    802 {
    803    AVPacket *pkt = obj;
    804    av_packet_free(&pkt);
    805 }
    806 
    807 static int container_packet_transfer(void *opaque, void *dst, void *src, unsigned flags)
    808 {
    809    if (flags & AV_CONTAINER_FIFO_FLAG_REF)
    810        return av_packet_ref(dst, src);
    811 
    812    av_packet_move_ref(dst, src);
    813    return 0;
    814 }
    815 
    816 AVContainerFifo *av_container_fifo_alloc_avpacket(unsigned flags)
    817 {
    818    return av_container_fifo_alloc(NULL, container_packet_alloc,
    819                                   container_packet_reset, container_packet_free,
    820                                   container_packet_transfer, 0);
    821 }