int av_dup_packet(AVPacket *pkt)
{
    AVPacket tmp_pkt;

    if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
        tmp_pkt = *pkt;

        pkt->data      = NULL;
        pkt->side_data = NULL;
        DUP_DATA(pkt->data, tmp_pkt.data, pkt->size, 1);
        pkt->destruct = av_destruct_packet;

        if (pkt->side_data_elems) {
            int i;

            DUP_DATA(pkt->side_data, tmp_pkt.side_data,
                     pkt->side_data_elems * sizeof(*pkt->side_data), 0);
            memset(pkt->side_data, 0, pkt->side_data_elems * sizeof(*pkt->side_data));
            for (i = 0; i < pkt->side_data_elems; i++) {
                DUP_DATA(pkt->side_data[i].data, tmp_pkt.side_data[i].data,
                         pkt->side_data[i].size, 1);
            }
        }
    }
    return 0;
failed_alloc:
    av_destruct_packet(pkt);
    return AVERROR(ENOMEM);
}